Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
BaseProfiledMatrixBuilder.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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
8
9#include "BaseProfiledMatrixBuilder.h"
10
12#include <alien/kernels/simple_csr/CSRStructInfo.h>
13#include <alien/kernels/simple_csr/SimpleCSRMatrix.h>
14
15#include <alien/utils/ArrayUtils.h>
16
17// #define CHECKPROFILE_ON_FILLING
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace Alien
23{
24
25using namespace Arccore;
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Common
31{
32
33 /*---------------------------------------------------------------------------*/
34 /*---------------------------------------------------------------------------*/
35
36 ProfiledMatrixBuilder::ProfiledMatrixBuilder(
37 IMatrix& matrix, const ResetFlag reset_values)
38 : m_matrix(matrix)
39 , m_finalized(false)
40 {
41 m_matrix.impl()->lock();
42 m_matrix_impl = &m_matrix.impl()->get<BackEnd::tag::simplecsr>(true);
43
44 const MatrixDistribution& dist = m_matrix_impl->distribution();
45
46 m_local_size = dist.localRowSize();
47 m_local_offset = dist.rowOffset();
48 m_next_offset = m_local_offset + m_local_size;
49
50 SimpleCSRInternal::CSRStructInfo const& profile =
51 m_matrix_impl->internal()->getCSRProfile();
52 m_row_starts = profile.getRowOffset();
53 m_local_row_size = m_matrix_impl->getDistStructInfo().m_local_row_size;
54 m_cols = profile.getCols();
55 m_values = m_matrix_impl->internal()->getValues();
56
57 if (reset_values == ProfiledMatrixOptions::eResetValues)
58 m_values.fill(0.);
59
60 if (profile.getColOrdering() != SimpleCSRInternal::CSRStructInfo::eFull)
61 throw FatalErrorException(
62 A_FUNCINFO, "Cannot build system without full column ordering");
63 }
64
65 /*---------------------------------------------------------------------------*/
66
67 ProfiledMatrixBuilder::~ProfiledMatrixBuilder()
68 {
69 if (!m_finalized) {
70 finalize();
71 }
72 }
73
74 /*---------------------------------------------------------------------------*/
75 Real ProfiledMatrixBuilder::getData(const Integer iIndex, const Integer jIndex) const
76 {
77 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
78 const Integer local_row = iIndex - m_local_offset;
79#ifdef CHECKPROFILE_ON_FILLING
80 if (local_row < 0 or local_row >= m_local_size)
81 throw FatalErrorException("Cannot add data on undefined row");
82#endif /* CHECKPROFILE_ON_FILLING */
83 const Integer row_start = m_row_starts[local_row];
84 const Integer ncols = m_local_row_size[local_row];
85 if (isLocal(jIndex)) {
86 const Integer col =
87 ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
88#ifdef CHECKPROFILE_ON_FILLING
89 if (col == -1)
90 throw FatalErrorException("Cannot add data on undefined column");
91#endif /* CHECKPROFILE_ON_FILLING */
92 return m_values[row_start + col];
93 }
94 else {
95 const Integer ngcols =
96 m_row_starts[iIndex - m_local_offset + 1] - row_start - ncols;
97 const Integer col = ArrayScan::dichotomicScan(
98 jIndex, m_cols.subConstView(row_start + ncols, ngcols));
99#ifdef CHECKPROFILE_ON_FILLING
100 if (col == -1)
101 throw FatalErrorException("Cannot add data on undefined column");
102#endif /* CHECKPROFILE_ON_FILLING */
103 return m_values[row_start + ncols + col];
104 }
105 }
106
107 void ProfiledMatrixBuilder::addData(
108 const Integer iIndex, const Integer jIndex, const Real value)
109 {
110 _startTimer();
111 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
112 const Integer local_row = iIndex - m_local_offset;
113#ifdef CHECKPROFILE_ON_FILLING
114 if (local_row < 0 or local_row >= m_local_size)
115 throw FatalErrorException("Cannot add data on undefined row");
116#endif /* CHECKPROFILE_ON_FILLING */
117 const Integer row_start = m_row_starts[local_row];
118 const Integer ncols = m_local_row_size[local_row];
119 if (isLocal(jIndex)) {
120 const Integer col =
121 ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
122#ifdef CHECKPROFILE_ON_FILLING
123 if (col == -1)
124 throw FatalErrorException("Cannot add data on undefined column");
125#endif /* CHECKPROFILE_ON_FILLING */
126 m_values[row_start + col] += value;
127 }
128 else {
129 const Integer ngcols =
130 m_row_starts[iIndex - m_local_offset + 1] - row_start - ncols;
131 const Integer col = ArrayScan::dichotomicScan(
132 jIndex, m_cols.subConstView(row_start + ncols, ngcols));
133#ifdef CHECKPROFILE_ON_FILLING
134 if (col == -1)
135 throw FatalErrorException("Cannot add data on undefined column");
136#endif /* CHECKPROFILE_ON_FILLING */
137 m_values[row_start + ncols + col] += value;
138 }
139 _stopTimer();
140 }
141
142 /*---------------------------------------------------------------------------*/
143
144 void ProfiledMatrixBuilder::addData(const Integer iIndex, const Real factor,
145 ConstArrayView<Integer> jIndexes, ConstArrayView<Real> jValues)
146 {
147 _startTimer();
148 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
149 ALIEN_ASSERT((jIndexes.size() == jValues.size()),
150 ("Inconsistent sizes: %d vs %d", jIndexes.size(), jValues.size()));
151 const Integer local_row = iIndex - m_local_offset;
152#ifdef CHECKPROFILE_ON_FILLING
153 if (local_row < 0 or local_row >= m_local_size)
154 throw FatalErrorException("Cannot add data on undefined row");
155#endif /* CHECKPROFILE_ON_FILLING */
156 const Integer row_start = m_row_starts[local_row];
157 const Integer row_size = m_row_starts[local_row + 1] - row_start;
158 const Integer ncols = m_local_row_size[local_row];
159 const Integer n = jIndexes.size();
160 for (Integer j = 0; j < n; ++j) {
161
162 Integer jIndex = jIndexes[j];
163 Integer col = -1;
164 if (isLocal(jIndex)) {
165 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
166 }
167 else {
168 const Integer ngcols = row_size - ncols;
169 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
170 }
171#ifdef CHECKPROFILE_ON_FILLING
172 if (col == -1)
173 throw FatalErrorException("Cannot add data on undefined column");
174#endif /* CHECKPROFILE_ON_FILLING */
175 m_values[row_start + col] += factor * jValues[j];
176 }
177 _stopTimer();
178 }
179
180 /*---------------------------------------------------------------------------*/
181
182 void ProfiledMatrixBuilder::setData(
183 const Integer iIndex, const Integer jIndex, const Real value)
184 {
185 _startTimer();
186 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
187 const Integer local_row = iIndex - m_local_offset;
188#ifdef CHECKPROFILE_ON_FILLING
189 if (local_row < 0 or local_row >= m_local_size)
190 throw FatalErrorException("Cannot set data on undefined row");
191#endif /* CHECKPROFILE_ON_FILLING */
192 const Integer row_start = m_row_starts[local_row];
193 const Integer row_size = m_row_starts[local_row + 1] - row_start;
194 const Integer ncols = m_local_row_size[local_row];
195 Integer col = -1;
196 if (isLocal(jIndex))
197 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
198 else {
199 const Integer ngcols = row_size - ncols;
200 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
201 }
202#ifdef CHECKPROFILE_ON_FILLING
203 if (col == -1)
204 throw FatalErrorException("Cannot set data on undefined column");
205#endif /* CHECKPROFILE_ON_FILLING */
206 m_values[row_start + col] = value;
207 _stopTimer();
208 }
209
210 /*---------------------------------------------------------------------------*/
211
212 void ProfiledMatrixBuilder::setData(const Integer iIndex, const Real factor,
213 ConstArrayView<Integer> jIndexes, ConstArrayView<Real> jValues)
214 {
215 _startTimer();
216 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
217 ALIEN_ASSERT((jIndexes.size() == jValues.size()),
218 ("Inconsistent sizes: %d vs %d", jIndexes.size(), jValues.size()));
219 const Integer local_row = iIndex - m_local_offset;
220#ifdef CHECKPROFILE_ON_FILLING
221 if (local_row < 0 or local_row >= m_local_size)
222 throw FatalErrorException("Cannot set data on undefined row");
223#endif /* CHECKPROFILE_ON_FILLING */
224 const Integer row_start = m_row_starts[local_row];
225 const Integer row_size = m_row_starts[local_row + 1] - row_start;
226 const Integer ncols = m_local_row_size[local_row];
227 const Integer n = jIndexes.size();
228 for (Integer j = 0; j < n; ++j) {
229 Integer jIndex = jIndexes[j];
230 Integer col = -1;
231 if (isLocal(jIndex))
232 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
233 else {
234 const Integer ngcols = row_size - ncols;
235 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
236 }
237#ifdef CHECKPROFILE_ON_FILLING
238 if (col == -1)
239 throw FatalErrorException("Cannot set data on undefined column");
240#endif /* CHECKPROFILE_ON_FILLING */
241 m_values[row_start + col] = factor * jValues[j];
242 }
243 _stopTimer();
244 }
245
246 /*---------------------------------------------------------------------------*/
247
248 void ProfiledMatrixBuilder::finalize()
249 {
250 if (m_finalized)
251 return;
252 m_matrix.impl()->unlock();
253 m_finalized = true;
254 }
255
256 /*---------------------------------------------------------------------------*/
257 /*---------------------------------------------------------------------------*/
258
259} // namespace Common
260
261/*---------------------------------------------------------------------------*/
262/*---------------------------------------------------------------------------*/
263
264} // namespace Alien
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
MultiMatrixImpl.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17