svMultiPhysics
Loading...
Searching...
No Matches
CmMod.h
1// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
2// SPDX-License-Identifier: BSD-3-Clause
3
4// The classes defined here duplicate the data structures in the Fortran CMMOD module
5// defined in COMU.f.
6
7#ifndef CMMOD_H
8#define CMMOD_H
9
10#include "Array.h"
11#include "Vector.h"
12
13#include "mpi.h"
14#include "consts.h"
15
16#include <string>
17
18namespace cm_mod {
19
20using MpiCommWorldType = MPI_Comm;
21//using MpiCommWorldType = decltype(MPI_COMM_WORLD);
22
23// Set MPI data type names.
24const decltype(MPI_CXX_BOOL) mplog = MPI_CXX_BOOL;
25//const decltype(MPI_LOGICAL) mplog = MPI_LOGICAL;
26const decltype(MPI_INTEGER) mpint = MPI_INTEGER;
27const decltype(MPI_DOUBLE_PRECISION) mpreal = MPI_DOUBLE_PRECISION;
28const decltype(MPI_CHARACTER) mpchar = MPI_CHARACTER;
29};
30
31/// @brief The CmMod class duplicates the data structures in the Fortran CMMOD module
32/// defined in COMU.f.
33///
34/// The data members here are the global variables exposed by the CMMOD module.
35class CmMod {
36
37 public:
38 CmMod();
39 ~CmMod();
40
41 // Size of blocks for openMP communications.
42 int mpBs = 1000;
43
44 // master is assumed to have zero ID
45 int master = 0;
46
47 // Abstracted MPI names.
48 decltype(MPI_LOGICAL) mplog = MPI_LOGICAL;
49 decltype(MPI_INTEGER) mpint = MPI_INTEGER;
50 decltype(MPI_DOUBLE_PRECISION) mpreal = MPI_DOUBLE_PRECISION;
51 decltype(MPI_CHARACTER) mpchar = MPI_CHARACTER;
52};
53
54/// @brief The cmType class stores data and defines methods used for mpi communication.
55class cmType {
56 public:
57 cmType();
58 ~cmType();
59
60 // Communicator handle.
61 decltype(MPI_COMM_WORLD) cHndl;
62
63 // Processors ID.
64 int taskId = 0;
65
66 // Number of openMP threads in this cm
67 int nThreads = 0;
68
69 // Number of processors
70 int nProcs = 0;
71
72 //----- M e t h o d s -----//
73
74 void bcast(const CmMod& cm_mod, bool* data) const;
75 void bcast(const CmMod& cm_mod, std::vector<bool>& data) const;
76
77 void bcast(const CmMod& cm_mod, std::string& data) const;
78
79 void bcast(const CmMod& cm_mod, double* data) const;
80 void bcast(const CmMod& cm_mod, Vector<double>& data, const std::string& name="") const;
81 void bcast(const CmMod& cm_mod, Array<double>& data, const std::string& name="") const;
82
83 void bcast(const CmMod& cm_mod, int* data) const;
84 void bcast(const CmMod& cm_mod, Vector<int>& data) const;
85
86 void bcast(const CmMod& cm_mod, Array<int>& data, const std::string& name="") const;
87
88 // Gather operations
89 void gather(const CmMod& cm_mod, const int* send_data, int send_count, int* recv_data, int recv_count, int root) const;
90 void gather(const CmMod& cm_mod, const double* send_data, int send_count, double* recv_data, int recv_count, int root) const;
91 void gather(const CmMod& cm_mod, const Vector<int>& send_data, Vector<int>& recv_data, int root) const;
92 void gather(const CmMod& cm_mod, const Vector<double>& send_data, Vector<double>& recv_data, int root) const;
93
94 // Gatherv operations
95 void gatherv(const CmMod& cm_mod, const Vector<int>& send_data, Vector<int>& recv_data, const Vector<int>& recv_counts, const Vector<int>& displs, int root) const;
96 void gatherv(const CmMod& cm_mod, const Vector<double>& send_data, Vector<double>& recv_data, const Vector<int>& recv_counts, const Vector<int>& displs, int root) const;
97
98 // Scatterv operations
99 void scatterv(const CmMod& cm_mod, const Vector<int>& send_data, const Vector<int>& send_counts, const Vector<int>& displs, Vector<int>& recv_data, int root) const;
100 void scatterv(const CmMod& cm_mod, const Vector<double>& send_data, const Vector<int>& send_counts, const Vector<int>& displs, Vector<double>& recv_data, int root) const;
101
102 // Scatter operations
103 void scatter(const CmMod& cm_mod, const int* send_data, int send_count, int* recv_data, int recv_count, int root) const;
104 void scatter(const CmMod& cm_mod, const double* send_data, int send_count, double* recv_data, int recv_count, int root) const;
105 void scatter(const CmMod& cm_mod, const Vector<int>& send_data, Vector<int>& recv_data, int root) const;
106 void scatter(const CmMod& cm_mod, const Vector<double>& send_data, Vector<double>& recv_data, int root) const;
107
108 //------------
109 // bcast_enum
110 //------------
111 //
112 template <typename T>
113 void bcast_enum(const CmMod& cm_mod, T* data) const
114 {
115 int idata = static_cast<int>(*data);
116 //std::cout << "[bcast_enum] idata in: " << idata << std::endl;
117 MPI_Bcast(&idata, 1, cm_mod::mpint, cm_mod.master, com());
118 //std::cout << "[bcast_enum] idata out: " << idata << std::endl;
119 *data = static_cast<T>(idata);
120 }
121
122 //------------
123 // bcast_prop
124 //------------
125 //
126 template <typename T>
127 void bcast_prop(const CmMod& cm_mod, std::map<T,double>& props) const
128 {
129 static const int MAX_SIZE = 100;
130
131 if (2*props.size() > MAX_SIZE) {
132 throw std::runtime_error("bcast prop is larger than " + std::to_string(MAX_SIZE) + ".");
133 }
134
135 double prop_array[MAX_SIZE];
136 std::fill_n(prop_array, MAX_SIZE, -1.0);
137
138 int n = 0;
139 for (auto& entry : props) {
140 prop_array[n++] = static_cast<int>(entry.first);
141 prop_array[n++] = entry.second;
142 }
143
144 MPI_Bcast(prop_array, MAX_SIZE, cm_mod::mpreal, cm_mod.master, com());
145
146 props.clear();
147 int num_props = MAX_SIZE / 2;;
148
149 for (int i = 0; i < num_props; i++) {
150 int iprop = static_cast<int>(prop_array[2*i]);
151 if (iprop == -1) {
152 break;
153 }
154 auto prop = static_cast<T>(iprop);
155 props[prop] = prop_array[2*i+1];
156 }
157 }
158
159 // Returns commu handle
160 cm_mod::MpiCommWorldType com() const;
161 //decltype(MPI_COMM_WORLD) com() const;
162
163 int idcm() const { return taskId; };
164 int id() { return taskId; };
165 bool mas(const CmMod& cm_mod) const { return (taskId == cm_mod.master); };
166
167 // Create a new Communicator
168 void new_cm(decltype(MPI_COMM_WORLD) comHandle);
169
170 int np() const { return nProcs; };
171
172 int nT() { return nThreads; };
173
174
175 //--------
176 // reduce
177 //--------
178 // For an int or double scalar.
179 //
180 template<typename T>
181 T reduce(const CmMod& cm_mod, T u, MPI_Op op = MPI_SUM) const
182 {
183 T gU{};
184
185 MPI_Datatype data_type;
186 if (typeid(T) == typeid(double)) {
187 data_type = MPI_DOUBLE_PRECISION;
188 } else if (typeid(T) == typeid(int)) {
189 data_type = MPI_INTEGER;
190 } else {
191 throw std::runtime_error("[cm_mod::reduce called with unknown data type.");
192 }
193
194 if (seq()) {
195 gU = u;
196 } else {
197 MPI_Allreduce(&u, &gU, 1, data_type, op, com());
198 }
199
200 return gU;
201 }
202
203 //--------
204 // reduce
205 //--------
206 // For an int or double Vector.
207 //
208 template<typename T>
209 Vector<T> reduce(const CmMod& cm_mod, Vector<T>& u, MPI_Op op = MPI_SUM) const
210 {
211 int size = u.size();
212 Vector<T> gU(size);
213
214 MPI_Datatype data_type;
215 if (typeid(T) == typeid(double)) {
216 data_type = MPI_DOUBLE_PRECISION;
217 } if (typeid(T) == typeid(int)) {
218 data_type = MPI_INTEGER;
219 }
220
221 if (seq()) {
222 gU = u;
223 } else {
224 MPI_Allreduce(u.data(), gU.data(), size, data_type, op, com());
225 }
226
227 return gU;
228 }
229
230 bool seq() const { return (nProcs == 1); };
231
232 bool slv(const CmMod& cm_mod) const { return (taskId != cm_mod.master); };
233
234 // Returns processor ID in fortran indexing
235 int tF(const CmMod& cm_mod) const { return taskId + 1; };
236
237};
238
239
240#endif
241
The CmMod class duplicates the data structures in the Fortran CMMOD module defined in COMU....
Definition CmMod.h:35
The Vector template class is used for storing int and double data.
Definition Vector.h:23
The cmType class stores data and defines methods used for mpi communication.
Definition CmMod.h:55
void gatherv(const CmMod &cm_mod, const Vector< int > &send_data, Vector< int > &recv_data, const Vector< int > &recv_counts, const Vector< int > &displs, int root) const
gatherv int Vector
Definition CmMod.cpp:194
void scatterv(const CmMod &cm_mod, const Vector< int > &send_data, const Vector< int > &send_counts, const Vector< int > &displs, Vector< int > &recv_data, int root) const
scatterv int Vector
Definition CmMod.cpp:208
void bcast(const CmMod &cm_mod, bool *data) const
bcast bool.
Definition CmMod.cpp:53
void gather(const CmMod &cm_mod, const int *send_data, int send_count, int *recv_data, int recv_count, int root) const
gather int array
Definition CmMod.cpp:142
cm_mod::MpiCommWorldType com() const
Returns commu handle.
Definition CmMod.cpp:32
void scatter(const CmMod &cm_mod, const int *send_data, int send_count, int *recv_data, int recv_count, int root) const
scatter int array
Definition CmMod.cpp:168