25#include <boost/scope_exit.hpp>
27#include "arccore/alina/MessagePassingUtils.h"
28#include "arccore/alina/AlinaLib.h"
29#include "AlinaSamplesCommon.h"
30#include "arccore/trace/ITraceMng.h"
32#include "DomainPartition.h"
34double constant_deflation(
int, ptrdiff_t,
void*)
46 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
47 MPI_Comm_size(MPI_COMM_WORLD, &size);
50 tm->
info() <<
"World size: " << size;
52 const ptrdiff_t n = argc > 1 ? atoi(argv[1]) : 1024;
53 const ptrdiff_t n2 = n * n;
56 boost::array<ptrdiff_t, 2> lo = { { 0, 0 } };
57 boost::array<ptrdiff_t, 2> hi = { { n - 1, n - 1 } };
59 DomainPartition<2> part(lo, hi, size);
60 ptrdiff_t chunk = part.size(rank);
62 std::vector<ptrdiff_t> domain(size + 1);
63 MPI_Allgather(&chunk, 1, Alina::mpi_datatype<ptrdiff_t>(), &domain[1], 1, Alina::mpi_datatype<ptrdiff_t>(), MPI_COMM_WORLD);
64 std::partial_sum(domain.begin(), domain.end(), domain.begin());
66 ptrdiff_t chunk_start = domain[rank];
67 ptrdiff_t chunk_end = domain[rank + 1];
69 std::vector<ptrdiff_t> renum(n2);
70 for (ptrdiff_t j = 0, idx = 0; j < n; ++j) {
71 for (ptrdiff_t i = 0; i < n; ++i, ++idx) {
72 boost::array<ptrdiff_t, 2> p = { { i, j } };
73 std::pair<int, ptrdiff_t> v = part.index(p);
74 renum[idx] = domain[v.first] + v.second;
79 std::vector<ptrdiff_t> ptr;
80 std::vector<ptrdiff_t> col;
81 std::vector<double> val;
82 std::vector<double> rhs;
84 ptr.reserve(chunk + 1);
85 col.reserve(chunk * 5);
86 val.reserve(chunk * 5);
91 const double hinv = (n - 1);
92 const double h2i = (n - 1) * (n - 1);
93 for (ptrdiff_t j = 0, idx = 0; j < n; ++j) {
94 for (ptrdiff_t i = 0; i < n; ++i, ++idx) {
95 if (renum[idx] < chunk_start || renum[idx] >= chunk_end)
99 col.push_back(renum[idx - n]);
104 col.push_back(renum[idx - 1]);
105 val.push_back(-h2i - hinv);
108 col.push_back(renum[idx]);
109 val.push_back(4 * h2i + hinv);
112 col.push_back(renum[idx + 1]);
117 col.push_back(renum[idx + n]);
122 ptr.push_back(col.size());
129 AlinaLib::params_set_string(prm,
"local.coarsening.type",
"smoothed_aggregation");
130 AlinaLib::params_set_string(prm,
"local.relax.type",
"spai0");
131 AlinaLib::params_set_string(prm,
"isolver.type",
"bicgstabl");
132 AlinaLib::params_set_string(prm,
"dsolver.type",
"skyline_lu");
135 chunk, ptr.data(), col.data(), val.data(),
136 1, constant_deflation, NULL, prm);
139 std::vector<double> x(chunk, 0);
142 std::cout <<
"Iterations: " << cnv.iterations << std::endl
143 <<
"Error: " << cnv.residual << std::endl;
146 AlinaLib::solver_mpi_destroy(solver);
147 AlinaLib::params_destroy(prm);
151 std::vector<double> X(n2);
152 std::copy(x.begin(), x.end(), X.begin());
154 for (
int i = 1; i < size; ++i)
155 MPI_Recv(&X[domain[i]], domain[i + 1] - domain[i], MPI_DOUBLE, i, 42, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
157 std::ofstream f(
"out.dat", std::ios::binary);
159 f.write((
char*)&m,
sizeof(
int));
160 for (ptrdiff_t i = 0; i < n2; ++i)
161 f.write((
char*)&X[renum[i]],
sizeof(
double));
164 MPI_Send(x.data(), chunk, MPI_DOUBLE, 0, 42, MPI_COMM_WORLD);
170int main(
int argc,
char* argv[])
172 return Arcane::Alina::SampleMainContext::execMain(main2, argc, argv);
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-