svMultiPhysics
Loading...
Searching...
No Matches
CmMod.h
1/* Copyright (c) Stanford University, The Regents of the University of California, and others.
2 *
3 * All Rights Reserved.
4 *
5 * See Copyright-SimVascular.txt for additional details.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject
13 * to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31// The classes defined here duplicate the data structures in the Fortran CMMOD module
32// defined in COMU.f.
33
34#ifndef CMMOD_H
35#define CMMOD_H
36
37#include "Array.h"
38#include "Vector.h"
39
40#include "mpi.h"
41#include "consts.h"
42
43#include <string>
44
45namespace cm_mod {
46
47using MpiCommWorldType = MPI_Comm;
48//using MpiCommWorldType = decltype(MPI_COMM_WORLD);
49
50// Set MPI data type names.
51const decltype(MPI_CXX_BOOL) mplog = MPI_CXX_BOOL;
52//const decltype(MPI_LOGICAL) mplog = MPI_LOGICAL;
53const decltype(MPI_INTEGER) mpint = MPI_INTEGER;
54const decltype(MPI_DOUBLE_PRECISION) mpreal = MPI_DOUBLE_PRECISION;
55const decltype(MPI_CHARACTER) mpchar = MPI_CHARACTER;
56};
57
58/// @brief The CmMod class duplicates the data structures in the Fortran CMMOD module
59/// defined in COMU.f.
60///
61/// The data members here are the global variables exposed by the CMMOD module.
62class CmMod {
63
64 public:
65 CmMod();
66 ~CmMod();
67
68 // Size of blocks for openMP communications.
69 int mpBs = 1000;
70
71 // master is assumed to have zero ID
72 int master = 0;
73
74 // Abstracted MPI names.
75 decltype(MPI_LOGICAL) mplog = MPI_LOGICAL;
76 decltype(MPI_INTEGER) mpint = MPI_INTEGER;
77 decltype(MPI_DOUBLE_PRECISION) mpreal = MPI_DOUBLE_PRECISION;
78 decltype(MPI_CHARACTER) mpchar = MPI_CHARACTER;
79};
80
81/// @brief The cmType class stores data and defines methods used for mpi communication.
82class cmType {
83 public:
84 cmType();
85 ~cmType();
86
87 // Communicator handle.
88 decltype(MPI_COMM_WORLD) cHndl;
89
90 // Processors ID.
91 int taskId = 0;
92
93 // Number of openMP threads in this cm
94 int nThreads = 0;
95
96 // Number of processors
97 int nProcs = 0;
98
99 //----- M e t h o d s -----//
100
101 void bcast(const CmMod& cm_mod, bool* data) const;
102 void bcast(const CmMod& cm_mod, std::vector<bool>& data) const;
103
104 void bcast(const CmMod& cm_mod, std::string& data) const;
105
106 void bcast(const CmMod& cm_mod, double* data) const;
107 void bcast(const CmMod& cm_mod, Vector<double>& data, const std::string& name="") const;
108 void bcast(const CmMod& cm_mod, Array<double>& data, const std::string& name="") const;
109
110 void bcast(const CmMod& cm_mod, int* data) const;
111 void bcast(const CmMod& cm_mod, Vector<int>& data) const;
112
113 //------------
114 // bcast_enum
115 //------------
116 //
117 template <typename T>
118 void bcast_enum(const CmMod& cm_mod, T* data) const
119 {
120 int idata = static_cast<int>(*data);
121 //std::cout << "[bcast_enum] idata in: " << idata << std::endl;
122 MPI_Bcast(&idata, 1, cm_mod::mpint, cm_mod.master, com());
123 //std::cout << "[bcast_enum] idata out: " << idata << std::endl;
124 *data = static_cast<T>(idata);
125 }
126
127 //------------
128 // bcast_prop
129 //------------
130 //
131 template <typename T>
132 void bcast_prop(const CmMod& cm_mod, std::map<T,double>& props) const
133 {
134 static const int MAX_SIZE = 100;
135
136 if (2*props.size() > MAX_SIZE) {
137 throw std::runtime_error("bcast prop is larger than " + std::to_string(MAX_SIZE) + ".");
138 }
139
140 double prop_array[MAX_SIZE];
141 std::fill_n(prop_array, MAX_SIZE, -1.0);
142
143 int n = 0;
144 for (auto& entry : props) {
145 prop_array[n++] = static_cast<int>(entry.first);
146 prop_array[n++] = entry.second;
147 }
148
149 MPI_Bcast(prop_array, MAX_SIZE, cm_mod::mpreal, cm_mod.master, com());
150
151 props.clear();
152 int num_props = MAX_SIZE / 2;;
153
154 for (int i = 0; i < num_props; i++) {
155 int iprop = static_cast<int>(prop_array[2*i]);
156 if (iprop == -1) {
157 break;
158 }
159 auto prop = static_cast<T>(iprop);
160 props[prop] = prop_array[2*i+1];
161 }
162 }
163
164 // Returns commu handle
165 cm_mod::MpiCommWorldType com() const;
166 //decltype(MPI_COMM_WORLD) com() const;
167
168 int idcm() const { return taskId; };
169 int id() { return taskId; };
170 bool mas(const CmMod& cm_mod) const { return (taskId == cm_mod.master); };
171
172 // Create a new Communicator
173 void new_cm(decltype(MPI_COMM_WORLD) comHandle);
174
175 int np() const { return nProcs; };
176
177 int nT() { return nThreads; };
178
179
180 //--------
181 // reduce
182 //--------
183 // For an int or double scalar.
184 //
185 template<typename T>
186 T reduce(const CmMod& cm_mod, T u, MPI_Op op = MPI_SUM) const
187 {
188 T gU{};
189
190 MPI_Datatype data_type;
191 if (typeid(T) == typeid(double)) {
192 data_type = MPI_DOUBLE_PRECISION;
193 } else if (typeid(T) == typeid(int)) {
194 data_type = MPI_INTEGER;
195 } else {
196 throw std::runtime_error("[cm_mod::reduce called with unknown data type.");
197 }
198
199 if (seq()) {
200 gU = u;
201 } else {
202 MPI_Allreduce(&u, &gU, 1, data_type, op, com());
203 }
204
205 return gU;
206 }
207
208 //--------
209 // reduce
210 //--------
211 // For an int or double Vector.
212 //
213 template<typename T>
214 Vector<T> reduce(const CmMod& cm_mod, Vector<T>& u, MPI_Op op = MPI_SUM) const
215 {
216 int size = u.size();
217 Vector<T> gU(size);
218
219 MPI_Datatype data_type;
220 if (typeid(T) == typeid(double)) {
221 data_type = MPI_DOUBLE_PRECISION;
222 } if (typeid(T) == typeid(int)) {
223 data_type = MPI_INTEGER;
224 }
225
226 if (seq()) {
227 gU = u;
228 } else {
229 MPI_Allreduce(u.data(), gU.data(), size, data_type, op, com());
230 }
231
232 return gU;
233 }
234
235 bool seq() const { return (nProcs == 1); };
236
237 bool slv(const CmMod& cm_mod) const { return (taskId != cm_mod.master); };
238
239 // Returns processor ID in fortran indexing
240 int tF(const CmMod& cm_mod) const { return taskId + 1; };
241
242};
243
244
245#endif
246
The CmMod class duplicates the data structures in the Fortran CMMOD module defined in COMU....
Definition CmMod.h:62
The Vector template class is used for storing int and double data.
Definition Vector.h:50
The cmType class stores data and defines methods used for mpi communication.
Definition CmMod.h:82
void bcast(const CmMod &cm_mod, bool *data) const
bcast bool.
Definition CmMod.cpp:80
cm_mod::MpiCommWorldType com() const
Returns commu handle.
Definition CmMod.cpp:59