Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
CSRStructInfo.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7#pragma once
8
9#include <vector>
10#include <algorithm>
11#include <alien/kernels/simple_csr/SimpleCSRPrecomp.h>
12#include <alien/utils/StdTimer.h>
13
14namespace Alien::SimpleCSRInternal
15{
16
17/*---------------------------------------------------------------------------*/
18
19class CSRStructInfo
20{
21 public:
22 enum ColOrdering
23 {
24 eUndef,
25 eOwnAndGhost,
26 eFull
27 };
28
29 typedef Integer IndexType;
30 typedef Alien::StdTimer TimerType;
31 typedef TimerType::Sentry SentryType;
32
33 public:
34 // Remark: variable block should not be taken into account in profile
35 // variable block is a matrix property.
36
37 CSRStructInfo(bool is_variable_block = false)
38 : m_is_variable_block(is_variable_block)
39 {}
40
41 CSRStructInfo(Integer nrow, bool is_variable_block = false)
42 : m_is_variable_block(is_variable_block)
43 , m_nrow(nrow)
44 {
45 m_row_offset.resize(nrow + 1);
46 if (m_is_variable_block)
47 m_block_row_offset.resize(nrow + 1);
48 }
49
50 CSRStructInfo(Integer nrow, const int* kcol, const int* cols)
51 : m_is_variable_block(false)
52 , m_nrow(nrow)
53 {
54 m_row_offset.resize(nrow + 1);
55 std::copy(kcol, kcol + nrow + 1, m_row_offset.data());
56 Integer nnz = kcol[nrow];
57 m_cols.resize(nnz);
58 std::copy(cols, cols + nnz, m_cols.data());
59 }
60
61 CSRStructInfo(const CSRStructInfo& src) { copy(src); }
62
63 virtual ~CSRStructInfo()
64 {
65#ifdef ALIEN_USE_PERF_TIMER
66 m_timer.printInfo("CSR-StructInfo");
67#endif
68 }
69
70 CSRStructInfo& operator=(const CSRStructInfo& src)
71 {
72 this->copy(src);
73 return *this;
74 }
75
76 CSRStructInfo* clone() const
77 {
78 return new CSRStructInfo(*this);
79 }
80
81 void init(Arccore::Integer nrow)
82 {
83 m_nrow = nrow;
84 m_row_offset.resize(nrow + 1);
85 if (m_is_variable_block)
86 m_block_row_offset.resize(nrow + 1);
87 }
88
89 void init(Integer nrows, Integer nnz)
90 {
91 assert(!m_is_variable_block);
92 m_nrow = nrows;
93 m_row_offset.resize(nrows + 1);
94 m_row_offset.fill(0);
95 m_row_offset[nrows] = nnz;
96 m_cols.resize(nnz);
97 }
98
99 Arccore::Int64 timestamp() const
100 {
101 return m_timestamp;
102 }
103
104 void setTimestamp(Arccore::Int64 value)
105 {
106 m_timestamp = value;
107 }
108
109 bool getSymmetric() const
110 {
111 return m_symmetric;
112 }
113
114 void setSymmetric(bool value)
115 {
116 m_symmetric = value;
117 }
118
119 Integer getNRows() const
120 {
121 return m_nrow;
122 }
123
124 Integer getNRow() const
125 {
126 return m_nrow;
127 }
128
129 Arccore::UniqueArray<Arccore::Integer>& getBlockRowOffset()
130 {
131 return m_block_row_offset;
132 }
133
134 Arccore::ArrayView<Integer> getRowOffset()
135 {
136 return m_row_offset.view();
137 }
138
139 Arccore::ConstArrayView<Integer> getRowOffset() const
140 {
141 return m_row_offset.constView();
142 }
143
144 const int* kcol() const
145 {
146 return m_row_offset.data();
147 }
148
149 int* kcol()
150 {
151 return m_row_offset.data();
152 }
153
154 ConstArrayView<Integer> getBlockRowOffset() const
155 {
156 return m_block_row_offset.constView();
157 }
158
159 UniqueArray<Integer>& getCols()
160 {
161 return m_cols;
162 }
163
164 UniqueArray<Integer>& getBlockCols()
165 {
166 return m_block_cols;
167 }
168
169 ConstArrayView<Integer> getCols() const
170 {
171 return m_cols.constView();
172 }
173
174 int* cols()
175 {
176 return m_cols.data();
177 }
178
179 const int* cols() const
180 {
181 return m_cols.data();
182 }
183
184 ConstArrayView<Integer> getBlockCols() const
185 {
186 return m_block_cols.constView();
187 }
188
189 ColOrdering& getColOrdering()
190 {
191 return m_col_ordering;
192 }
193
194 ColOrdering getColOrdering() const
195 {
196 return m_col_ordering;
197 }
198
199 void setDiagFirst(bool val)
200 {
201 m_diag_first = val;
202 }
203
204 bool getDiagFirstOpt() const
205 {
206 return m_diag_first;
207 }
208
209 Integer getRowSize(Integer row) const
210 {
211 return m_row_offset[row + 1] - m_row_offset[row];
212 }
213
214 Integer getBlockRowSize(Integer row) const
215 {
216 return m_block_row_offset[row + 1] - m_block_row_offset[row];
217 }
218
219 Integer getNnz() const
220 {
221 return m_row_offset[m_nrow];
222 }
223
224 Integer getNElems() const
225 {
226 return m_row_offset[m_nrow];
227 }
228
229 Integer getBlockNnz() const
230 {
231 return m_block_row_offset[m_nrow];
232 }
233
234 UniqueArray<Integer>& getUpperDiagOffset()
235 {
236 if (m_col_ordering != eUndef && m_upper_diag_offset.size() == 0)
237 computeUpperDiagOffset();
238 return m_upper_diag_offset;
239 }
240
241 ConstArrayView<Integer> getUpperDiagOffset() const
242 {
243 if (m_col_ordering != eUndef && m_upper_diag_offset.size() == 0)
244 computeUpperDiagOffset();
245 return m_upper_diag_offset.constView();
246 }
247
248 int const* dcol() const
249 {
250 if (m_col_ordering == eUndef)
251 return nullptr;
252 else {
253 getUpperDiagOffset();
254 return m_upper_diag_offset.data();
255 }
256 }
257
258 void allocate()
259 {
260 auto row_offset = (m_nrow > 0) ? m_row_offset[m_nrow] : 0;
261 m_cols.resize(row_offset);
262 if (m_is_variable_block)
263 m_block_cols.resize(row_offset + 1);
264 }
265
266 void computeUpperDiagOffset() const
267 {
268#ifdef ALIEN_USE_PERF_TIMER
269 SentryType sentry(m_timer, "CSR-ComputeDiagOffset");
270#endif
271 if (m_col_ordering != eUndef) {
272 m_upper_diag_offset.resize(m_nrow);
273 for (int irow = 0; irow < m_nrow; ++irow) {
274 int index = m_row_offset[irow];
275 for (int k = m_row_offset[irow]; k < m_row_offset[irow + 1]; ++k) {
276 if (m_cols[k] < irow)
277 ++index;
278 else
279 break;
280 }
281 m_upper_diag_offset[irow] = index;
282 }
283 }
284 }
285
286 Integer computeBandeSize() const
287 {
288 int bande_size = 0;
289 for (int irow = 0; irow < m_nrow; ++irow) {
290 int min_col = irow;
291 int max_col = irow;
292 for (int k = m_row_offset[irow]; k < m_row_offset[irow + 1]; ++k) {
293 int col = m_cols[k];
294 min_col = std::min(col, min_col);
295 max_col = std::max(col, max_col);
296 }
297 bande_size = std::max(bande_size, max_col - min_col);
298 }
299 return bande_size;
300 }
301
302 Integer computeUpperBandeSize() const
303 {
304 int bande_size = 0;
305 for (int irow = 0; irow < m_nrow; ++irow) {
306 int max_col = irow;
307 for (int k = m_row_offset[irow]; k < m_row_offset[irow + 1]; ++k) {
308 int col = m_cols[k];
309 max_col = std::max(col, max_col);
310 }
311 bande_size = std::max(bande_size, max_col - irow);
312 }
313 return bande_size;
314 }
315
316 Integer computeLowerBandeSize() const
317 {
318 std::vector<int> maxRow(m_nrow);
319 for (int col = 0; col < m_nrow; ++col)
320 maxRow[col] = col;
321 for (int irow = 0; irow < m_nrow; ++irow) {
322 for (int k = m_row_offset[irow]; k < m_row_offset[irow + 1]; ++k) {
323 int col = m_cols[k];
324 maxRow[col] = std::max(maxRow[col], irow);
325 }
326 }
327 int bande_size = 0;
328 for (int col = 0; col < m_nrow; ++col)
329 bande_size = std::max(bande_size, maxRow[col]);
330 return bande_size;
331 }
332
333 Integer computeMaxRowSize() const
334 {
335 m_max_row_size = 0;
336 for (int irow = 0; irow < m_nrow; ++irow)
337 m_max_row_size = std::max(m_max_row_size, m_row_offset[irow + 1] - m_row_offset[irow]);
338 return m_max_row_size;
339 }
340
341 Integer getMaxRowSize() const
342 {
343 if (m_max_row_size == -1)
344 computeMaxRowSize();
345 return m_max_row_size;
346 }
347
348 void copy(const CSRStructInfo& profile)
349 {
350 auto nrows = profile.getNRows();
351 init(nrows);
352
353 m_row_offset.copy(profile.getRowOffset());
354
355 allocate();
356
357 m_cols.copy(profile.getCols());
358
359 if (m_is_variable_block) {
360 m_block_row_offset.copy(profile.getBlockRowOffset());
361 m_block_cols.copy(profile.getBlockCols());
362 }
363
364 m_col_ordering = profile.getColOrdering();
365
366 setDiagFirst(profile.getDiagFirstOpt());
367
368 m_upper_diag_offset.copy(profile.getUpperDiagOffset());
369
370 setSymmetric(profile.getSymmetric());
371 }
372
373 protected:
374 bool m_is_variable_block = false;
375 Arccore::Integer m_nrow = 0;
376 ColOrdering m_col_ordering = eUndef;
377 bool m_diag_first = false;
378 mutable int m_max_row_size = -1;
379 bool m_symmetric = true;
380 Arccore::Int64 m_timestamp = -1;
381 Arccore::UniqueArray<Arccore::Integer> m_row_offset;
382 Arccore::UniqueArray<Arccore::Integer> m_block_row_offset;
383 Arccore::UniqueArray<Arccore::Integer> m_cols;
384 Arccore::UniqueArray<Arccore::Integer> m_block_cols;
385 mutable Arccore::UniqueArray<Arccore::Integer> m_upper_diag_offset;
386#ifdef ALIEN_USE_PERF_TIMER
387 private:
388 mutable TimerType m_timer;
389#endif
390};
391
392/*---------------------------------------------------------------------------*/
393
394} // namespace Alien::SimpleCSRInternal
395
396/*---------------------------------------------------------------------------*/