From f209cb48f9ab9ffb257b0d970a13dc53c206191c Mon Sep 17 00:00:00 2001 From: Simon Praetorius <simon.praetorius@tu-dresden.de> Date: Sun, 15 Sep 2024 13:31:31 +0200 Subject: [PATCH] Revert "Switch internal data structure in MatrixIndexSet" This reverts commit c8272a07fa0fd4dc1274612ed5ffb016d4d326c8. --- dune/istl/matrixindexset.hh | 132 +++++++----------------------------- 1 file changed, 24 insertions(+), 108 deletions(-) diff --git a/dune/istl/matrixindexset.hh b/dune/istl/matrixindexset.hh index acc4466b4..10baccf35 100644 --- a/dune/istl/matrixindexset.hh +++ b/dune/istl/matrixindexset.hh @@ -5,139 +5,55 @@ #ifndef DUNE_ISTL_MATRIXINDEXSET_HH #define DUNE_ISTL_MATRIXINDEXSET_HH -#include <algorithm> -#include <cstddef> -#include <cstdint> -#include <set> -#include <variant> #include <vector> - -#include <dune/common/overloadset.hh> +#include <set> namespace Dune { - /** - * \brief Stores the nonzero entries for creating a sparse matrix - * - * This stores std::set-like container for the column index - * of each row. A sorted std::vector is used for this container - * up to a customizable maxVectorSize. If this size is exceeded, - * storage of the corresponding row is switched to std::set. - * - * The default value for maxVectorSize works well and ensures - * that the slow std::set fallback is only used for very - * dense rows. - */ + /** \brief Stores the nonzero entries in a sparse matrix */ class MatrixIndexSet { - using Index = std::size_t; - - // A vector that partly mimics a std::set by staying - // sorted on insert() and having unique values. - class FlatSet : public std::vector<Index> - { - using Base = std::vector<Index>; - public: - using Base::Base; - using Base::begin; - using Base::end; - void insert(const Index& value) { - auto it = std::lower_bound(begin(), end(), value); - if ((it == end() or (*it != value))) - Base::insert(it, value); - } - bool contains(const Index& value) const { - return std::binary_search(begin(), end(), value); - } - }; - - using RowIndexSet = std::variant<FlatSet, std::set<Index>>; public: + typedef std::size_t size_type; - using size_type = Index; - - /** - * \brief Default value for maxVectorSize - * - * This was selected after benchmarking for the worst case - * of reverse insertion of column indices. In many applications - * this works well. There's no need to use a different value - * unless you have many dense rows with more than defaultMaxVectorSize - * nonzero entries. Even in this case defaultMaxVectorSize may work - * well and a finding a better value may require careful - * benchmarking. - */ - static constexpr size_type defaultMaxVectorSize = 2048; - - /** - * \brief Constructor with custom maxVectorSize - * - * \param maxVectorSize Maximal size for stored row vector (default is defaultMaxVectorSize). - */ - MatrixIndexSet(size_type maxVectorSize=defaultMaxVectorSize) noexcept : rows_(0), cols_(0), maxVectorSize_(maxVectorSize) + /** \brief Default constructor */ + MatrixIndexSet() : rows_(0), cols_(0) {} - /** - * \brief Constructor setting the matrix size - * - * \param rows Number of matrix rows - * \param cols Number of matrix columns - * \param maxVectorSize Maximal size for stored row vector (default is defaultMaxVectorSize). - */ - MatrixIndexSet(size_type rows, size_type cols, size_type maxVectorSize=defaultMaxVectorSize) : rows_(rows), cols_(cols), maxVectorSize_(maxVectorSize) - { - indices_.resize(rows_, FlatSet()); + /** \brief Constructor setting the matrix size */ + MatrixIndexSet(size_type rows, size_type cols) : rows_(rows), cols_(cols) { + indices_.resize(rows_); } /** \brief Reset the size of an index set */ void resize(size_type rows, size_type cols) { rows_ = rows; cols_ = cols; - indices_.resize(rows_, FlatSet()); + indices_.resize(rows_); } /** \brief Add an index to the index set */ - void add(size_type row, size_type col) { - return std::visit(Dune::overload( - // If row is stored as set, call insert directly - [&](std::set<size_type>& set) { - set.insert(col); - }, - // If row is stored as vector only insert directly - // if maxVectorSize_ is not reached. Otherwise switch - // to set storage first. - [&](FlatSet& sortedVector) { - if (sortedVector.size() < maxVectorSize_) - sortedVector.insert(col); - else if (not sortedVector.contains(col)) - { - std::set<size_type> set(sortedVector.begin(), sortedVector.end()); - set.insert(col); - indices_[row] = std::move(set); - } - } - ), indices_[row]); + void add(size_type i, size_type j) { + indices_[i].insert(j); } /** \brief Return the number of entries */ size_type size() const { size_type entries = 0; for (size_type i=0; i<rows_; i++) - entries += rowsize(i); + entries += indices_[i].size(); + return entries; } /** \brief Return the number of rows */ size_type rows() const {return rows_;} + /** \brief Return the number of entries in a given row */ - size_type rowsize(size_type row) const { - return std::visit([&](const auto& rowIndices) { - return rowIndices.size(); - }, indices_[row]); - } + size_type rowsize(size_type row) const {return indices_[row].size();} /** \brief Import all nonzero entries of a sparse matrix into the index set \tparam MatrixType Needs to be BCRSMatrix<...> @@ -176,16 +92,17 @@ namespace Dune { matrix.setSize(rows_, cols_); matrix.setBuildMode(MatrixType::random); - for (size_type row=0; row<rows_; row++) - matrix.setrowsize(row, rowsize(row)); + for (size_type i=0; i<rows_; i++) + matrix.setrowsize(i, indices_[i].size()); matrix.endrowsizes(); - for (size_type row=0; row<rows_; row++) { - std::visit([&](const auto& rowIndices) { - for(size_type col : rowIndices) - matrix.addindex(row, col); - }, indices_[row]); + for (size_type i=0; i<rows_; i++) { + + typename std::set<size_type>::iterator it = indices_[i].begin(); + for (; it!=indices_[i].end(); ++it) + matrix.addindex(i, *it); + } matrix.endindices(); @@ -194,10 +111,9 @@ namespace Dune { private: - std::vector<RowIndexSet> indices_; + std::vector<std::set<size_type> > indices_; size_type rows_, cols_; - size_type maxVectorSize_; }; -- GitLab