suanPan
SparseMatMPI.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (C) 2017-2024 Theodore Chang
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
31// ReSharper disable CppClangTidyClangDiagnosticMissingFieldInitializers
32#ifndef SPARSEMATMPI_HPP
33#define SPARSEMATMPI_HPP
34
35#if defined(SUANPAN_MPI) && defined(SUANPAN_MKL)
36
37#include <mpi.h>
38
39extern int SUANPAN_NUM_NODES;
40
41template<sp_d T> class SparseMatMPIPARDISO final : public SparseMat<T> {
42 int iparm[64];
43
44protected:
46
47 int direct_solve(Mat<T>&, const Mat<T>&) override;
48
49public:
50 SparseMatMPIPARDISO(const uword in_row, const uword in_col, const uword in_elem = 0)
51 : SparseMat<T>(in_row, in_col, in_elem)
52 , iparm{} {
53 iparm[34] = 1; // zero-based indexing
54 }
55
56 unique_ptr<MetaMat<T>> make_copy() override { return std::make_unique<SparseMatMPIPARDISO>(*this); }
57};
58
59template<sp_d T> int SparseMatMPIPARDISO<T>::direct_solve(Mat<T>& X, const Mat<T>& B) {
60 X.set_size(B.n_rows, B.n_cols);
61
62 csr_form<T, int> csr_mat(this->triplet_mat, SparseBase::ZERO, true);
63
64 const auto n = static_cast<int>(B.n_rows);
65 const auto nrhs = static_cast<int>(B.n_cols);
66 const auto nnz = static_cast<int>(csr_mat.n_elem);
67
68 MPI_Comm worker;
69 MPI_Comm_spawn("solver.pardiso", MPI_ARGV_NULL, SUANPAN_NUM_NODES, MPI_INFO_NULL, 0, MPI_COMM_SELF, &worker, MPI_ERRCODES_IGNORE);
70
71 int config[8];
72
73 config[0] = 11; // mtype
74 config[1] = nrhs; // nrhs
75 config[2] = 1; // maxfct
76 config[3] = 1; // mnum
77 config[4] = 0; // msglvl
78 config[5] = n; // n
79 config[6] = nnz; // nnz
80 config[7] = std::is_same_v<T, double> ? 1 : -1;
81 const auto FLOAT_TYPE = std::is_same_v<T, double> ? MPI_DOUBLE : MPI_FLOAT;
82
83 MPI_Comm remote;
84 MPI_Intercomm_merge(worker, 0, &remote);
85 MPI_Bcast(&config, 8, MPI_INT, 0, remote);
86
87 MPI_Request requests[5];
88 MPI_Isend(&iparm, 64, MPI_INT, 0, 0, worker, &requests[0]);
89 MPI_Isend(csr_mat.row_mem(), n + 1, MPI_INT, 0, 0, worker, &requests[1]);
90 MPI_Isend(csr_mat.col_mem(), nnz, MPI_INT, 0, 0, worker, &requests[2]);
91 MPI_Isend(csr_mat.val_mem(), nnz, FLOAT_TYPE, 0, 0, worker, &requests[3]);
92 MPI_Isend(B.memptr(), static_cast<int>(B.n_elem), FLOAT_TYPE, 0, 0, worker, &requests[4]);
93 MPI_Waitall(5, requests, MPI_STATUSES_IGNORE);
94
95 int error = -1;
96 MPI_Recv(&error, 1, MPI_INT, 0, 0, worker, MPI_STATUS_IGNORE);
97 if(0 == error) {
98 MPI_Recv(X.memptr(), static_cast<int>(B.n_elem), FLOAT_TYPE, 0, 0, worker, MPI_STATUS_IGNORE);
99 return SUANPAN_SUCCESS;
100 }
101
102 return SUANPAN_FAIL;
103}
104
105#endif
106
107#endif
108
virtual unique_ptr< MetaMat > make_copy()=0
A SparseMat class that holds matrices.
Definition: SparseMat.hpp:34
int direct_solve(Mat< T > &X, Mat< T > &&B) override
Definition: SparseMat.hpp:38
Definition: csr_form.hpp:25
int SUANPAN_NUM_NODES
Definition: command.cpp:73
void error(const std::string_view file_name, const int line, const std::string_view format_str, const T &... args)
Definition: suanPan.h:234
constexpr auto SUANPAN_SUCCESS
Definition: suanPan.h:172
constexpr auto SUANPAN_FAIL
Definition: suanPan.h:173