9#include "ProfiledFixedBlockMatrixBuilder.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 ProfiledFixedBlockMatrixBuilder::ProfiledFixedBlockMatrixBuilder(
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 const auto* block = m_matrix_impl->block();
52 if (block ==
nullptr) {
53 throw FatalErrorException(
"matrix must be block");
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;
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();
68 if (reset_values == ProfiledBlockMatrixBuilderOptions::eResetValues)
71 if (profile.getColOrdering() != SimpleCSRInternal::CSRStructInfo::eFull)
72 throw FatalErrorException(
73 A_FUNCINFO,
"Cannot build system without full column ordering");
78 ProfiledFixedBlockMatrixBuilder::~ProfiledFixedBlockMatrixBuilder()
82 m_matrix.impl()->unlock();
87 void ProfiledFixedBlockMatrixBuilder::addData(
88 const Integer iIndex,
const Integer jIndex,
const ConstArray2View<Real> value)
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");
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];
103 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
105 const Integer ngcols = row_size - ncols;
106 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
108#ifdef CHECKPROFILE_ON_FILLING
110 throw FatalErrorException(A_FUNCINFO,
"Cannot add data on undefined column");
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];
122 void ProfiledFixedBlockMatrixBuilder::addData(
const Integer iIndex,
123 const Integer jIndex,
const Real factor,
const ConstArray2View<Real> value)
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");
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];
138 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
140 const Integer ngcols = row_size - ncols;
141 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
143#ifdef CHECKPROFILE_ON_FILLING
145 throw FatalErrorException(A_FUNCINFO,
"Cannot add data on undefined column");
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];
157 void ProfiledFixedBlockMatrixBuilder::setData(
158 const Integer iIndex,
const Integer jIndex, ConstArray2View<Real> value)
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");
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];
173 col = ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start, ncols));
175 const Integer ngcols = row_size - ncols;
176 col = ncols + ArrayScan::dichotomicScan(jIndex, m_cols.subConstView(row_start + ncols, ngcols));
178#ifdef CHECKPROFILE_ON_FILLING
180 throw FatalErrorException(A_FUNCINFO,
"Cannot set data on undefined column");
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];
192 void ProfiledFixedBlockMatrixBuilder::finalize() { m_finalized =
true; }
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --