11 changed files with 340 additions and 85 deletions
			
			
		- 
					113resources/3rdparty/gmm-5.2/include/gmm/gmm_blas.h
- 
					167src/storm/adapters/GmmxxAdapter.cpp
- 
					59src/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