From 01cefbb2c01a94726f28aacf93e65512a47f97ce Mon Sep 17 00:00:00 2001 From: dehnert Date: Mon, 1 Sep 2014 11:04:02 +0200 Subject: [PATCH] Modified the multiplication of a sparse matrix with a dense vector to only use the parallel version if available and the number of nonzero entries exceeds a certain threshold. Former-commit-id: 07957b2d298e4da1532665698c1050a2200a42dc --- src/storage/SparseMatrix.cpp | 52 +++++++++++++++++++++++------------- src/storage/SparseMatrix.h | 26 +++++++++++++++++- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/storage/SparseMatrix.cpp b/src/storage/SparseMatrix.cpp index c6bfd0214..e03909703 100644 --- a/src/storage/SparseMatrix.cpp +++ b/src/storage/SparseMatrix.cpp @@ -770,6 +770,36 @@ namespace storm { template void SparseMatrix::multiplyWithVector(std::vector const& vector, std::vector& result) const { #ifdef STORM_HAVE_INTELTBB + if (this->getNonzeroEntryCount() > 10000) { + return this->multiplyWithVectorParallel(vector, result); + } else { + return this->multiplyWithVectorSequential(vector, result); + } +#else + 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; + typename 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::constantZero(); + + 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) { uint_fast64_t startRow = range.begin(); @@ -778,8 +808,8 @@ namespace storm { const_iterator ite; std::vector::const_iterator rowIterator = this->rowIndications.begin() + startRow; std::vector::const_iterator rowIteratorEnd = this->rowIndications.begin() + endRow; - std::vector::iterator resultIterator = result.begin() + startRow; - std::vector::iterator resultIteratorEnd = result.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::constantZero(); @@ -789,23 +819,9 @@ namespace storm { } } }); -#else - const_iterator it = this->begin(); - const_iterator ite; - typename 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::constantZero(); - - for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) { - *resultIterator += it->getValue() * vector[it->getColumn()]; - } - } -#endif } - +#endif + template uint_fast64_t SparseMatrix::getSizeInMemory() const { uint_fast64_t size = sizeof(*this); diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index 46eaa0860..38b1cec9e 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -576,7 +576,9 @@ namespace storm { std::vector getPointwiseProductRowSumVector(storm::storage::SparseMatrix const& otherMatrix) const; /*! - * Multiplies the matrix with the given vector and writes the result to given result vector. + * Multiplies the matrix with the given vector and writes the result to the given result vector. If a + * parallel implementation is available and it is considered worthwhile (heuristically, based on the metrics + * of the matrix), the multiplication is carried out in parallel. * * @param vector The vector with which to multiply the matrix. * @param result The vector that is supposed to hold the result of the multiplication after the operation. @@ -584,6 +586,28 @@ namespace storm { */ void multiplyWithVector(std::vector const& vector, std::vector& result) const; + /*! + * Multiplies the matrix with the given vector in a sequential way and writes the result to the given result + * vector. + * + * @param vector The vector with which to multiply the matrix. + * @param result The vector that is supposed to hold the result of the multiplication after the operation. + * @return The product of the matrix and the given vector as the content of the given result vector. + */ + void multiplyWithVectorSequential(std::vector const& vector, std::vector& result) const; + +#ifdef STORM_HAVE_INTELTBB + /*! + * Multiplies the matrix with the given vector in a parallel fashion using Intel's TBB and writes the result + * to the given result vector. + * + * @param vector The vector with which to multiply the matrix. + * @param result The vector that is supposed to hold the result of the multiplication after the operation. + * @return The product of the matrix and the given vector as the content of the given result vector. + */ + void multiplyWithVectorParallel(std::vector const& vector, std::vector& result) const; +#endif + /*! * Computes the sum of the entries in a given row. *