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