Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
DistributedSPMMScaling.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/*---------------------------------------------------------------------------*/
9/*
10 * This file is based on the work on AMGCL library (version march 2026)
11 * which can be found at https://github.com/ddemidov/amgcl.
12 *
13 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
14 * SPDX-License-Identifier: MIT
15 */
16/*---------------------------------------------------------------------------*/
17/*---------------------------------------------------------------------------*/
18
19#include <iostream>
20#include <vector>
21
22#include <boost/scope_exit.hpp>
23#include <boost/program_options.hpp>
24
25#include "arccore/alina/BuiltinBackend.h"
26#include "arccore/alina/Adapters.h"
27#include "arccore/alina/DistributedMatrix.h"
28#include "arccore/alina/Profiler.h"
29
30#include "DomainPartition.h"
31
32using namespace Arcane;
33
34struct renumbering
35{
36 const DomainPartition<3>& part;
37 const std::vector<ptrdiff_t>& dom;
38
39 renumbering(const DomainPartition<3>& p,
40 const std::vector<ptrdiff_t>& d)
41 : part(p)
42 , dom(d)
43 {}
44
45 ptrdiff_t operator()(ptrdiff_t i, ptrdiff_t j, ptrdiff_t k) const
46 {
47 boost::array<ptrdiff_t, 3> p = { { i, j, k } };
48 std::pair<int, ptrdiff_t> v = part.index(p);
49 return dom[v.first] + v.second;
50 }
51};
52
53int main(int argc, char* argv[])
54{
55 auto& prof = Alina::Profiler::globalProfiler();
56 MPI_Init(&argc, &argv);
57 BOOST_SCOPE_EXIT(void)
58 {
59 MPI_Finalize();
60 }
61 BOOST_SCOPE_EXIT_END
62
63 Alina::mpi_communicator world(MPI_COMM_WORLD);
64
65 if (world.rank == 0)
66 std::cout << "World size: " << world.size << std::endl;
67
68 // Read configuration from command line
69 ptrdiff_t n = 128;
70
71 namespace po = boost::program_options;
72 po::options_description desc("Options");
73
74 desc.add_options()("help,h", "show help")(
75 "size,n",
76 po::value<ptrdiff_t>(&n)->default_value(n),
77 "domain size");
78
79 po::variables_map vm;
80 po::store(po::parse_command_line(argc, argv, desc), vm);
81 po::notify(vm);
82
83 if (vm.count("help")) {
84 std::cout << desc << std::endl;
85 return 0;
86 }
87
88 boost::array<ptrdiff_t, 3> lo = { { 0, 0, 0 } };
89 boost::array<ptrdiff_t, 3> hi = { { n - 1, n - 1, n - 1 } };
90
91 prof.tic("partition");
92 DomainPartition<3> part(lo, hi, world.size);
93 ptrdiff_t chunk = part.size(world.rank);
94
95 std::vector<ptrdiff_t> domain = world.exclusive_sum(chunk);
96
97 lo = part.domain(world.rank).min_corner();
98 hi = part.domain(world.rank).max_corner();
99
100 renumbering renum(part, domain);
101 prof.toc("partition");
102
103 prof.tic("assemble");
104 std::vector<ptrdiff_t> ptr;
105 std::vector<ptrdiff_t> col;
106 std::vector<double> val;
107 std::vector<double> rhs;
108
109 ptr.reserve(chunk + 1);
110 col.reserve(chunk * 7);
111 val.reserve(chunk * 7);
112
113 ptr.push_back(0);
114
115 const double h2i = (n - 1) * (n - 1);
116
117 for (ptrdiff_t k = lo[2]; k <= hi[2]; ++k) {
118 for (ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
119 for (ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
120 if (k > 0) {
121 col.push_back(renum(i, j, k - 1));
122 val.push_back(-h2i);
123 }
124
125 if (j > 0) {
126 col.push_back(renum(i, j - 1, k));
127 val.push_back(-h2i);
128 }
129
130 if (i > 0) {
131 col.push_back(renum(i - 1, j, k));
132 val.push_back(-h2i);
133 }
134
135 col.push_back(renum(i, j, k));
136 val.push_back(6 * h2i);
137
138 if (i + 1 < n) {
139 col.push_back(renum(i + 1, j, k));
140 val.push_back(-h2i);
141 }
142
143 if (j + 1 < n) {
144 col.push_back(renum(i, j + 1, k));
145 val.push_back(-h2i);
146 }
147
148 if (k + 1 < n) {
149 col.push_back(renum(i, j, k + 1));
150 val.push_back(-h2i);
151 }
152
153 ptr.push_back(col.size());
154 }
155 }
156 }
157 prof.toc("assemble");
158
159 typedef Alina::BuiltinBackend<double> Backend;
161
162 prof.tic("create distributed version");
163 Matrix A(world, std::tie(chunk, ptr, col, val), chunk);
164 prof.toc("create distributed version");
165
166 prof.tic("distributed product");
167 auto B = product(A, A);
168 prof.toc("distributed product");
169
170 if (world.rank == 0) {
171 if (world.size == 1) {
172 typedef Alina::CSRMatrix<double> matrix;
173 matrix A(std::tie(chunk, ptr, col, val));
174 prof.tic("openmp product");
175 auto B = product(A, A);
176 prof.toc("openmp product");
177 }
178
179 std::cout << prof << std::endl;
180 }
181}
Distributed Matrix using message passing.
Matrix class, to be used by user.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Sparse matrix stored in CSR (Compressed Sparse Row) format.
Definition CSRMatrix.h:98
Convenience wrapper around MPI_Comm.