This program is a standalone application that solves a system of linear equations using the pposvx
solver.
The caller spawns this program as a worker process.
The error code (0 for success) will be sent back to the root process of the caller. If error code is 0, the solution will be sent back as well.
The example caller logic can be seen as follows.
#include <iostream>
#include <mpl/mpl.hpp>
int main(int argc, char** argv) {
if(argc < 2) {
std::cout << "Usage: runner ge|gex|po|gb|db|pb [n]\n";
std::cout << "Example: runner ge 3\n";
return 0;
}
constexpr auto N = 6, NRHS = 1;
std::vector<double> A, B(N * NRHS, 1.);
std::vector<int> config;
const auto type = std::string(argv[1]);
std::string solver;
if("ge" == type) {
solver = "solver.pgesv";
config = {N, NRHS, 1};
A.resize(N * N, 0.);
for(auto I = 0; I < N; ++I) A[I * N + I] = I + 1.;
}
else if("gex" == type) {
solver = "solver.pgesvx";
config = {N, NRHS, 1};
A.resize(N * N, 0.);
for(auto I = 0; I < N; ++I) A[I * N + I] = I + 1.;
}
else if("po" == type) {
solver = "solver.pposv";
config = {N, NRHS, 1};
A.resize(N * N, 0.);
for(auto I = 0; I < N; ++I) A[I * N + I] = I + 1.;
}
else if("gb" == type) {
solver = "solver.pgbsv";
constexpr auto KL = 1, KU = 1;
config = {N, KL, KU, NRHS, 1};
A.resize(N * (KL + KU + 1), 0.);
for(auto I = 0; I < N; ++I) A[KU + I * (KL + KU + 1)] = I + 1.;
}
else if("db" == type) {
solver = "solver.pdbsv";
constexpr auto KL = 1, KU = 1;
config = {N, KL, KU, NRHS, 1};
A.resize(N * (KL + KU + 1), 0.);
for(auto I = 0; I < N; ++I) A[KU + I * (KL + KU + 1)] = I + 1.;
}
else if("pb" == type) {
solver = "solver.ppbsv";
constexpr auto KLU = 1;
config = {N, KLU, NRHS, 1};
A.resize(N * (KLU + 1), 0.);
for(auto I = 0; I < N; ++I) A[I + I * KLU] = I + 1.;
}
else {
std::cout << "Usage: runner ge|po|gb|db|pb [n]\n";
return 0;
}
const auto& comm_world{mpl::environment::comm_world()};
const auto worker = comm_world.spawn(0, argc < 3 ? 1 : std::abs(std::stoi(argv[2])), {solver});
const auto all = mpl::communicator(worker, mpl::communicator::order_low);
all.bcast(0, config.data(), mpl::contiguous_layout<int>(config.size()));
mpl::irequest_pool requests;
requests.push(worker.isend(A, 0, mpl::tag_t{0}));
requests.push(worker.isend(B, 0, mpl::tag_t{1}));
requests.waitall();
int error = -1;
worker.recv(error, 0);
if(0 == error) worker.recv(B, 0);
for(auto I = 0; I < N; ++I) printf("x[%d] = %+.6f\n", I, B[I]);
return 0;
}