Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
ProfiledFixedBlockMatrixBuilder.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 "ProfiledFixedBlockMatrixBuilder.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 ProfiledFixedBlockMatrixBuilder::ProfiledFixedBlockMatrixBuilder(
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 const auto* block = m_matrix_impl->block();
51
52 if (block == nullptr) {
53 throw FatalErrorException("matrix must be block");
54 }
55
56 m_block_size = block->size();
57 m_local_size = dist.localRowSize();
58 m_local_offset = dist.rowOffset();
59 m_next_offset = m_local_offset + m_local_size;
60
61 SimpleCSRInternal::CSRStructInfo const& profile =
62 m_matrix_impl->internal()->getCSRProfile();
63 m_row_starts = profile.getRowOffset();
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 == ProfiledBlockMatrixBuilderOptions::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 ProfiledFixedBlockMatrixBuilder::~ProfiledFixedBlockMatrixBuilder()
79 {
80 if (!m_finalized)
81 finalize();
82 m_matrix.impl()->unlock();
83 }
84
85 /*---------------------------------------------------------------------------*/
86
87 void ProfiledFixedBlockMatrixBuilder::addData(
88 const Integer iIndex, const Integer jIndex, const ConstArray2View<Real> value)
89 {
90 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
91 ALIEN_ASSERT((value.dim1Size() == m_block_size), ("Block size error"));
92 ALIEN_ASSERT((value.dim2Size() == m_block_size), ("Block size error"));
93 const Integer local_row = iIndex - m_local_offset;
94#ifdef CHECKPROFILE_ON_FILLING
95 if (local_row < 0 or local_row >= m_local_size)
96 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined row");
97#endif /* CHECKPROFILE_ON_FILLING */
98 const Integer row_start = m_row_starts[local_row];
99 const Integer row_size = m_row_starts[local_row + 1] - row_start;
100 const Integer ncols = m_local_row_size[local_row];
101 Integer col = -1;
102 if (isLocal(jIndex))
103 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
104 else {
105 const Integer ngcols = row_size - ncols;
106 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
107 }
108#ifdef CHECKPROFILE_ON_FILLING
109 if (col == -1)
110 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined column");
111#endif /* CHECKPROFILE_ON_FILLING */
112 const Integer brow_start = row_start * m_block_size * m_block_size;
113 const Integer bcol = col * m_block_size * m_block_size;
114 Array2View<Real> block(&m_values[brow_start + bcol], m_block_size, m_block_size);
115 for (Integer i = 0; i < m_block_size; ++i)
116 for (Integer j = 0; j < m_block_size; ++j)
117 block[i][j] += value[i][j];
118 }
119
120 /*---------------------------------------------------------------------------*/
121
122 void ProfiledFixedBlockMatrixBuilder::addData(const Integer iIndex,
123 const Integer jIndex, const Real factor, const ConstArray2View<Real> value)
124 {
125 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
126 ALIEN_ASSERT((value.dim1Size() == m_block_size), ("Block size error"));
127 ALIEN_ASSERT((value.dim2Size() == m_block_size), ("Block size error"));
128 const Integer local_row = iIndex - m_local_offset;
129#ifdef CHECKPROFILE_ON_FILLING
130 if (local_row < 0 or local_row >= m_local_size)
131 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined row");
132#endif /* CHECKPROFILE_ON_FILLING */
133 const Integer row_start = m_row_starts[local_row];
134 const Integer row_size = m_row_starts[local_row + 1] - row_start;
135 const Integer ncols = m_local_row_size[local_row];
136 Integer col = -1;
137 if (isLocal(jIndex))
138 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
139 else {
140 const Integer ngcols = row_size - ncols;
141 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
142 }
143#ifdef CHECKPROFILE_ON_FILLING
144 if (col == -1)
145 throw FatalErrorException(A_FUNCINFO, "Cannot add data on undefined column");
146#endif /* CHECKPROFILE_ON_FILLING */
147 const Integer brow_start = row_start * m_block_size * m_block_size;
148 const Integer bcol = col * m_block_size * m_block_size;
149 Array2View<Real> block(&m_values[brow_start + bcol], m_block_size, m_block_size);
150 for (Integer i = 0; i < m_block_size; ++i)
151 for (Integer j = 0; j < m_block_size; ++j)
152 block[i][j] += factor * value[i][j];
153 }
154
155 /*---------------------------------------------------------------------------*/
156
157 void ProfiledFixedBlockMatrixBuilder::setData(
158 const Integer iIndex, const Integer jIndex, ConstArray2View<Real> value)
159 {
160 ALIEN_ASSERT((!m_finalized), ("Finalized matrix cannot be modified"));
161 ALIEN_ASSERT((value.dim1Size() == m_block_size), ("Block size error"));
162 ALIEN_ASSERT((value.dim2Size() == m_block_size), ("Block size error"));
163 const Integer local_row = iIndex - m_local_offset;
164#ifdef CHECKPROFILE_ON_FILLING
165 if (local_row < 0 or local_row >= m_local_size)
166 throw FatalErrorException(A_FUNCINFO, "Cannot set data on undefined row");
167#endif /* CHECKPROFILE_ON_FILLING */
168 const Integer row_start = m_row_starts[local_row];
169 const Integer row_size = m_row_starts[local_row + 1] - row_start;
170 const Integer ncols = m_local_row_size[local_row];
171 Integer col = -1;
172 if (isLocal(jIndex))
173 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
174 else {
175 const Integer ngcols = row_size - ncols;
176 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
177 }
178#ifdef CHECKPROFILE_ON_FILLING
179 if (col == -1)
180 throw FatalErrorException(A_FUNCINFO, "Cannot set data on undefined column");
181#endif /* CHECKPROFILE_ON_FILLING */
182 const Integer brow_start = row_start * m_block_size * m_block_size;
183 const Integer bcol = col * m_block_size * m_block_size;
184 Array2View<Real> block(&m_values[brow_start + bcol], m_block_size, m_block_size);
185 for (Integer i = 0; i < m_block_size; ++i)
186 for (Integer j = 0; j < m_block_size; ++j)
187 block[i][j] = value[i][j];
188 }
189
190 /*---------------------------------------------------------------------------*/
191
192 void ProfiledFixedBlockMatrixBuilder::finalize() { m_finalized = true; }
193
194 /*---------------------------------------------------------------------------*/
195 /*---------------------------------------------------------------------------*/
196
197} // namespace Common
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201
202} // namespace Alien
203
204/*---------------------------------------------------------------------------*/
205/*---------------------------------------------------------------------------*/
MultiMatrixImpl.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17