dehnert
7 years ago
11 changed files with 340 additions and 85 deletions
-
101resources/3rdparty/gmm-5.2/include/gmm/gmm_blas.h
-
167src/storm/adapters/GmmxxAdapter.cpp
-
53src/storm/adapters/GmmxxAdapter.h
-
32src/storm/solver/GmmxxLinearEquationSolver.cpp
-
4src/storm/solver/GmmxxLinearEquationSolver.h
-
12src/storm/solver/StandardMinMaxLinearEquationSolver.cpp
-
1src/storm/solver/StandardMinMaxLinearEquationSolver.h
-
10src/storm/storage/SparseMatrix.cpp
-
3src/storm/storage/SparseMatrix.h
-
16src/test/storm/modelchecker/GmmxxHybridMdpPrctlModelCheckerTest.cpp
-
8src/test/storm/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp
@ -0,0 +1,167 @@ |
|||
#include "storm/adapters/GmmxxAdapter.h"
|
|||
|
|||
#include <algorithm>
|
|||
|
|||
#include "storm/adapters/RationalNumberAdapter.h"
|
|||
#include "storm/adapters/RationalFunctionAdapter.h"
|
|||
|
|||
#include "storm/utility/constants.h"
|
|||
#include "storm/exceptions/NotSupportedException.h"
|
|||
|
|||
namespace storm { |
|||
namespace adapters { |
|||
|
|||
template<typename T> |
|||
std::unique_ptr<gmm::csr_matrix<T>> GmmxxAdapter<T>::toGmmxxSparseMatrix(storm::storage::SparseMatrix<T> const& matrix) { |
|||
uint_fast64_t realNonZeros = matrix.getEntryCount(); |
|||
STORM_LOG_DEBUG("Converting " << matrix.getRowCount() << "x" << matrix.getColumnCount() << " matrix with " << realNonZeros << " non-zeros to gmm++ format."); |
|||
|
|||
// Prepare the resulting matrix.
|
|||
std::unique_ptr<gmm::csr_matrix<T>> result(new gmm::csr_matrix<T>(matrix.getRowCount(), matrix.getColumnCount())); |
|||
|
|||
// Copy Row Indications
|
|||
std::copy(matrix.rowIndications.begin(), matrix.rowIndications.end(), result->jc.begin()); |
|||
|
|||
// Copy columns and values.
|
|||
std::vector<T> values; |
|||
values.reserve(matrix.getEntryCount()); |
|||
|
|||
// To match the correct vector type for gmm, we create the vector with the exact same type.
|
|||
decltype(result->ir) columns; |
|||
columns.reserve(matrix.getEntryCount()); |
|||
|
|||
for (auto const& entry : matrix) { |
|||
columns.emplace_back(entry.getColumn()); |
|||
values.emplace_back(entry.getValue()); |
|||
} |
|||
|
|||
std::swap(result->ir, columns); |
|||
std::swap(result->pr, values); |
|||
|
|||
STORM_LOG_DEBUG("Done converting matrix to gmm++ format."); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
template<typename T> |
|||
void GmmxxMultiplier<T>::multAdd(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) { |
|||
if (b) { |
|||
gmm::mult_add(matrix, x, *b, result); |
|||
} else { |
|||
gmm::mult(matrix, x, result); |
|||
} |
|||
} |
|||
|
|||
template<typename T> |
|||
void GmmxxMultiplier<T>::multAddGaussSeidelBackward(gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b) { |
|||
STORM_LOG_ASSERT(matrix.nr == matrix.nc, "Expecting square matrix."); |
|||
if (b) { |
|||
gmm::mult_add_by_row_bwd(matrix, x, *b, x, gmm::abstract_dense()); |
|||
} else { |
|||
gmm::mult_by_row_bwd(matrix, x, x, gmm::abstract_dense()); |
|||
} |
|||
} |
|||
|
|||
template<typename T> |
|||
void GmmxxMultiplier<T>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) { |
|||
std::vector<T>* target = &result; |
|||
std::unique_ptr<std::vector<T>> temporary; |
|||
if (&x == &result) { |
|||
STORM_LOG_WARN("Using temporary in 'multAddReduce'."); |
|||
temporary = std::make_unique<std::vector<T>>(x.size()); |
|||
target = temporary.get(); |
|||
} |
|||
|
|||
multAddReduceHelper(dir, rowGroupIndices, matrix, x, b, *target, choices); |
|||
} |
|||
|
|||
template<typename T> |
|||
void GmmxxMultiplier<T>::multAddReduceGaussSeidel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b, std::vector<uint64_t>* choices) { |
|||
multAddReduceHelper(dir, rowGroupIndices, matrix, x, b, x, choices); |
|||
} |
|||
|
|||
template<typename T> |
|||
void GmmxxMultiplier<T>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) { |
|||
typedef std::vector<T> VectorType; |
|||
typedef gmm::csr_matrix<T> MatrixType; |
|||
|
|||
typename gmm::linalg_traits<VectorType>::const_iterator add_it, add_ite; |
|||
if (b) { |
|||
add_it = gmm::vect_end(*b) - 1; |
|||
add_ite = gmm::vect_begin(*b) - 1; |
|||
} |
|||
typename gmm::linalg_traits<VectorType>::iterator target_it = gmm::vect_end(result) - 1; |
|||
typename gmm::linalg_traits<MatrixType>::const_row_iterator itr = mat_row_const_end(matrix) - 1; |
|||
typename std::vector<uint64_t>::iterator choice_it; |
|||
if (choices) { |
|||
choice_it = choices->end() - 1; |
|||
} |
|||
|
|||
uint64_t choice; |
|||
for (auto row_group_it = rowGroupIndices.end() - 2, row_group_ite = rowGroupIndices.begin() - 1; row_group_it != row_group_ite; --row_group_it, --choice_it, --target_it) { |
|||
T currentValue = b ? *add_it : storm::utility::zero<T>(); |
|||
currentValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); |
|||
|
|||
if (choices) { |
|||
choice = *(row_group_it + 1) - 1 - *row_group_it; |
|||
*choice_it = choice; |
|||
} |
|||
|
|||
--itr; |
|||
if (b) { |
|||
--add_it; |
|||
} |
|||
|
|||
for (uint64_t row = *row_group_it + 1, rowEnd = *(row_group_it + 1); row < rowEnd; ++row, --itr) { |
|||
T newValue = b ? *add_it : storm::utility::zero<T>(); |
|||
newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); |
|||
|
|||
if (choices) { |
|||
--choice; |
|||
} |
|||
|
|||
if ((dir == OptimizationDirection::Minimize && newValue < currentValue) || (dir == OptimizationDirection::Maximize && newValue > currentValue)) { |
|||
currentValue = newValue; |
|||
if (choices) { |
|||
*choice_it = choice; |
|||
} |
|||
} |
|||
if (b) { |
|||
--add_it; |
|||
} |
|||
} |
|||
|
|||
// Write back final value.
|
|||
*target_it = currentValue; |
|||
} |
|||
} |
|||
|
|||
template<> |
|||
void GmmxxMultiplier<storm::RationalFunction>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<storm::RationalFunction> const& matrix, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) { |
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported for this data type."); |
|||
} |
|||
|
|||
#ifdef STORM_HAVE_INTELTBB
|
|||
template<typename T> |
|||
void GmmxxMultiplier<T>::multAddParallel(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) { |
|||
if (b) { |
|||
gmm::mult_add_parallel(matrix, x, *b, result); |
|||
} else { |
|||
gmm::mult_parallel(matrix, x, result); |
|||
} |
|||
} |
|||
#endif
|
|||
|
|||
template class GmmxxAdapter<double>; |
|||
template class GmmxxMultiplier<double>; |
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class GmmxxAdapter<storm::RationalNumber>; |
|||
template class GmmxxAdapter<storm::RationalFunction>; |
|||
|
|||
template class GmmxxMultiplier<storm::RationalNumber>; |
|||
template class GmmxxMultiplier<storm::RationalFunction>; |
|||
#endif
|
|||
|
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue