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 void bcast(const CmMod& cm_mod, Array<int>& data, const std::string& name="") const;
114
115 //------------
116 // bcast_enum
117 //------------
118 //
119 template <typename T>
120 void bcast_enum(const CmMod& cm_mod, T* data) const
121 {
122 int idata = static_cast<int>(*data);
123 //std::cout << "[bcast_enum] idata in: " << idata << std::endl;
124 MPI_Bcast(&idata, 1, cm_mod::mpint, cm_mod.master, com());
125 //std::cout << "[bcast_enum] idata out: " << idata << std::endl;
126 *data = static_cast<T>(idata);
127 }
128
129 //------------
130 // bcast_prop
131 //------------
132 //
133 template <typename T>
134 void bcast_prop(const CmMod& cm_mod, std::map<T,double>& props) const
135 {
136 static const int MAX_SIZE = 100;
137
138 if (2*props.size() > MAX_SIZE) {
139 throw std::runtime_error("bcast prop is larger than " + std::to_string(MAX_SIZE) + ".");
140 }
141
142 double prop_array[MAX_SIZE];
143 std::fill_n(prop_array, MAX_SIZE, -1.0);
144
145 int n = 0;
146 for (auto& entry : props) {
147 prop_array[n++] = static_cast<int>(entry.first);
148 prop_array[n++] = entry.second;
149 }
150
151 MPI_Bcast(prop_array, MAX_SIZE, cm_mod::mpreal, cm_mod.master, com());
152
153 props.clear();
154 int num_props = MAX_SIZE / 2;;
155
156 for (int i = 0; i < num_props; i++) {
157 int iprop = static_cast<int>(prop_array[2*i]);
158 if (iprop == -1) {
159 break;
160 }
161 auto prop = static_cast<T>(iprop);
162 props[prop] = prop_array[2*i+1];
163 }
164 }
165
166 // Returns commu handle
167 cm_mod::MpiCommWorldType com() const;
168 //decltype(MPI_COMM_WORLD) com() const;
169
170 int idcm() const { return taskId; };
171 int id() { return taskId; };
172 bool mas(const CmMod& cm_mod) const { return (taskId == cm_mod.master); };
173
174 // Create a new Communicator
175 void new_cm(decltype(MPI_COMM_WORLD) comHandle);
176
177 int np() const { return nProcs; };
178
179 int nT() { return nThreads; };
180
181
182 //--------
183 // reduce
184 //--------
185 // For an int or double scalar.
186 //
187 template<typename T>
188 T reduce(const CmMod& cm_mod, T u, MPI_Op op = MPI_SUM) const
189 {
190 T gU{};
191
192 MPI_Datatype data_type;
193 if (typeid(T) == typeid(double)) {
194 data_type = MPI_DOUBLE_PRECISION;
195 } else if (typeid(T) == typeid(int)) {
196 data_type = MPI_INTEGER;
197 } else {
198 throw std::runtime_error("[cm_mod::reduce called with unknown data type.");
199 }
200
201 if (seq()) {
202 gU = u;
203 } else {
204 MPI_Allreduce(&u, &gU, 1, data_type, op, com());
205 }
206
207 return gU;
208 }
209
210 //--------
211 // reduce
212 //--------
213 // For an int or double Vector.
214 //
215 template<typename T>
216 Vector<T> reduce(const CmMod& cm_mod, Vector<T>& u, MPI_Op op = MPI_SUM) const
217 {
218 int size = u.size();
219 Vector<T> gU(size);
220
221 MPI_Datatype data_type;
222 if (typeid(T) == typeid(double)) {
223 data_type = MPI_DOUBLE_PRECISION;
224 } if (typeid(T) == typeid(int)) {
225 data_type = MPI_INTEGER;
226 }
227
228 if (seq()) {
229 gU = u;
230 } else {
231 MPI_Allreduce(u.data(), gU.data(), size, data_type, op, com());
232 }
233
234 return gU;
235 }
236
237 bool seq() const { return (nProcs == 1); };
238
239 bool slv(const CmMod& cm_mod) const { return (taskId != cm_mod.master); };
240
241 // Returns processor ID in fortran indexing
242 int tF(const CmMod& cm_mod) const { return taskId + 1; };
243
244};
245
246
247#endif
248
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