Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
ProfiledVBlockMatrixBuilder.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 "ProfiledVBlockMatrixBuilder.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
29namespace Common
30{
31
32 /*---------------------------------------------------------------------------*/
33 /*---------------------------------------------------------------------------*/
34
35 ProfiledVBlockMatrixBuilder::ProfiledVBlockMatrixBuilder(
36 IMatrix& matrix, const ResetFlag reset_values)
37 : m_matrix(matrix)
38 , m_finalized(false)
39 {
40 m_matrix.impl()->lock();
41 m_matrix_impl = &m_matrix.impl()->get<BackEnd::tag::simplecsr>(true);
42
43 const ISpace& space = m_matrix.rowSpace();
44 // if (space != m_matrix.colSpace())
45 // throw FatalErrorException(
46 // "profiled matrix builder must be used with square matrix");
47
48 const MatrixDistribution& dist = m_matrix_impl->distribution();
49
50 m_vblock = m_matrix_impl->vblock();
51
52 if (m_vblock == nullptr) {
53 throw FatalErrorException("matrix must be vblock");
54 }
55
56 m_local_size = dist.localRowSize();
57 m_local_offset = dist.rowOffset();
58 m_next_offset = m_local_offset + m_local_size;
59
60 SimpleCSRInternal::CSRStructInfo const& profile =
61 m_matrix_impl->internal()->getCSRProfile();
62 m_row_starts = profile.getRowOffset();
63 m_block_cols = profile.getBlockCols();
64 m_cols = profile.getCols();
65 m_local_row_size = m_matrix_impl->getDistStructInfo().m_local_row_size;
66 m_values = m_matrix_impl->internal()->getValues();
67
68 if (reset_values == ProfiledVBlockMatrixBuilderOptions::eResetValues)
69 m_values.fill(0.);
70
71 if (profile.getColOrdering() != SimpleCSRInternal::CSRStructInfo::eFull)
72 throw FatalErrorException(
73 A_FUNCINFO, "Cannot build system without full column ordering");
74 }
75
76 /*---------------------------------------------------------------------------*/
77
78 ProfiledVBlockMatrixBuilder::~ProfiledVBlockMatrixBuilder()
79 {
80 if (!m_finalized)
81 finalize();
82 m_matrix.impl()->unlock();
83 }
84
85 /*---------------------------------------------------------------------------*/
86
87 void ProfiledVBlockMatrixBuilder::addData(
88 const Integer iIndex, const Integer jIndex, const ConstArray2View<Real> value)
89 {
90 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
91 auto row_block_size = m_vblock->size(iIndex);
92 auto col_block_size = m_vblock->size(jIndex);
93 ALIEN_ASSERT((value.dim1Size() == row_block_size), ("Block size error"));
94 ALIEN_ASSERT((value.dim2Size() == col_block_size), ("Block size error"));
95 const Integer local_row = iIndex - m_local_offset;
96#ifdef CHECKPROFILE_ON_FILLING
97 if (local_row < 0 or local_row >= m_local_size)
98 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined row");
99#endif /* CHECKPROFILE_ON_FILLING */
100 const Integer row_start = m_row_starts[local_row];
101 const Integer row_size = m_row_starts[local_row + 1] - row_start;
102 const Integer ncols = m_local_row_size[local_row];
103 Integer col = -1;
104 if (isLocal(jIndex))
105 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
106 else {
107 const Integer ngcols = row_size - ncols;
108 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
109 }
110#ifdef CHECKPROFILE_ON_FILLING
111 if (col == -1)
112 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined column");
113#endif /* CHECKPROFILE_ON_FILLING */
114 const Integer bcols_offset = m_block_cols[col];
115 Array2View<Real> block(&m_values[bcols_offset], row_block_size, col_block_size);
116 for (Integer i = 0; i < row_block_size; ++i)
117 for (Integer j = 0; j < col_block_size; ++j)
118 block[i][j] += value[i][j];
119 }
120
121 /*---------------------------------------------------------------------------*/
122
123 void ProfiledVBlockMatrixBuilder::addData(const Integer iIndex,
124 const Integer jIndex, const Real factor, const ConstArray2View<Real> value)
125 {
126 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
127 auto row_block_size = m_vblock->size(iIndex);
128 auto col_block_size = m_vblock->size(jIndex);
129 ALIEN_ASSERT((value.dim1Size() == row_block_size), ("Block size error"));
130 ALIEN_ASSERT((value.dim2Size() == col_block_size), ("Block size error"));
131 const Integer local_row = iIndex - m_local_offset;
132#ifdef CHECKPROFILE_ON_FILLING
133 if (local_row < 0 or local_row >= m_local_size)
134 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined row");
135#endif /* CHECKPROFILE_ON_FILLING */
136 const Integer row_start = m_row_starts[local_row];
137 const Integer row_size = m_row_starts[local_row + 1] - row_start;
138 const Integer ncols = m_local_row_size[local_row];
139 Integer col = -1;
140 if (isLocal(jIndex))
141 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
142 else {
143 const Integer ngcols = row_size - ncols;
144 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
145 }
146#ifdef CHECKPROFILE_ON_FILLING
147 if (col == -1)
148 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined column");
149#endif /* CHECKPROFILE_ON_FILLING */
150 const Integer bcols_offset = m_block_cols[col];
151 Array2View<Real> block(&m_values[bcols_offset], row_block_size, col_block_size);
152 for (Integer i = 0; i < row_block_size; ++i)
153 for (Integer j = 0; j < col_block_size; ++j)
154 block[i][j] += factor * value[i][j];
155 }
156
157 /*---------------------------------------------------------------------------*/
158
159 void ProfiledVBlockMatrixBuilder::setData(
160 const Integer iIndex, const Integer jIndex, ConstArray2View<Real> value)
161 {
162 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
163 auto row_block_size = m_vblock->size(iIndex);
164 auto col_block_size = m_vblock->size(jIndex);
165 ALIEN_ASSERT((value.dim1Size() == row_block_size), ("Block size error"));
166 ALIEN_ASSERT((value.dim2Size() == col_block_size), ("Block size error"));
167 const Integer local_row = iIndex - m_local_offset;
168#ifdef CHECKPROFILE_ON_FILLING
169 if (local_row < 0 or local_row >= m_local_size)
170 throw FatalErrorException(A_FUNCINFO, "Cannot set data on undefined row");
171#endif /* CHECKPROFILE_ON_FILLING */
172 const Integer row_start = m_row_starts[local_row];
173 const Integer row_size = m_row_starts[local_row + 1] - row_start;
174 const Integer ncols = m_local_row_size[local_row];
175 Integer col = -1;
176 if (isLocal(jIndex))
177 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
178 else {
179 const Integer ngcols = row_size - ncols;
180 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
181 }
182#ifdef CHECKPROFILE_ON_FILLING
183 if (col == -1)
184 throw FatalErrorException(A_FUNCINFO, "Cannot set data on undefined column");
185#endif /* CHECKPROFILE_ON_FILLING */
186 const Integer bcols_offset = m_block_cols[col];
187 Array2View<Real> block(&m_values[bcols_offset], row_block_size, col_block_size);
188 for (Integer i = 0; i < row_block_size; ++i)
189 for (Integer j = 0; j < col_block_size; ++j)
190 block[i][j] = value[i][j];
191 }
192
193 /*---------------------------------------------------------------------------*/
194
195 void ProfiledVBlockMatrixBuilder::finalize() { m_finalized = true; }
196
197 /*---------------------------------------------------------------------------*/
198 /*---------------------------------------------------------------------------*/
199
200} // namespace Common
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
205} // namespace Alien
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
MultiMatrixImpl.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17