16template<
typename ValueType>
21template<
typename ValueType>
23 if (gmmMatrix.nrows() == 0) {
28template<
typename ValueType>
30 gmmMatrix = gmm::csr_matrix<ValueType>();
34template<
typename ValueType>
39template<
typename ValueType>
41 std::vector<ValueType>& result)
const {
43 std::vector<ValueType>* target = &result;
45 if (this->cachedVector) {
46 this->cachedVector->resize(x.size());
48 this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size());
50 target = this->cachedVector.get();
52 if (parallelize(env)) {
53 multAddParallel(x, b, *target);
55 multAdd(x, b, *target);
58 std::swap(result, *this->cachedVector);
62template<
typename ValueType>
68 gmm::mult_add_by_row_bwd(gmmMatrix, x, *b, x, gmm::abstract_dense());
70 gmm::mult_by_row_bwd(gmmMatrix, x, x, gmm::abstract_dense());
74 gmm::mult_add_by_row(gmmMatrix, x, *b, x, gmm::abstract_dense());
76 gmm::mult_by_row(gmmMatrix, x, x, gmm::abstract_dense());
81template<
typename ValueType>
83 std::vector<ValueType>
const& x, std::vector<ValueType>
const* b, std::vector<ValueType>& result,
84 std::vector<uint_fast64_t>* choices)
const {
86 std::vector<ValueType>* target = &result;
88 if (this->cachedVector) {
89 this->cachedVector->resize(x.size());
91 this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size());
93 target = this->cachedVector.get();
95 if (parallelize(env)) {
96 multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices);
98 multAddReduceHelper(dir, rowGroupIndices, x, b, *target, choices,
false);
101 std::swap(result, *this->cachedVector);
105template<
typename ValueType>
107 std::vector<uint64_t>
const& rowGroupIndices, std::vector<ValueType>& x,
108 std::vector<ValueType>
const* b, std::vector<uint_fast64_t>* choices,
bool backwards)
const {
110 multAddReduceHelper(dir, rowGroupIndices, x, b, x, choices, backwards);
113template<
typename ValueType>
116 value += vect_sp(gmm::mat_const_row(gmmMatrix, rowIndex), x,
typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(),
117 typename gmm::linalg_traits<std::vector<ValueType>>::storage_type());
120template<
typename ValueType>
124 gmm::mult_add(gmmMatrix, x, result);
126 gmm::mult_add(gmmMatrix, x, *b, result);
129 gmm::mult(gmmMatrix, x, result);
133template<
typename ValueType>
134void GmmxxMultiplier<ValueType>::multAddReduceHelper(
OptimizationDirection const& dir, std::vector<uint64_t>
const& rowGroupIndices,
135 std::vector<ValueType>
const& x, std::vector<ValueType>
const* b, std::vector<ValueType>& result,
136 std::vector<uint64_t>* choices,
bool backwards)
const {
137 if (dir == storm::OptimizationDirection::Minimize) {
139 multAddReduceHelper<storm::utility::ElementLess<ValueType>,
true>(rowGroupIndices, x, b, result, choices);
141 multAddReduceHelper<storm::utility::ElementLess<ValueType>,
false>(rowGroupIndices, x, b, result, choices);
145 multAddReduceHelper<storm::utility::ElementGreater<ValueType>,
true>(rowGroupIndices, x, b, result, choices);
147 multAddReduceHelper<storm::utility::ElementGreater<ValueType>,
false>(rowGroupIndices, x, b, result, choices);
152template<
typename ValueType>
153template<
typename Compare,
bool backwards>
154void GmmxxMultiplier<ValueType>::multAddReduceHelper(std::vector<uint64_t>
const& rowGroupIndices, std::vector<ValueType>
const& x,
155 std::vector<ValueType>
const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices)
const {
157 typedef std::vector<ValueType> VectorType;
158 typedef gmm::csr_matrix<ValueType> MatrixType;
160 typename gmm::linalg_traits<VectorType>::const_iterator add_it, add_ite;
162 add_it = backwards ? gmm::vect_end(*b) - 1 : gmm::vect_begin(*b);
163 add_ite = backwards ? gmm::vect_begin(*b) - 1 : gmm::vect_end(*b);
165 typename gmm::linalg_traits<VectorType>::iterator target_it = backwards ? gmm::vect_end(result) - 1 : gmm::vect_begin(result);
166 typename gmm::linalg_traits<MatrixType>::const_row_iterator itr = backwards ? mat_row_const_end(gmmMatrix) - 1 : mat_row_const_begin(gmmMatrix);
167 typename std::vector<uint64_t>::iterator choice_it;
169 choice_it = backwards ? choices->end() - 1 : choices->begin();
174 uint64_t selectedChoice;
176 uint64_t currentRow = backwards ? gmmMatrix.nrows() - 1 : 0;
177 auto row_group_it = backwards ? rowGroupIndices.end() - 2 : rowGroupIndices.begin();
178 auto row_group_ite = backwards ? rowGroupIndices.begin() - 1 : rowGroupIndices.end() - 1;
179 while (row_group_it != row_group_ite) {
180 ValueType currentValue = storm::utility::zero<ValueType>();
183 if (*row_group_it != *(row_group_it + 1)) {
186 currentValue = *add_it;
189 currentValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x);
192 selectedChoice = currentRow - *row_group_it;
193 if (*choice_it == selectedChoice) {
194 oldSelectedChoiceValue = currentValue;
210 uint64_t rowGroupSize = *(row_group_it + 1) - *row_group_it;
211 for (uint64_t i = 1;
i < rowGroupSize; ++
i) {
212 ValueType newValue = b ? *add_it : storm::utility::zero<ValueType>();
213 newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x);
215 if (choices && currentRow == *choice_it + *row_group_it) {
216 oldSelectedChoiceValue = newValue;
219 if (compare(newValue, currentValue)) {
220 currentValue = newValue;
222 selectedChoice = currentRow - *row_group_it;
238 *target_it = currentValue;
239 if (choices && compare(currentValue, oldSelectedChoiceValue)) {
240 *choice_it = selectedChoice;
258template<
typename Compare,
bool backwards>
259void GmmxxMultiplier<storm::RationalFunction>::multAddReduceHelper(std::vector<uint64_t>
const& rowGroupIndices, std::vector<storm::RationalFunction>
const& x,
260 std::vector<storm::RationalFunction>
const* b, std::vector<storm::RationalFunction>& result,
261 std::vector<uint64_t>* choices)
const {
262 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Operation not supported for this data type.");
265template<
typename ValueType>
266void GmmxxMultiplier<ValueType>::multAddParallel(std::vector<ValueType>
const& x, std::vector<ValueType>
const* b, std::vector<ValueType>& result)
const {
267#ifdef STORM_HAVE_INTELTBB
270 gmm::mult_add_parallel(gmmMatrix, x, result);
272 gmm::mult_add_parallel(gmmMatrix, x, *b, result);
275 gmm::mult_parallel(gmmMatrix, x, result);
278 STORM_LOG_WARN(
"Storm was built without support for Intel TBB, defaulting to sequential version.");
279 multAdd(x, b, result);
283#ifdef STORM_HAVE_INTELTBB
284template<
typename ValueType,
typename Compare>
285class TbbMultAddReduceFunctor {
287 TbbMultAddReduceFunctor(std::vector<uint64_t>
const& rowGroupIndices, gmm::csr_matrix<ValueType>
const& matrix, std::vector<ValueType>
const& x,
288 std::vector<ValueType>
const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices)
289 : rowGroupIndices(rowGroupIndices), matrix(matrix), x(x), b(b), result(result), choices(choices) {
293 void operator()(tbb::blocked_range<unsigned long>
const& range)
const {
294 typedef std::vector<ValueType> VectorType;
295 typedef gmm::csr_matrix<ValueType> MatrixType;
297 auto groupIt = rowGroupIndices.begin() + range.begin();
298 auto groupIte = rowGroupIndices.begin() + range.end();
300 auto itr = mat_row_const_begin(matrix) + *groupIt;
301 typename std::vector<ValueType>::const_iterator bIt;
303 bIt = b->begin() + *groupIt;
305 typename std::vector<uint64_t>::iterator choiceIt;
307 choiceIt = choices->begin() + range.begin();
310 auto resultIt = result.begin() + range.begin();
314 uint64_t selectedChoice;
316 uint64_t currentRow = *groupIt;
317 for (; groupIt != groupIte; ++groupIt, ++resultIt, ++choiceIt) {
318 ValueType currentValue = storm::utility::zero<ValueType>();
321 if (*groupIt != *(groupIt + 1)) {
327 currentValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x);
330 selectedChoice = currentRow - *groupIt;
331 if (*choiceIt == selectedChoice) {
332 oldSelectedChoiceValue = currentValue;
339 for (
auto itre = mat_row_const_begin(matrix) + *(groupIt + 1); itr != itre; ++itr, ++bIt, ++currentRow) {
340 ValueType newValue = b ? *bIt : storm::utility::zero<ValueType>();
341 newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x);
343 if (compare(newValue, currentValue)) {
344 currentValue = newValue;
346 selectedChoice = currentRow - *groupIt;
353 *resultIt = currentValue;
354 if (choices && compare(currentValue, oldSelectedChoiceValue)) {
355 *choiceIt = selectedChoice;
362 std::vector<uint64_t>
const& rowGroupIndices;
363 gmm::csr_matrix<ValueType>
const& matrix;
364 std::vector<ValueType>
const& x;
365 std::vector<ValueType>
const* b;
366 std::vector<ValueType>& result;
367 std::vector<uint64_t>* choices;
371template<
typename ValueType>
373 std::vector<ValueType>
const& x, std::vector<ValueType>
const* b, std::vector<ValueType>& result,
374 std::vector<uint64_t>* choices)
const {
375#ifdef STORM_HAVE_INTELTBB
376 if (dir == storm::OptimizationDirection::Minimize) {
377 tbb::parallel_for(tbb::blocked_range<unsigned long>(0, rowGroupIndices.size() - 1, 100),
381 tbb::blocked_range<unsigned long>(0, rowGroupIndices.size() - 1, 100),
385 STORM_LOG_WARN(
"Storm was built without support for Intel TBB, defaulting to sequential version.");
386 multAddReduceHelper(dir, rowGroupIndices, x, b, result, choices);
392 std::vector<uint64_t>
const& rowGroupIndices,
393 std::vector<storm::RationalFunction>
const& x,
394 std::vector<storm::RationalFunction>
const* b,
395 std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices)
const {
396 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"This operation is not supported.");
399template class GmmxxMultiplier<double>;
401#ifdef STORM_HAVE_CARL
402template class GmmxxMultiplier<storm::RationalNumber>;
403template class GmmxxMultiplier<storm::RationalFunction>;
virtual void multiplyAndReduceGaussSeidel(Environment const &env, OptimizationDirection const &dir, std::vector< uint64_t > const &rowGroupIndices, std::vector< ValueType > &x, std::vector< ValueType > const *b, std::vector< uint_fast64_t > *choices=nullptr, bool backwards=true) const override
virtual void multiply(Environment const &env, std::vector< ValueType > const &x, std::vector< ValueType > const *b, std::vector< ValueType > &result) const override
Performs a matrix-vector multiplication x' = A*x + b.
virtual void multiplyGaussSeidel(Environment const &env, std::vector< ValueType > &x, std::vector< ValueType > const *b, bool backwards=true) const override
Performs a matrix-vector multiplication in gauss-seidel style.
GmmxxMultiplier(storm::storage::SparseMatrix< ValueType > const &matrix)
virtual void clearCache() const override
virtual void multiplyAndReduce(Environment const &env, OptimizationDirection const &dir, std::vector< uint64_t > const &rowGroupIndices, std::vector< ValueType > const &x, std::vector< ValueType > const *b, std::vector< ValueType > &result, std::vector< uint_fast64_t > *choices=nullptr) const override
virtual void multiplyRow(uint64_t const &rowIndex, std::vector< ValueType > const &x, ValueType &value) const override
Multiplies the row with the given index with x and adds the result to the provided value.
virtual void clearCache() const
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_WARN(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
SFTBDDChecker::ValueType ValueType
typename detail::ElementLess< ValueType >::type ElementLess
typename detail::ElementGreater< ValueType >::type ElementGreater