9#include "ProfiledVBlockMatrixBuilder.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;
35 ProfiledVBlockMatrixBuilder::ProfiledVBlockMatrixBuilder(
36 IMatrix& matrix,
const ResetFlag reset_values)
40 m_matrix.impl()->lock();
41 m_matrix_impl = &m_matrix.impl()->get<BackEnd::tag::simplecsr>(
true);
43 const ISpace& space = m_matrix.rowSpace();
48 const MatrixDistribution& dist = m_matrix_impl->distribution();
50 m_vblock = m_matrix_impl->vblock();
52 if (m_vblock ==
nullptr) {
53 throw FatalErrorException(
"matrix must be vblock");
56 m_local_size = dist.localRowSize();
57 m_local_offset = dist.rowOffset();
58 m_next_offset = m_local_offset + m_local_size;
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();
68 if (reset_values == ProfiledVBlockMatrixBuilderOptions::eResetValues)
71 if (profile.getColOrdering() != SimpleCSRInternal::CSRStructInfo::eFull)
72 throw FatalErrorException(
73 A_FUNCINFO,
"Cannot build system without full column ordering");
78 ProfiledVBlockMatrixBuilder::~ProfiledVBlockMatrixBuilder()
82 m_matrix.impl()->unlock();
87 void ProfiledVBlockMatrixBuilder::addData(
88 const Integer iIndex,
const Integer jIndex,
const ConstArray2View<Real> value)
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");
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];
105 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
107 const Integer ngcols = row_size - ncols;
108 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
110#ifdef CHECKPROFILE_ON_FILLING
112 throw FatalErrorException(A_FUNCINFO,
"Cannot add data on undefined column");
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];
123 void ProfiledVBlockMatrixBuilder::addData(
const Integer iIndex,
124 const Integer jIndex,
const Real factor,
const ConstArray2View<Real> value)
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");
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];
141 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
143 const Integer ngcols = row_size - ncols;
144 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
146#ifdef CHECKPROFILE_ON_FILLING
148 throw FatalErrorException(A_FUNCINFO,
"Cannot add data on undefined column");
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];
159 void ProfiledVBlockMatrixBuilder::setData(
160 const Integer iIndex,
const Integer jIndex, ConstArray2View<Real> value)
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");
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];
177 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
179 const Integer ngcols = row_size - ncols;
180 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
182#ifdef CHECKPROFILE_ON_FILLING
184 throw FatalErrorException(A_FUNCINFO,
"Cannot set data on undefined column");
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];
195 void ProfiledVBlockMatrixBuilder::finalize() { m_finalized =
true; }
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --