From f16f18bbf6b4033f558fbcfb2667201548bb4ab1 Mon Sep 17 00:00:00 2001 From: TimQu Date: Fri, 10 Feb 2017 11:08:05 +0100 Subject: [PATCH] fix in Matrix-vector multiplication --- src/storm/storage/SparseMatrix.cpp | 77 +++++++++++++++--------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/storm/storage/SparseMatrix.cpp b/src/storm/storage/SparseMatrix.cpp index 3f70b8f2a..42b762b64 100644 --- a/src/storm/storage/SparseMatrix.cpp +++ b/src/storm/storage/SparseMatrix.cpp @@ -1165,7 +1165,7 @@ namespace storm { return result; } - + template void SparseMatrix::multiplyWithVector(std::vector const& vector, std::vector& result) const { #ifdef STORM_HAVE_INTELTBB @@ -1178,59 +1178,60 @@ namespace storm { return multiplyWithVectorSequential(vector, result); #endif } - + template void SparseMatrix::multiplyWithVectorSequential(std::vector const& vector, std::vector& result) const { - const_iterator it = this->begin(); - const_iterator ite; - std::vector::const_iterator rowIterator = rowIndications.begin(); - typename std::vector::iterator resultIterator = result.begin(); - typename std::vector::iterator resultIteratorEnd = result.end(); - - // If the vector to multiply with and the target vector are actually the same, we need an auxiliary variable - // to store the intermediate result. if (&vector == &result) { - for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) { - ValueType tmpValue = storm::utility::zero(); - - for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) { - tmpValue += it->getValue() * vector[it->getColumn()]; - } - *resultIterator = tmpValue; - } + STORM_LOG_WARN("Matrix-vector-multiplication invoked but the target vector uses the same memory as the input vector. This requires to allocate auxiliary memory."); + std::vector tmpVector(this->getRowCount()); + multiplyWithVectorSequential(vector, tmpVector); + result = std::move(tmpVector); } else { + const_iterator it = this->begin(); + const_iterator ite; + std::vector::const_iterator rowIterator = rowIndications.begin(); + typename std::vector::iterator resultIterator = result.begin(); + typename std::vector::iterator resultIteratorEnd = result.end(); + for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) { *resultIterator = storm::utility::zero(); - + for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) { *resultIterator += it->getValue() * vector[it->getColumn()]; } } } } - + #ifdef STORM_HAVE_INTELTBB template void SparseMatrix::multiplyWithVectorParallel(std::vector const& vector, std::vector& result) const { - tbb::parallel_for(tbb::blocked_range(0, result.size(), 10), - [&] (tbb::blocked_range const& range) { - index_type startRow = range.begin(); - index_type endRow = range.end(); - const_iterator it = this->begin(startRow); - const_iterator ite; - std::vector::const_iterator rowIterator = this->rowIndications.begin() + startRow; - std::vector::const_iterator rowIteratorEnd = this->rowIndications.begin() + endRow; - typename std::vector::iterator resultIterator = result.begin() + startRow; - typename std::vector::iterator resultIteratorEnd = result.begin() + endRow; - - for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) { - *resultIterator = storm::utility::zero(); - - for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) { - *resultIterator += it->getValue() * vector[it->getColumn()]; + if (&vector == &result) { + STORM_LOG_WARN("Matrix-vector-multiplication invoked but the target vector uses the same memory as the input vector. This requires to allocate auxiliary memory."); + std::vector tmpVector(this->getRowCount()); + multiplyWithVectorParallel(vector, tmpVector); + result = std::move(tmpVector); + } else { + tbb::parallel_for(tbb::blocked_range(0, result.size(), 10), + [&] (tbb::blocked_range const& range) { + index_type startRow = range.begin(); + index_type endRow = range.end(); + const_iterator it = this->begin(startRow); + const_iterator ite; + std::vector::const_iterator rowIterator = this->rowIndications.begin() + startRow; + std::vector::const_iterator rowIteratorEnd = this->rowIndications.begin() + endRow; + typename std::vector::iterator resultIterator = result.begin() + startRow; + typename std::vector::iterator resultIteratorEnd = result.begin() + endRow; + + for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) { + *resultIterator = storm::utility::zero(); + + for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) { + *resultIterator += it->getValue() * vector[it->getColumn()]; + } } - } - }); + }); + } } #endif