99 typedef val_t value_type;
100 typedef val_t val_type;
101 typedef col_t col_type;
102 typedef ptr_t ptr_type;
109 size_t m_nb_non_zero = 0;
114 bool own_data =
true;
116 [[nodiscard]]
size_t nbRow()
const noexcept {
return m_nb_row; }
117 void setNbRow(
size_t v) { m_nb_row = v; }
119 [[nodiscard]]
size_t nbNonZero()
const noexcept {
return m_nb_non_zero; }
120 void setNbNonZero(
size_t v) { m_nb_non_zero = v; }
124 CSRMatrix() =
default;
126 template <
class PtrRange,
class ColRange,
class ValRange>
127 CSRMatrix(
size_t nrows,
size_t ncols,
const PtrRange& ptr_range,
const ColRange& col_range,
const ValRange& val_range)
131 ARCCORE_ALINA_TIC(
"CSR copy");
132 precondition(
static_cast<ptrdiff_t
>(nrows + 1) == std::distance(std::begin(ptr_range), std::end(ptr_range)),
133 "ptr_range has wrong size in crs constructor");
135 m_nb_non_zero = ptr_range[nrows];
137 precondition(
static_cast<ptrdiff_t
>(m_nb_non_zero) == std::distance(std::begin(col_range), std::end(col_range)),
138 "col_range has wrong size in crs constructor");
140 precondition(
static_cast<ptrdiff_t
>(m_nb_non_zero) == std::distance(std::begin(val_range), std::end(val_range)),
141 "val_range has wrong size in crs constructor");
143 ptr.resize(nrows + 1);
144 col.resize(m_nb_non_zero);
145 val.resize(m_nb_non_zero);
147 ptr[0] = ptr_range[0];
149 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
151 ptr[i + 1] = ptr_range[i + 1];
152 for (
auto j = ptr_range[i]; j < ptr_range[i + 1]; ++j) {
153 col[j] = col_range[j];
154 val[j] = val_range[j];
158 ARCCORE_ALINA_TOC(
"CSR copy");
162 template <
class Matrix>
163 CSRMatrix(
const Matrix& A)
164 : m_nb_row(backend::nbRow(A))
165 , ncols(backend::nbColumn(A))
167 ARCCORE_ALINA_TIC(
"CSR copy");
168 ptr.resize(m_nb_row + 1);
172 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
174 for (
auto a = backend::row_begin(A, i); a; ++a)
176 ptr[i + 1] = row_width;
180 m_nb_non_zero = scan_row_sizes();
181 col.resize(m_nb_non_zero);
182 val.resize(m_nb_non_zero);
185 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
186 ptr_type row_head = ptr[i];
187 for (
auto a = backend::row_begin(A, i); a; ++a) {
188 col[row_head] = a.col();
189 val[row_head] = a.value();
195 ARCCORE_ALINA_TOC(
"CSR copy");
198 CSRMatrix(
const CSRMatrix& other)
199 : m_nb_row(other.m_nb_row)
201 , m_nb_non_zero(other.m_nb_non_zero)
203 if (other.ptr && other.col && other.val) {
204 ptr.resize(m_nb_row + 1);
205 col.resize(m_nb_non_zero);
206 val.resize(m_nb_non_zero);
208 ptr[0] = other.ptr[0];
210 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
211 ptr[i + 1] = other.ptr[i + 1];
212 for (ptr_type j = other.ptr[i]; j < other.ptr[i + 1]; ++j) {
213 col[j] = other.col[j];
214 val[j] = other.val[j];
221 CSRMatrix(CSRMatrix&& other) noexcept
222 : m_nb_row(other.m_nb_row)
224 , m_nb_non_zero(other.m_nb_non_zero)
228 , own_data(other.own_data)
232 other.m_nb_non_zero = 0;
238 CSRMatrix& operator=(
const CSRMatrix& other)
242 m_nb_row = other.m_nb_row;
244 m_nb_non_zero = other.m_nb_non_zero;
246 if (other.ptr && other.col && other.val) {
247 ptr =
new ptr_type[m_nb_row + 1];
248 col =
new col_type[m_nb_non_zero];
249 val =
new val_type[m_nb_non_zero];
251 ptr[0] = other.ptr[0];
253 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
254 ptr[i + 1] = other.ptr[i + 1];
255 for (ptr_type j = other.ptr[i]; j < other.ptr[i + 1]; ++j) {
256 col[j] = other.col[j];
257 val[j] = other.val[j];
266 CSRMatrix& operator=(CSRMatrix&& other)
noexcept
268 std::swap(m_nb_row, other.m_nb_row);
269 std::swap(ncols, other.ncols);
270 std::swap(m_nb_non_zero, other.m_nb_non_zero);
271 std::swap(ptr, other.ptr);
272 std::swap(col, other.col);
273 std::swap(val, other.val);
274 std::swap(own_data, other.own_data);
288 void set_size(
size_t n,
size_t m,
bool clean_ptr =
false)
290 precondition(!ptr,
"matrix data has already been allocated!");
295 ptr.resize(m_nb_row + 1);
300 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
307 ptr_type scan_row_sizes()
309 std::partial_sum(ptr.data(), ptr.data() + m_nb_row + 1, ptr.data());
310 return ptr[m_nb_row];
315 set_nonzeros(ptr[m_nb_row]);
318 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
319 ptrdiff_t row_beg = ptr[i];
320 ptrdiff_t row_end = ptr[i + 1];
321 for (ptrdiff_t j = row_beg; j < row_end; ++j) {
323 val[j] = math::zero<val_type>();
329 void set_nonzeros(
size_t n,
bool need_values =
true)
331 precondition(!col && !val,
"matrix data has already been allocated!");
335 col.resize(m_nb_non_zero);
338 val.resize(m_nb_non_zero);
350 row_iterator(
const col_type* col,
const col_type* end,
const val_type* val)
356 operator bool()
const
358 return m_col < m_end;
361 row_iterator& operator++()
373 val_type value()
const
380 const col_type* m_col =
nullptr;
381 const col_type* m_end =
nullptr;
382 const val_type* m_val =
nullptr;
387 ptr_type p = ptr[row];
388 ptr_type e = ptr[row + 1];
395 return sizeof(ptr_type) * (m_nb_row + 1) +
sizeof(col_type) * m_nb_non_zero +
sizeof(val_type) * m_nb_non_zero;