OGS
ProcessLib::Assembly::MatrixElementCache< Dim > Class Template Referencefinal

Detailed Description

template<std::size_t Dim>
class ProcessLib::Assembly::MatrixElementCache< Dim >

Definition at line 65 of file MatrixElementCache.h.

#include <MatrixElementCache.h>

Collaboration diagram for ProcessLib::Assembly::MatrixElementCache< Dim >:
[legend]

Public Member Functions

 MatrixElementCache (MatOrVec &mat_or_vec, Stats &stats, const int num_threads)
void add (std::vector< double > const &local_data, std::vector< GlobalIndexType > const &indices)
 ~MatrixElementCache ()

Private Types

using MatOrVec = std::conditional_t<Dim == 1, GlobalVector, GlobalMatrix>

Private Member Functions

void addToCache (std::vector< double > const &values, std::vector< GlobalIndexType > const &indices)
void addToCacheImpl (std::vector< double > const &values, std::vector< GlobalIndexType > const &indices, std::integral_constant< std::size_t, 1 >)
void addToCacheImpl (std::vector< double > const &values, std::vector< GlobalIndexType > const &indices, std::integral_constant< std::size_t, 2 >)
void ensureEnoughSpace (std::size_t const space_needed)
OGS_NO_INLINE void ensureEnoughSpaceSlow (std::size_t const space_needed)
void addCacheToGlobal ()

Private Attributes

std::vector< MatrixElementCacheEntry< Dim > > cache_
MatOrVecmat_or_vec_
Statsstats_
int num_threads_

Static Private Attributes

static constexpr std::size_t cache_capacity = 1'000'000

Member Typedef Documentation

◆ MatOrVec

template<std::size_t Dim>
using ProcessLib::Assembly::MatrixElementCache< Dim >::MatOrVec = std::conditional_t<Dim == 1, GlobalVector, GlobalMatrix>
private

Definition at line 68 of file MatrixElementCache.h.

Constructor & Destructor Documentation

◆ MatrixElementCache()

template<std::size_t Dim>
ProcessLib::Assembly::MatrixElementCache< Dim >::MatrixElementCache ( MatOrVec & mat_or_vec,
Stats & stats,
const int num_threads )
inline

◆ ~MatrixElementCache()

template<std::size_t Dim>
ProcessLib::Assembly::MatrixElementCache< Dim >::~MatrixElementCache ( )
inline

Member Function Documentation

◆ add()

template<std::size_t Dim>
void ProcessLib::Assembly::MatrixElementCache< Dim >::add ( std::vector< double > const & local_data,
std::vector< GlobalIndexType > const & indices )
inline

Definition at line 80 of file MatrixElementCache.h.

82 {
83 if (local_data.empty())
84 {
85 return;
86 }
87
88 if (num_threads_ == 1)
89 {
90 if constexpr (Dim == 2)
91 {
92 auto const num_r_c = indices.size();
93 mat_or_vec_.add(
95 indices},
97 }
98 else
99 {
101 }
102 return;
103 }
104
106 }
void addToCache(std::vector< double > const &values, std::vector< GlobalIndexType > const &indices)
Eigen::Map< const Matrix > toMatrix(std::vector< double > const &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)

References addToCache(), mat_or_vec_, num_threads_, and MathLib::toMatrix().

◆ addCacheToGlobal()

template<std::size_t Dim>
void ProcessLib::Assembly::MatrixElementCache< Dim >::addCacheToGlobal ( )
inlineprivate

Definition at line 227 of file MatrixElementCache.h.

228 {
229 if (cache_.empty())
230 {
231 return;
232 }
233
234#pragma omp critical
235 {
236 if constexpr (Dim == 2)
237 {
238 auto const n_cols = mat_or_vec_.getNumberOfColumns();
239
240 // TODO would be more efficient if our global matrix and vector
241 // implementations supported batch addition of matrix elements
242 // with arbitrary indices (not restricted to (n x m) shaped
243 // submatrices).
244 for (auto const [rc, value] : cache_)
245 {
246 auto const [r, c] = rc;
247
248 auto const c_no_ghost =
250
252 }
253 }
254 else
255 {
256 // TODO batch addition would be more efficient. That needs the
257 // refactoring of the matrix element cache.
258 for (auto const [r, value] : cache_)
259 {
260 mat_or_vec_.add(r.front(), value);
261 }
262 }
263 }
264
265 stats_.count_global += cache_.size();
266 cache_.clear();
267 }
GlobalIndexType transformToNonGhostIndex(GlobalIndexType const i, GlobalIndexType const n)

References cache_, mat_or_vec_, stats_, and ProcessLib::Assembly::detail::transformToNonGhostIndex().

Referenced by ~MatrixElementCache(), and ensureEnoughSpaceSlow().

◆ addToCache()

template<std::size_t Dim>
void ProcessLib::Assembly::MatrixElementCache< Dim >::addToCache ( std::vector< double > const & values,
std::vector< GlobalIndexType > const & indices )
inlineprivate

Definition at line 111 of file MatrixElementCache.h.

113 {
115
118 }
void addToCacheImpl(std::vector< double > const &values, std::vector< GlobalIndexType > const &indices, std::integral_constant< std::size_t, 1 >)
void ensureEnoughSpace(std::size_t const space_needed)

References addToCacheImpl(), and ensureEnoughSpace().

Referenced by add().

◆ addToCacheImpl() [1/2]

template<std::size_t Dim>
void ProcessLib::Assembly::MatrixElementCache< Dim >::addToCacheImpl ( std::vector< double > const & values,
std::vector< GlobalIndexType > const & indices,
std::integral_constant< std::size_t, 1 >  )
inlineprivate

Definition at line 121 of file MatrixElementCache.h.

124 {
125 auto const num_r_c = indices.size();
126 auto const* const __restrict val = values.data();
127 auto const* const __restrict idx = indices.data();
128
129 // Count non-zeros first
130 auto const nonzero_count = ranges::count_if(
131 val, val + num_r_c, [](double v) { return v != 0.0; });
132
133 if (nonzero_count == 0)
134 {
135 stats_.count += num_r_c;
136 return;
137 }
138
139 auto entries =
142 { return val[i] != 0.0; }) |
144 [val, idx](std::size_t i)
145 { return MatrixElementCacheEntry<1>{{idx[i]}, val[i]}; });
146
147 auto const old_size = cache_.size();
148 cache_.resize(old_size + nonzero_count);
150
151 stats_.count += num_r_c;
152 stats_.count_nonzero += nonzero_count;
153 }

References cache_, and stats_.

Referenced by addToCache().

◆ addToCacheImpl() [2/2]

template<std::size_t Dim>
void ProcessLib::Assembly::MatrixElementCache< Dim >::addToCacheImpl ( std::vector< double > const & values,
std::vector< GlobalIndexType > const & indices,
std::integral_constant< std::size_t, 2 >  )
inlineprivate

Definition at line 156 of file MatrixElementCache.h.

159 {
160 auto const num_r_c = indices.size();
161 auto const total_entries = num_r_c * num_r_c;
162
163 // Store pointers to avoid repeated dereferencing.
164 auto const* __restrict__ const idx = indices.data();
165 auto const* __restrict__ const val = values.data();
166
167 auto const old_size = cache_.size();
168 cache_.resize(old_size + total_entries);
169 auto* __restrict__ dest = cache_.data() + old_size;
170
171 for (std::size_t r = 0; r < num_r_c; ++r)
172 {
173 auto const r_global = idx[r];
174 for (std::size_t c = 0; c < num_r_c; ++c)
175 {
176 dest->indices[0] = r_global;
177 dest->indices[1] = idx[c];
178 dest->value = val[r * num_r_c + c]; // Row-major indexing
179 ++dest;
180 }
181 }
182
183 stats_.count += total_entries;
184 stats_.count_nonzero += total_entries;
185 }

References cache_, and stats_.

◆ ensureEnoughSpace()

template<std::size_t Dim>
void ProcessLib::Assembly::MatrixElementCache< Dim >::ensureEnoughSpace ( std::size_t const space_needed)
inlineprivate

Definition at line 187 of file MatrixElementCache.h.

188 {
189 // Fast path - inline this check
190 if (cache_.size() + space_needed <= cache_.capacity()) [[likely]]
191 {
192 return;
193 }
194
195 // Slow path - keep in separate function to avoid code bloat
197 }
OGS_NO_INLINE void ensureEnoughSpaceSlow(std::size_t const space_needed)

References cache_, and ensureEnoughSpaceSlow().

Referenced by addToCache().

◆ ensureEnoughSpaceSlow()

template<std::size_t Dim>
OGS_NO_INLINE void ProcessLib::Assembly::MatrixElementCache< Dim >::ensureEnoughSpaceSlow ( std::size_t const space_needed)
inlineprivate

Definition at line 199 of file MatrixElementCache.h.

200 {
201 if (cache_.capacity() < cache_capacity)
202 {
203 cache_.reserve(cache_capacity);
204 }
205
206 auto const size_initial = cache_.size();
207 auto const cap_initial = cache_.capacity();
208
210 {
211 return;
212 }
213
215
216 // ensure again that there is enough capacity (corner case, if initial
217 // capacity is too small because of whatever arcane reason)
218 auto const size_after = cache_.size();
219 auto const cap_after = cache_.capacity();
220
222 {
223 cache_.reserve(size_after + 2 * space_needed);
224 }
225 }

References addCacheToGlobal(), cache_, cache_capacity, and OGS_NO_INLINE.

Referenced by ensureEnoughSpace().

Member Data Documentation

◆ cache_

◆ cache_capacity

template<std::size_t Dim>
std::size_t ProcessLib::Assembly::MatrixElementCache< Dim >::cache_capacity = 1'000'000
staticconstexprprivate

Definition at line 70 of file MatrixElementCache.h.

Referenced by MatrixElementCache(), and ensureEnoughSpaceSlow().

◆ mat_or_vec_

template<std::size_t Dim>
MatOrVec& ProcessLib::Assembly::MatrixElementCache< Dim >::mat_or_vec_
private

Definition at line 270 of file MatrixElementCache.h.

Referenced by MatrixElementCache(), add(), and addCacheToGlobal().

◆ num_threads_

template<std::size_t Dim>
int ProcessLib::Assembly::MatrixElementCache< Dim >::num_threads_
private

Definition at line 272 of file MatrixElementCache.h.

Referenced by MatrixElementCache(), and add().

◆ stats_

template<std::size_t Dim>
Stats& ProcessLib::Assembly::MatrixElementCache< Dim >::stats_
private

The documentation for this class was generated from the following file: