14#ifndef THREADED_MATRIX_CHUNKS
15#define THREADED_MATRIX_CHUNKS
19#include <boost/timer/timer.hpp>
21#include "dune/common/config.h"
22#include <dune/istl/bcrsmatrix.hh>
23#include <dune/istl/operators.hh>
37 template <
class Entry,
class Index>
40 template <
class Scalar,
class Index>
43 template <
class Target,
class Source,
class RowIndices,
class ColIndices>
44 Target
submatrix(Source
const& A, RowIndices
const& ri, ColIndices
const& ci);
52 template <
class Entry,
class Allocator,
class Index>
55 for (
auto ri=matrix.begin(); ri!=matrix.end(); ++ri)
57 for (
auto ci=ri->begin(); ci!=ri->end(); ++ci)
58 ++rowCount[ci.index()];
60 rowCount[ri.index()] = ri->size();
63 template <
class Entry,
class Index2,
class Index>
66 for (
auto ri=matrix.
begin(); ri!=matrix.
end(); ++ri)
68 for (
auto ci=ri->begin(); ci!=ri->end(); ++ci)
69 ++rowCount[ci.index()];
71 rowCount[ri.index()] = ri->size();
74 template <
class Entry,
class Index,
class Index2>
77 auto const& indices = isTransposed? matrix.
cidx: matrix.
ridx;
86 template <
class Entry,
class Matrix,
bool symmetric,
bool transposed,
class Index>
92 std::vector<Index>
const& )
94 for (Index i=0; i<last-first; ++i)
97 for (
auto ci=matrix[first+i].begin(); ci!=matrix[first+i].end(); ++ci, ++j)
99 values[colStart[i]+j] = *ci;
100 cols[colStart[i]+j] = ci.index();
106 template <
class Entry,
class Matrix,
bool transposed,
class Index>
112 std::vector<Index>
const& nRowEntries)
118 std::vector<Index> entriesInRow(last-first,0);
119 for (Index i=0; i<last-first; ++i)
122 for (
auto ci=matrix[first+i].begin(); ci!=matrix[first+i].end(); ++ci, ++j)
124 values[colStart[i]+j] = *ci;
125 cols[colStart[i]+j] = ci.index();
127 entriesInRow[i] = matrix[first+i].
size();
128 assert(entriesInRow[i]<=nRowEntries[first+i]);
133 for (Index r=first+1; r!=matrix.N(); ++r)
134 for (
auto c=matrix[r].begin(); c!=matrix[r].end(); ++c)
137 Index ridx = c.index();
138 if (ridx>=first && ridx<last)
144 assert(ridx-first<colStart.size() && ridx-first < entriesInRow.size());
145 Index pos = colStart[ridx-first] + entriesInRow[ridx-first];
146 assert(pos<colStart[ridx-first+1]);
149 ++entriesInRow[ridx-first];
150 assert(entriesInRow[ridx-first]<=nRowEntries[ridx]);
158 template <
class Entry,
class Matrix,
class Index>
164 std::vector<Index>
const& nRowEntries)
170 std::vector<Index> entriesInRow(last-first,0);
172 for (
auto r=matrix.begin(); r!=matrix.end(); ++r)
173 for (
auto c=r->begin(); c!=r->end(); ++c)
176 Index ridx = c.index();
177 if (ridx>=first && ridx<last)
179 Index cidx = r.index();
181 assert(ridx-first<colStart.size() && ridx-first < entriesInRow.size());
182 Index pos = colStart[ridx-first] + entriesInRow[ridx-first];
183 assert(pos<colStart[ridx-first+1]);
186 ++entriesInRow[ridx-first];
187 assert(entriesInRow[ridx-first]<=nRowEntries[ridx]);
200 template <
class To,
class From,
class scalarsMatch = std::false_type>
203 static void copy(From
const& from, To& to,
bool isTransposed)
205 assert(isTransposed);
212 template <
class To,
class From>
213 struct MatrixEntry<To, From, typename std::is_same<typename To::field_type, typename From::field_type>
::type>
215 static void copy(From
const& from, To& to,
bool isTransposed)
217 assert(!isTransposed);
218 static_assert(To::rows == From::rows && To::cols == From::cols,
"Mismatch of dimensions.");
219 for(
int i=0;i<To::rows;++i)
220 for(
int j=0;j<To::cols;++j)
221 to[i][j] =
static_cast<typename To::field_type
>(from[i][j]);
230 template <
class Entry>
233 static void copy(Entry
const& from, Entry& to,
bool isTransposed)
235 if (isTransposed && from.rows > 1 && from.cols > 1 && from.rows != from.cols)
237 std::cerr <<
"Transposing rectangular Dune::FieldMatrix not implemented!" <<
'\n'
238 <<
"#rows=" << from.rows <<
", #cols=" << from.cols <<
'\n';
241 if (isTransposed && from.rows == from.cols)
246 for (
int i=0;i<from.rows;i++)
249 for (
int j=i+1;j<from.cols;j++)
251 typename Entry::field_type s=from[j][i];
270 template <
class Index=
size_t>
273 template <
class IndexP>
291 template <
class IndexP>
294 , numaNode(pi.numaNode), symm(pi.symm)
315 int node()
const {
return numaNode; }
345 template <
class Index=
size_t>
382 r.reserve(nnzPerRow);
412 template <
class IterRow,
class IterCol>
414 IterCol
const fromCol, IterCol
const toCol,
bool colIsSorted=
false)
418 sortedCols.insert(end(sortedCols),fromCol,toCol);
420 std::sort(begin(sortedCols),end(sortedCols));
421 sortedCols.erase(std::unique(begin(sortedCols),end(sortedCols)),end(sortedCols));
424 for ( ; fromRow != toRow; ++fromRow)
425 if (this->
first() <= *fromRow && *fromRow < this->
last())
429 std::upper_bound(begin(sortedCols),end(sortedCols),*fromRow):
431 tmp.resize(c.size() + std::distance(begin(sortedCols),top));
432 tmp.erase(std::set_union(begin(c),end(c),begin(sortedCols),top,
433 begin(tmp)),end(tmp));
448 for (Index i=0; i<cols.size(); ++i)
451 std::iota(begin(cols[i]),end(cols[i]),
static_cast<Index
>(0));
467 for (
auto const& r: cols)
482 size_t balanceForward(
size_t const covered,
size_t const nnz,
int chunks, std::vector<IndexArray>& moveRows);
494 size_t balanceBackward(
size_t covered,
size_t const nnz,
int chunks, std::vector<IndexArray>& moveRows);
497 std::vector<IndexArray> cols;
509 template <
class Index=
size_t>
529 template <
class IndexP>
532 , colStarts(p.colStarts)
534 , nnzPerRow(p.nnzPerRow)
552 template <
class Expanded,
class Condensed,
class Matrix>
562 colStarts[i-
first] = cols.size();
564 auto const& row = mat[eIndices[i]];
566 auto cend = row.end();
567 for (
auto c = row.begin(); c!=cend; ++c)
569 Index ci = cIndices[c.index()];
570 if (ci<eIndices.size())
575 colStarts.back() = cols.size();
578 nnzPerRow = this->last()==this->first()? 0 :
nonzeroes() / (this->
last()-this->
first());
593 template <
class Matrix>
600 isTransposed =
false;
607 Index fromRow = this->
first(), toRow = this->
last();
611 fromRow = 0, toRow = matrix.N();
613 for (Index ri=fromRow; ri<toRow; ++ri)
615 auto cend = matrix[ri].end();
616 for (
auto ci=matrix[ri].begin(); ci!=cend; ++ci)
618 Index r = ri, c = ci.index();
622 ++rowCount[r-this->
first()];
624 ++rowCount[c-this->
first()];
629 colStarts.resize(rowCount.size()+1,0);
630 std::partial_sum(rowCount.begin(),rowCount.end(),colStarts.begin()+1);
633 cols.resize(colStarts.back());
636 for (Index ri=fromRow; ri<toRow; ++ri)
638 auto cend = matrix[ri].end();
639 for (
auto ci=matrix[ri].begin(); ci!=cend; ++ci)
641 Index r = ri, c = ci.index();
646 cols[colStarts[r-this->
first()]+rowCount[r-this->
first()]-1] = c;
647 --rowCount[r-this->
first()];
651 cols[colStarts[c-this->
first()]+rowCount[c-this->
first()]-1] = r;
652 --rowCount[c-this->
first()];
658 for (Index ri=0; ri<rowCount.size(); ++ri) {
659 assert(rowCount[ri] == 0);
660 std::sort(cols.begin()+colStarts[ri],cols.begin()+colStarts[ri+1]);
677 template <
class Scalar,
class Index2>
684 isTransposed =
false;
690 for (
size_t i=0; i<matrix.
ridx.size(); ++i)
692 Index r = matrix.
ridx[i], c = matrix.
cidx[i];
696 ++rowCount[r-this->
first()];
698 ++rowCount[c-this->
first()];
702 colStarts.resize(rowCount.size()+1,0);
703 std::partial_sum(rowCount.begin(),rowCount.end(),colStarts.begin()+1);
706 cols.resize(colStarts.back());
709 for (
size_t i=0; i<matrix.
ridx.size(); ++i)
711 Index r = matrix.
ridx[i], c = matrix.
cidx[i];
716 cols[colStarts[r-this->
first()]+rowCount[r-this->
first()]-1] = c;
717 --rowCount[r-this->
first()];
721 cols[colStarts[c-this->
first()]+rowCount[c-this->
first()]-1] = r;
722 --rowCount[c-this->
first()];
727 for (Index ri=0; ri<rowCount.size(); ++ri)
729 assert(rowCount[ri] == 0);
730 auto first = cols.begin()+colStarts[ri];
731 auto last = cols.begin()+colStarts[ri+1];
739 for (Index ri=1; ri<rowCount.size(); ++ri)
741 Index newStart = colStarts[ri-1] + rowCount[ri-1];
742 if (newStart != colStarts[ri])
744 std::copy(cols.begin()+colStarts[ri],cols.begin()+colStarts[ri]+rowCount[ri],cols.begin()+newStart);
745 colStarts[ri] = newStart;
748 if (!rowCount.empty())
749 colStarts.back() = colStarts[rowCount.size()-1]+rowCount.back();
750 cols.erase(cols.begin()+colStarts.back(),cols.end());
762 Index
col(
size_t idx)
const {
return cols[idx]; }
768 size_t colStart(Index row)
const {
return colStarts[row]; }
774 typename std::vector<Index,NumaAllocator<Index>>::const_iterator
colStartIterator(Index row)
const
789 auto b = cols.begin();
791 assert(0 <= r && r+1 < colStarts.size());
792 auto p = std::lower_bound(b+colStarts[r],b+colStarts[r+1],c);
793 if (p==b+colStarts[r+1] || *p!=c)
794 return std::numeric_limits<size_t>::max();
803 return position(r,c) != std::numeric_limits<size_t>::max();
811 size_t storage()
const {
return cols.size(); }
826 template <
class IndexP>
830 std::vector<size_t,NumaAllocator<size_t>> colStarts;
831 std::vector<Index,NumaAllocator<Index>> cols;
839 template <
class Arguments,
class Operation>
868 template <
class Entry,
class Index=
size_t>
873 template <
class EntryA,
class IndexA>
899 template <
class EntryA,
class IndexA,
900 typename = std::enable_if_t<std::is_convertible_v<EntryA,Entry>>>
905 , values(c.values.begin(),c.values.end(),
NumaAllocator<Entry>(c.pat->node()))
915 , values(pat->nonzeroes(),init,
NumaAllocator<Entry>(pat->node()))
931 template <
class Matrix>
933 bool isSymmetric,
bool isTransposed)
936 typedef typename Matrix::block_type SuppliedEntry;
938 Index first = pat->first(), last = pat->last();
941 isTransposed =
false;
944 Index fromRow = first, toRow = last;
945 if (isSymmetric && !pat->symmetric())
948 fromRow = 0, toRow = matrix.N();
951 for (Index ri=fromRow; ri<toRow; ++ri)
953 auto cend = matrix[ri].end();
954 for (
auto ci=matrix[ri].begin(); ci!=cend; ++ci)
956 Index r = ri, c = ci.index();
959 if (first<=r && r<last && (!pat->symmetric() || c<=r))
961 assert(pat->position(r,c) < values.size());
964 if (isSymmetric && !pat->symmetric() && c<r && first<=c && c<last)
981 template <
class Scalar,
class Index2>
985 Index first = pat->first(), last = pat->last();
988 isTransposed =
false;
992 for (
size_t i=0; i<matrix.
ridx.size(); ++i)
994 Index r = matrix.
ridx[i], c = matrix.
cidx[i];
997 if (first<=r && r<last && (!pat->symmetric() || c<=r))
999 assert(pat->position(r,c) < values.size());
1000 values[pat->position(r,c)] = matrix.
data[i];
1002 if (isSymmetric && !pat->symmetric() && c<r && first<=c && c<last)
1003 values[pat->position(c,r)] = matrix.
data[i];
1020 template <
class Matrix>
1022 Index firstRow, Index lastRow,
bool symmetric,
int node)
1024 firstRow,lastRow,symmetric,node),
1025 matrix,isSymmetric,isTransposed)
1040 template <
class Expanded,
class Condensed,
class Matrix>
1042 Expanded
const& eIndices, Condensed
const& cIndices,
Matrix const& matrix)
1045 Index first = pat->first(), last = pat->last();
1046 for (Index r=first; r<last; ++r)
1048 auto row = matrix[eIndices[r]];
1049 auto p = begin(values) + pat->colStart(r-first);
1050 for (
auto c=row.begin(); c!=row.end(); ++c)
1051 if (cIndices[c.index()]<eIndices.size())
1054 assert(!std::isnan(*p));
1058 assert(p==begin(values)+pat->colStart(r-first+1));
1074 template <
class Value>
1077 std::fill(begin(values),end(values),a);
1085 template <
class Arguments,
class Operation>
1088 Index first = pat->first();
1089 for (Index r=0; r<pat->last()-first; ++r)
1091 auto eend = e.
end(r);
1092 auto ci = pat->colStartIterator(r);
1093 auto cend = pat->colStartIterator(r+1);
1094 auto vi = begin(values)+pat->colStart(r);
1095 for (
auto ei = e.
begin(r); ei != eend; ++ei)
1097 auto pos = std::find(ci,cend,ei.index());
1098 assert(pos != cend);
1110 template <
class Domain,
class Range>
1114 auto const& p = *pat;
1115 Index first = p.first();
1116 Index last = p.last();
1124 for (Index row=first; row<last; ++row)
1127 typename Range::block_type z(0);
1129 size_t jEnd = p.colStart(row+1-first);
1130 for (
size_t j=p.colStart(row-first); j<jEnd; ++j)
1131 if (Entry::rows==1 && Entry::cols==1)
1132 z.axpy(values[j][0][0],x[p.col(j)]);
1134 values[j].umv(x[p.col(j)],z);
1138 if (initialize) y[row] = z;
1142 if (Entry::rows==Entry::cols && row<x.size())
1143 dp += y[row]*x[row];
1153 template <
class Domain,
class Range>
1156 auto const& p = *pat;
1157 Index first = p.first();
1158 Index last = p.last();
1160 assert(x.size()>=last);
1163 for (Index j=first; j<last; ++j)
1165 size_t jEnd = p.colStart(j+1-first);
1166 for (
size_t k=p.colStart(j-first); k<jEnd; ++k)
1169 if (Entry::rows==1 && Entry::cols==1)
1170 y[i] += a*values[k][0][0] * x[j];
1172 values[k].usmtv(a,x[j],y[i]);
1185 template <
class Domain,
class Range>
1188 auto const& p = *block.pat;
1189 Index firstRow = p.first();
1190 Index lastRow = p.last();
1191 Index firstCol = pat->first();
1192 Index lastCol = pat->last();
1194 assert(lastRow<=y.size());
1197 for (Index row=firstRow; row<lastRow; ++row)
1200 for (Index row=firstRow; row<lastRow; ++row)
1202 auto const& xrow = x[row];
1204 auto cend = p.colStartIterator(row+1-firstRow);
1205 auto ci = firstCol==0?
1206 p.colStartIterator(row-firstRow):
1207 std::lower_bound(p.colStartIterator(row-firstRow),cend,firstCol);
1208 auto vi = block.values.begin() + (ci-p.colStartIterator(0));
1210 for ( ; ci!=cend && *ci<lastCol && *ci<row; ++ci, ++vi)
1211 vi->usmtv(a,xrow,y[*ci]);
1213 for ( ; ci!=cend && *ci<lastCol; ++ci, ++vi)
1214 vi->usmtv(a,xrow,y[*ci]);
1229 return values.begin()+pat->colStart(row);
1235 template <
class LMIterator>
1238 Index firstRow = pat->first();
1239 Index lastRow = pat->last();
1241 if (first==last || firstRow==lastRow)
1244 Index nnzPerRow = pat->nonzeroesPerRow();
1249 Index n = scatterMutex.size();
1250 for (Index i=0; i<n; ++i)
1252 boost::lock_guard<boost::mutex> lock(scatterMutex[i].get());
1257 if (nnzPerRow == pat->columns())
1258 scatterRowRange<0>(first,last,firstRow,rowRangeStart,rowRangeEnd);
1259 else if (nnzPerRow > 10*(first->cidx().size()))
1260 scatterRowRange<1>(first,last,firstRow,rowRangeStart,rowRangeEnd);
1262 scatterRowRange<2>(first,last,firstRow,rowRangeStart,rowRangeEnd);
1271 template <
class F,
class EntryB,
class IndexB>
1274 auto const& p = *pat;
1275 Index first = p.first();
1276 Index last = p.last();
1278 for (Index row=first; row<last; ++row)
1280 auto const& Br = B[row];
1281 size_t jEnd = p.colStart(row+1-first);
1282 auto bri = Br.
begin();
1283 auto brend = Br.
end();
1284 for (
size_t j=p.colStart(row-first); j<jEnd; ++j)
1286 while (bri!= brend && bri.index()<p.col(j))
1288 if (bri!=brend && bri.index()==p.col(j))
1289 values[j] = f(values[j],*bri);
1295 std::shared_ptr<CRSChunkPattern<Index>> pat;
1296 std::vector<Mutex> scatterMutex;
1299 std::vector<Entry,NumaAllocator<Entry>> values;
1304 template <
int sparsity,
class LMIterator>
1305 void scatterRowRange(LMIterator first, LMIterator last, Index startRow, Index firstRow, Index lastRow)
1308 for ( ; first!=last; ++first)
1310 for (
auto rgl: first->ridx())
1312 Index rg = rgl.first;
1316 scatterRow<sparsity>(*first,rg-startRow,rgl.second);
1321 template <
int sparsity,
class LM,
class LIndex>
1322 void scatterRow(LM
const& a, Index rg, LIndex rl)
1324 auto cbegin = pat->colStartIterator(rg);
1325 auto cend = pat->colStartIterator(rg+1);
1330 auto pos = std::find(cbegin,cend,rg+pat->first());
1331 assert(pos != cend);
1332 vbegin[pos-cbegin] += a(rl,rl);
1336 for (
auto cgl: a.cidx())
1338 auto pos = sparsity==0? std::lower_bound(cbegin,cend,cgl.first)
1339 : sparsity==1? std::lower_bound(cbegin,cend,cgl.first)
1340 : std::find(cbegin,cend,cgl.first);
1345 vbegin += pos-cbegin;
1348 *vbegin += a(rl,cgl.second);
std::vector< SparseIndexInt > ridx
row indices
std::vector< SparseIndexInt > cidx
column indices
std::vector< Scalar > data
data
An STL allocator that uses memory of a specific NUMA node only.
A NUMA-aware compressed row storage matrix adhering mostly to the Dune ISTL interface (to complete....
iterator end()
returns an iterator to the first row
iterator begin()
returns an iterator to the first row
virtual int size() const
Number of shape functions in the set.
CRSChunk(std::shared_ptr< CRSChunkPattern< Index > > const &pattern_, MatrixAsTriplet< Scalar, Index2 > const &matrix, bool isSymmetric, bool isTransposed)
Constructor.
CRSChunk(int node)
Constructor initializing an empty Chunk.
CRSChunkPattern< Index > const & pattern() const
void scatter(LMIterator first, LMIterator last)
Scatters given sub-matrices into the chunk by adding up their entries.
CRSChunk(std::shared_ptr< CRSChunkPattern< Index > > const &pattern_, Entry const &init)
Constructor.
auto valStartIterator(Index row)
Returns an iterator to the start of the values for the given local row index.
void applyTransposed(Scalar a, Domain const &x, Range &y) const
Transpose matrix-vector multiplication or .
Scalar apply(Scalar a, Domain const &x, Range &y, bool initialize) const
Matrix-vector multiplication or and .
CRSChunk(std::shared_ptr< CRSChunkPattern< Index > > const &pattern_, Matrix const &matrix, bool isSymmetric, bool isTransposed)
Constructor.
CRSChunk(std::shared_ptr< CRSChunkPattern< Index > > const &pattern, CRSChunk< EntryA, IndexA > const &c)
Copy constructor.
Self & operator=(Self const &c)=default
Copy assignment.
void gatherMirrored(Scalar a, Domain const &x, Range &y, CRSChunk< Entry, Index > const &block, bool subdiagonal, bool initToZero) const
Matrix-vector multiplication of transposed parts.
void entrywiseOp(F const &f, NumaBCRSMatrix< EntryB, IndexB > const &B)
Performs entry-wise operations on our own matrix and some other.
CRSChunk(std::shared_ptr< CRSChunkPattern< Index > > const &pattern_, Expanded const &eIndices, Condensed const &cIndices, Matrix const &matrix)
Constructor.
Self & operator=(Value const &a)
Assigns the given value to each entry.
CRSChunk(Matrix const &matrix, bool isSymmetric, bool isTransposed, Index firstRow, Index lastRow, bool symmetric, int node)
Constructor.
Self & operator=(ThreadedMatrixDetail::NumaBCRSMatrixExpressionChunk< Arguments, Operation > const &e)
Assigns the given matrix expression componentwise.
typename EntryTraits< Entry >::field_type Scalar
A class supporting two-stage construction of sparsity patterns of NUMA matrix chunks.
size_t nonzeroes() const
Returns the number of stored entries (structurally nonzero elements).
size_t balanceBackward(size_t covered, size_t const nnz, int chunks, std::vector< IndexArray > &moveRows)
Moves rows in and out of the chunk in order to equilibrate the number of nonzeroes.
CRSChunkPatternCreator(Index firstRow, Index lastRow, Index ncols, bool symmetric, int node)
Constructor.
void addAllElements(Index columns)
Enters all possible elements (defining a dense chunk).
void addElements(IterRow fromRow, IterRow const toRow, IterCol const fromCol, IterCol const toCol, bool colIsSorted=false)
Enters elements into the sparsity pattern.
IndexArray const & row(Index i) const
Returns the sorted and unique column indices of elements in row .
void clear()
Clears the complete data, handing back the memory.
size_t balanceForward(size_t const covered, size_t const nnz, int chunks, std::vector< IndexArray > &moveRows)
Moves rows in and out of the chunk in order to equilibrate the number of nonzeroes.
std::vector< Index > IndexArray
void reserve(Index nnzPerRow=8)
Reserves a certain amount of entries per row.
This class maintains the sparsity structure of a couple of matrix rows (a NUMA matrix chunk).
bool exists(Index r, Index c) const
returns true if the entry with global row and column indices is present in the sparsity pattern
size_t colStart(Index row) const
returns the index from which on the entries in given local row are stored
size_t storage() const
Returns the number of stored entries.
CRSChunkPattern(CRSChunkPatternCreator< Index > const &creator)
Constructor.
CRSChunkPattern(Index first, Index last, Expanded const &eIndices, Condensed const &cIndices, Matrix const &mat, int node)
Constructor.
Index nonzeroesPerRow() const
Returns the average number of nonzeroes per row.
size_t position(Index r, Index c) const
returns the position of an element with given global row and column indices
CRSChunkPattern(CRSChunkPattern< IndexP > const &p)
Copy constructor.
CRSChunkPattern(Matrix const &matrix, bool isSymmetric, bool isTransposed, Index firstRow, Index lastRow, bool symmetric, int node)
Constructor.
CRSChunkPattern(MatrixAsTriplet< Scalar, Index2 > const &matrix, bool isSymmetric, bool isTransposed, Index firstRow, Index lastRow, bool symmetric, int node)
Constructor.
friend class CRSChunkPattern
Index col(size_t idx) const
std::vector< Index, NumaAllocator< Index > >::const_iterator colStartIterator(Index row) const
an iterator pointing to the start of the column index for the given local row
Index columns() const
number of columns in the matrix
int node() const
the NUMA node on which to allocate the memory
Index last() const
end of the half-open row range
CRSChunkPatternInfo(CRSChunkPatternInfo< IndexP > const &pi)
Copy constructor.
CRSChunkPatternInfo(Index first_, Index last_, Index cols_, bool symmetric, int node)
Constructor.
friend class CRSChunkPatternInfo
Index first() const
start of the covered row range
bool symmetric() const
if true, only the lower triangular part is stored
iterator end(size_t) const
iterator begin(size_t) const
ConstIterator end() const
This file contains various utility functions that augment the basic functionality of Dune.
DynamicMatrix< MEntry > submatrix(DynamicMatrix< MEntry > const &A, int rowstart, int rowend, int colstart, int colend)
extracts contiguous submatrices, copying the data
Index uniformWeightRangeStart(BlockIndex i, BlockIndex n, Index m)
Computes partitioning points of ranges for uniform weight distributions.
void getRowCount(Dune::BCRSMatrix< Entry, Allocator > const &matrix, bool isTransposed, std::vector< Index > &rowCount)
static void init(Index first, Index last, Matrix const &matrix, std::vector< size_t, NumaAllocator< size_t > > &colStart, std::vector< Index, NumaAllocator< Index > > &cols, std::vector< Entry, NumaAllocator< Entry > > &values, std::vector< Index > const &nRowEntries)
static void init(Index first, Index last, Matrix const &matrix, std::vector< size_t, NumaAllocator< size_t > > &colStart, std::vector< Index, NumaAllocator< Index > > &cols, std::vector< Entry, NumaAllocator< Entry > > &values, std::vector< Index > const &nRowEntries)
static void init(Index first, Index last, Matrix const &matrix, std::vector< size_t, NumaAllocator< size_t > > &colStart, std::vector< Index, NumaAllocator< Index > > &cols, std::vector< Entry, NumaAllocator< Entry > > &values, std::vector< Index > const &)
static void copy(Entry const &from, Entry &to, bool isTransposed)
static void copy(From const &from, To &to, bool isTransposed)
static void copy(From const &from, To &to, bool isTransposed)