9#include "BaseProfiledMatrixBuilder.h"
12#include <alien/kernels/simple_csr/CSRStructInfo.h>
13#include <alien/kernels/simple_csr/SimpleCSRMatrix.h>
15#include <alien/utils/ArrayUtils.h>
25using namespace Arccore;
36 ProfiledMatrixBuilder::ProfiledMatrixBuilder(
37 IMatrix& matrix,
const ResetFlag reset_values)
41 m_matrix.impl()->lock();
42 m_matrix_impl = &m_matrix.impl()->get<BackEnd::tag::simplecsr>(
true);
44 const MatrixDistribution& dist = m_matrix_impl->distribution();
46 m_local_size = dist.localRowSize();
47 m_local_offset = dist.rowOffset();
48 m_next_offset = m_local_offset + m_local_size;
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();
57 if (reset_values == ProfiledMatrixOptions::eResetValues)
60 if (profile.getColOrdering() != SimpleCSRInternal::CSRStructInfo::eFull)
61 throw FatalErrorException(
62 A_FUNCINFO,
"Cannot build system without full column ordering");
67 ProfiledMatrixBuilder::~ProfiledMatrixBuilder()
75 Real ProfiledMatrixBuilder::getData(
const Integer iIndex,
const Integer jIndex)
const
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");
83 const Integer row_start = m_row_starts[local_row];
84 const Integer ncols = m_local_row_size[local_row];
85 if (isLocal(jIndex)) {
87 ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
88#ifdef CHECKPROFILE_ON_FILLING
90 throw FatalErrorException(
"Cannot add data on undefined column");
92 return m_values[row_start + col];
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
101 throw FatalErrorException(
"Cannot add data on undefined column");
103 return m_values[row_start + ncols + col];
107 void ProfiledMatrixBuilder::addData(
108 const Integer iIndex,
const Integer jIndex,
const Real value)
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");
117 const Integer row_start = m_row_starts[local_row];
118 const Integer ncols = m_local_row_size[local_row];
119 if (isLocal(jIndex)) {
121 ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
122#ifdef CHECKPROFILE_ON_FILLING
124 throw FatalErrorException(
"Cannot add data on undefined column");
126 m_values[row_start + col] += value;
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
135 throw FatalErrorException(
"Cannot add data on undefined column");
137 m_values[row_start + ncols + col] += value;
144 void ProfiledMatrixBuilder::addData(
const Integer iIndex,
const Real factor,
145 ConstArrayView<Integer> jIndexes, ConstArrayView<Real> jValues)
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");
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) {
162 Integer jIndex = jIndexes[j];
164 if (isLocal(jIndex)) {
165 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
168 const Integer ngcols = row_size - ncols;
169 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
171#ifdef CHECKPROFILE_ON_FILLING
173 throw FatalErrorException(
"Cannot add data on undefined column");
175 m_values[row_start + col] += factor * jValues[j];
182 void ProfiledMatrixBuilder::setData(
183 const Integer iIndex,
const Integer jIndex,
const Real value)
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");
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];
197 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
199 const Integer ngcols = row_size - ncols;
200 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
202#ifdef CHECKPROFILE_ON_FILLING
204 throw FatalErrorException(
"Cannot set data on undefined column");
206 m_values[row_start + col] = value;
212 void ProfiledMatrixBuilder::setData(
const Integer iIndex,
const Real factor,
213 ConstArrayView<Integer> jIndexes, ConstArrayView<Real> jValues)
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");
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];
232 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
234 const Integer ngcols = row_size - ncols;
235 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
237#ifdef CHECKPROFILE_ON_FILLING
239 throw FatalErrorException(
"Cannot set data on undefined column");
241 m_values[row_start + col] = factor * jValues[j];
248 void ProfiledMatrixBuilder::finalize()
252 m_matrix.impl()->unlock();
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --