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 
39 extern int SUANPAN_NUM_NODES;
40 
41 template<sp_d T> class SparseMatMPIPARDISO final : public SparseMat<T> {
42  int iparm[64];
43 
44 protected:
46 
47  int direct_solve(Mat<T>&, const Mat<T>&) override;
48 
49 public:
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 
59 template<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:72
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