12#ifndef ARCCORE_ALINA_MATRIXPARTITIONUTILS_H
13#define ARCCORE_ALINA_MATRIXPARTITIONUTILS_H
32#include "arccore/alina/BackendInterface.h"
33#include "arccore/alina/DistributedMatrix.h"
38namespace Arcane::Alina
44template <
class Backend,
class Ptr,
class Col>
void
46 std::vector<Ptr>& ptr, std::vector<Col>& col)
48 using build_matrix = Backend::matrix;
50 ARCCORE_ALINA_TIC(
"symm graph");
52 build_matrix& A_loc = *A.local();
53 build_matrix& A_rem = *A.remote();
55 ptrdiff_t n = A_loc.nbRow();
56 ptrdiff_t row_beg = A.loc_col_shift();
58 auto T = transpose(A);
60 build_matrix& T_loc = *T->local();
61 build_matrix& T_rem = *T->remote();
67 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
68 using Alina::detail::sort_row;
70 ptrdiff_t A_loc_beg = A_loc.ptr[i];
71 ptrdiff_t A_loc_end = A_loc.ptr[i + 1];
73 ptrdiff_t A_rem_beg = A_rem.ptr[i];
74 ptrdiff_t A_rem_end = A_rem.ptr[i + 1];
76 ptrdiff_t T_loc_beg = T_loc.ptr[i];
77 ptrdiff_t T_loc_end = T_loc.ptr[i + 1];
79 ptrdiff_t T_rem_beg = T_rem.ptr[i];
80 ptrdiff_t T_rem_end = T_rem.ptr[i + 1];
82 sort_row(A_loc.col + A_loc_beg, A_loc.val + A_loc_beg, A_loc_end - A_loc_beg);
83 sort_row(A_rem.col + A_rem_beg, A_rem.val + A_rem_beg, A_rem_end - A_rem_beg);
85 sort_row(T_loc.col + T_loc_beg, T_loc.val + T_loc_beg, T_loc_end - T_loc_beg);
86 sort_row(T_rem.col + T_rem_beg, T_rem.val + T_rem_beg, T_rem_end - T_rem_beg);
90 for (ptrdiff_t ja = A_loc_beg, jt = T_loc_beg; ja < A_loc_end || jt < T_loc_end;) {
92 if (ja == A_loc_end) {
96 else if (jt == T_loc_end) {
101 ptrdiff_t ca = A_loc.col[ja];
102 ptrdiff_t ct = T_loc.col[jt];
122 for (ptrdiff_t ja = A_rem_beg, jt = T_rem_beg; ja < A_rem_end || jt < T_rem_end;) {
123 if (ja == A_rem_end) {
126 else if (jt == T_rem_end) {
130 ptrdiff_t ca = A_rem.col[ja];
131 ptrdiff_t ct = T_rem.col[jt];
147 ptr[i + 1] = row_width;
151 std::partial_sum(ptr.begin(), ptr.end(), ptr.begin());
153 col.resize(ptr.back());
158 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
159 ptrdiff_t A_loc_beg = A_loc.ptr[i];
160 ptrdiff_t A_loc_end = A_loc.ptr[i + 1];
162 ptrdiff_t A_rem_beg = A_rem.ptr[i];
163 ptrdiff_t A_rem_end = A_rem.ptr[i + 1];
165 ptrdiff_t T_loc_beg = T_loc.ptr[i];
166 ptrdiff_t T_loc_end = T_loc.ptr[i + 1];
168 ptrdiff_t T_rem_beg = T_rem.ptr[i];
169 ptrdiff_t T_rem_end = T_rem.ptr[i + 1];
173 for (ptrdiff_t ja = A_loc_beg, jt = T_loc_beg; ja < A_loc_end || jt < T_loc_end;) {
175 if (ja == A_loc_end) {
179 else if (jt == T_loc_end) {
184 ptrdiff_t ca = A_loc.col[ja];
185 ptrdiff_t ct = T_loc.col[jt];
202 col[head++] = c + row_beg;
205 for (ptrdiff_t ja = A_rem_beg, jt = T_rem_beg; ja < A_rem_end || jt < T_rem_end;) {
206 if (ja == A_rem_end) {
207 col[head] = T_rem.col[jt];
210 else if (jt == T_rem_end) {
211 col[head] = A_rem.col[ja];
215 ptrdiff_t ca = A_rem.col[ja];
216 ptrdiff_t ct = T_rem.col[jt];
237 ARCCORE_ALINA_TOC(
"symm graph");
243template <
class Idx> std::tuple<ptrdiff_t, ptrdiff_t>
244mpi_graph_perm_index(
mpi_communicator comm,
int npart,
const std::vector<Idx>& part,
245 std::vector<ptrdiff_t>& perm)
247 ARCCORE_ALINA_TIC(
"perm index");
248 ptrdiff_t n = part.size();
251 std::vector<ptrdiff_t> loc_part_cnt(npart, 0);
252 std::vector<ptrdiff_t> loc_part_beg(npart, 0);
253 std::vector<ptrdiff_t> glo_part_cnt(npart);
254 std::vector<ptrdiff_t> glo_part_beg(npart + 1);
259 MPI_Exscan(&loc_part_cnt[0], &loc_part_beg[0], npart, mpi_datatype<ptrdiff_t>(), MPI_SUM, comm);
260 MPI_Allreduce(&loc_part_cnt[0], &glo_part_cnt[0], npart, mpi_datatype<ptrdiff_t>(), MPI_SUM, comm);
263 std::partial_sum(glo_part_cnt.begin(), glo_part_cnt.end(), glo_part_beg.begin() + 1);
265 std::vector<ptrdiff_t> cnt(npart, 0);
266 for (ptrdiff_t i = 0; i < n; ++i) {
268 perm[i] = glo_part_beg[p] + loc_part_beg[p] + cnt[p]++;
271 ARCCORE_ALINA_TOC(
"perm index");
272 return std::make_tuple(
273 glo_part_beg[std::min(npart, comm.rank)],
274 glo_part_beg[std::min(npart, comm.rank + 1)]);
280template <
class Backend,
class Idx>
281std::shared_ptr<DistributedMatrix<Backend>>
282mpi_graph_perm_matrix(
mpi_communicator comm, ptrdiff_t col_beg, ptrdiff_t col_end,
283 const std::vector<Idx>& perm)
285 typedef typename Backend::value_type value_type;
286 using build_matrix = Backend::matrix;
288 ARCCORE_ALINA_TIC(
"perm matrix");
290 ptrdiff_t n = perm.size();
291 ptrdiff_t ncols = col_end - col_beg;
293 auto i_loc = std::make_shared<build_matrix>();
294 auto i_rem = std::make_shared<build_matrix>();
296 build_matrix& I_loc = *i_loc;
297 build_matrix& I_rem = *i_rem;
299 I_loc.set_size(n, ncols,
false);
300 I_rem.set_size(n, 0,
false);
306 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
307 ptrdiff_t j = perm[i];
309 if (col_beg <= j && j < col_end) {
310 I_loc.ptr[i + 1] = 1;
311 I_rem.ptr[i + 1] = 0;
314 I_loc.ptr[i + 1] = 0;
315 I_rem.ptr[i + 1] = 1;
320 I_loc.set_nonzeros(I_loc.scan_row_sizes());
321 I_rem.set_nonzeros(I_rem.scan_row_sizes());
324 for (ptrdiff_t i = begin; i < (begin + size); ++i) {
325 ptrdiff_t j = perm[i];
327 if (col_beg <= j && j < col_end) {
328 ptrdiff_t k = I_loc.ptr[i];
329 I_loc.col[k] = j - col_beg;
330 I_loc.val[k] = math::identity<value_type>();
333 ptrdiff_t k = I_rem.ptr[i];
335 I_rem.val[k] = math::identity<value_type>();
340 ARCCORE_ALINA_TOC(
"perm matrix");
341 return std::make_shared<DistributedMatrix<Backend>>(comm, i_loc, i_rem);
Distributed Matrix using message passing.
void arccoreParallelFor(const ComplexForLoopRanges< RankValue > &loop_ranges, const ForLoopRunInfo &run_info, const LambdaType &lambda_function, const ReducerArgs &... reducer_args)
Applique en concurrence la fonction lambda lambda_function sur l'intervalle d'itération donné par loo...
std::int32_t Int32
Type entier signé sur 32 bits.
Convenience wrapper around MPI_Comm.