FasTensor  1.0.0
Transform Supercomputing for AI
ft_mpi.h
Go to the documentation of this file.
1 /*
2 ****************************
3 
4 FasTensor (FT) Copyright (c) 2021, The Regents of the University of
5 California, through Lawrence Berkeley National Laboratory (subject to
6 receipt of any required approvals from the U.S. Dept. of Energy).
7 All rights reserved.
8 
9 If you have questions about your rights to use or distribute this software,
10 please contact Berkeley Lab's Intellectual Property Office at
12 
13 NOTICE. This Software was developed under funding from the U.S. Department
14 of Energy and the U.S. Government consequently retains certain rights. As
15 such, the U.S. Government has been granted for itself and others acting on
16 its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
17 Software to reproduce, distribute copies to the public, prepare derivative
18 works, and perform publicly and display publicly, and to permit others to do so.
19 
20 
21 ****************************
22 
23 
24 *** License Agreement ***
25 
26 FasTensor (FT) Copyright (c) 2021, The Regents of the University of
27 California, through Lawrence Berkeley National Laboratory (subject to
28 receipt of any required approvals from the U.S. Dept. of Energy).
29 All rights reserved.
30 
31 Redistribution and use in source and binary forms, with or without
32 modification, are permitted provided that the following conditions are met:
33 
34 (1) Redistributions of source code must retain the above copyright notice,
35 this list of conditions and the following disclaimer.
36 
37 (2) Redistributions in binary form must reproduce the above copyright
38 notice, this list of conditions and the following disclaimer in the
39 documentation and/or other materials provided with the distribution.
40 
41 (3) Neither the name of the University of California, Lawrence Berkeley
42 National Laboratory, U.S. Dept. of Energy nor the names of its contributors
43 may be used to endorse or promote products derived from this software
44 without specific prior written permission.
45 
46 
47 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57 POSSIBILITY OF SUCH DAMAGE.
58 
59 You are under no obligation whatsoever to provide any bug fixes, patches,
60 or upgrades to the features, functionality or performance of the source
61 code ("Enhancements") to anyone; however, if you choose to make your
62 Enhancements available either publicly, or directly to Lawrence Berkeley
63 National Laboratory, without imposing a separate written license agreement
64 for such Enhancements, then you hereby grant the following license: a
65 non-exclusive, royalty-free perpetual license to install, use, modify,
66 prepare derivative works, incorporate into other computer software,
67 distribute, and sublicense such enhancements or derivative works thereof,
68 in binary and source code form.
69 */
70 
80 #ifndef ARRAYUDF_MPI_H
81 #define ARRAYUDF_MPI_H
82 
83 #include <ctime>
84 #include <iostream>
85 #include "ft_merge.h"
86 
87 #define ENABLE_MPI 1
88 
89 #ifdef ENABLE_MPI
90 #include "mpi.h"
91 #define MPI_COMM_TYPE MPI_Comm
92 #define AU_WTIME_TYPE double
93 #define AU_WTIME MPI_Wtime()
94 #define MPI_COMM_WORLD_DEFAULT MPI_COMM_WORLD
95 #define MPI_INFO_NULL_DEFAULT MPI_INFO_NULL
96 #define AU_MPI_Datatype MPI_Datatype
97 #define AU_MPI_Op MPI_Op
98 #define MPI_INIT(argc, argv, au_mpi_comm_global, au_mpi_rank_global, au_mpi_size_global) \
99  { \
100  int mpi_init_flag = 0; \
101  MPI_Initialized(&mpi_init_flag); \
102  if (!mpi_init_flag) \
103  { \
104  MPI_Init(&argc, &argv); \
105  } \
106  MPI_Comm_rank(au_mpi_comm_global, &au_mpi_rank_global); \
107  MPI_Comm_size(au_mpi_comm_global, &au_mpi_size_global); \
108  }
109 
110 #define MPI_FINALIZE() \
111  { \
112  int mpi_finalize_flag = 0; \
113  MPI_Finalized(&mpi_finalize_flag); \
114  if (!mpi_finalize_flag) \
115  { \
116  MPI_Finalize(); \
117  } \
118  }
119 
120 template <typename T>
121 inline MPI_Datatype InferMPIType()
122 {
123  if (std::is_same<T, int>::value)
124  {
125  return MPI_INT;
126  }
127  else if (std::is_same<T, short>::value)
128  {
129  return MPI_SHORT;
130  }
131  else if (std::is_same<T, long>::value)
132  {
133  return MPI_LONG;
134  }
135  else if (std::is_same<T, long long>::value)
136  {
137  return MPI_LONG_LONG;
138  }
139  else if (std::is_same<T, unsigned int>::value)
140  {
141  return MPI_UNSIGNED;
142  }
143  else if (std::is_same<T, unsigned short>::value)
144  {
145  return MPI_UNSIGNED_SHORT;
146  }
147  else if (std::is_same<T, unsigned long>::value)
148  {
149  return MPI_UNSIGNED_LONG;
150  }
151  else if (std::is_same<T, unsigned long long>::value)
152  {
153  return MPI_UNSIGNED_LONG_LONG;
154  }
155  else if (std::is_same<T, float>::value)
156  {
157  return MPI_FLOAT;
158  }
159  else if (std::is_same<T, double>::value)
160  {
161  return MPI_DOUBLE;
162  }
163  else if (std::is_same<T, std::complex<double>>::value)
164  {
165  return MPI_CXX_DOUBLE_COMPLEX;
166  }
167  else
168  {
169  AU_EXIT("Not supporte MPI data type");
170  }
171 
172  return MPI_INT;
173 }
174 
175 inline MPI_Op InferMPIMergeOp(std::string &opt_str)
176 {
177  AU_Op op_int;
178  std::istringstream reader(opt_str);
179  reader >> op_int;
180 
181  switch (op_int)
182  {
183  case AU_MAX:
184  return MPI_MAX;
185  break;
186  case AU_MIN:
187  return MPI_MIN;
188  break;
189  case AU_SUM:
190  return MPI_SUM;
191  break;
192  case AU_PROD:
193  return MPI_PROD;
194  break;
195  case AU_LAND:
196  return MPI_LAND;
197  break;
198  case AU_BAND:
199  return MPI_BAND;
200  break;
201  case AU_LOR:
202  return MPI_LOR;
203  break;
204  case AU_BOR:
205  return MPI_BOR;
206  break;
207  case AU_LXOR:
208  return MPI_LXOR;
209  break;
210  case AU_BXOR:
211  return MPI_BXOR;
212  break;
213  case AU_MINLOC:
214  return MPI_MINLOC;
215  break;
216  case AU_MAXLOC:
217  return MPI_MAXLOC;
218  break;
219  case AU_REPLACE:
220  return MPI_REPLACE;
221  break;
222  default:
223  AU_EXIT("Not supported type in MPI_Reduce");
224  break;
225  }
226 
227  return 0;
228 }
229 
230 #define AU_Reduce(local_buffer_p, reduced_buffer_p, size, type, op, root, comm) \
231  { \
232  MPI_Reduce(local_buffer_p, reduced_buffer_p, size, type, op, root, comm); \
233  }
234 #define AU_Bcast(data_bffer_p, count_p, datatype_p, root_p, comm_p) \
235  { \
236  MPI_Bcast(data_bffer_p, count_p, datatype_p, root_p, comm_p); \
237  }
238 
246 template <typename T>
247 inline void MPIReduceStats(const T local_value, std::vector<T> &stats_vector)
248 {
249  MPI_Datatype mpi_type = InferMPIType<T>();
250  T value_max, value_min, value_sum;
251  MPI_Allreduce(&local_value, &value_max, 1, mpi_type, MPI_MAX, MPI_COMM_WORLD);
252  MPI_Allreduce(&local_value, &value_min, 1, mpi_type, MPI_MIN, MPI_COMM_WORLD);
253  MPI_Allreduce(&local_value, &value_sum, 1, mpi_type, MPI_SUM, MPI_COMM_WORLD);
254 
255  stats_vector.resize(3);
256  stats_vector[0] = value_max;
257  stats_vector[1] = value_min;
258  stats_vector[2] = value_sum;
259 }
260 
261 #else
262 #define MPI_COMM_TYPE int
263 #define AU_WTIME_TYPE time_t
264 #define AU_WTIME time(NULL)
265 #define MPI_COMM_WORLD_DEFAULT 0
266 #define MPI_INFO_NULL_DEFAULT 0
267 #define AU_MPI_Datatype int
268 #define AU_MPI_Op int
269 
270 #define MPI_INIT(argc, argv, au_mpi_comm_global, au_mpi_rank_global, au_mpi_size_global) \
271  { \
272  au_mpi_rank_global = 0; \
273  au_mpi_size_global = 1; \
274  }
275 #define MPI_FINALIZE() \
276  { \
277  }
278 
286 template <typename T>
287 inline void MPIReduceStats(const T local_value, std::vector<T> &stats_vector)
288 {
289  stats_vector.resize(3);
290  stats_vector[0] = local_value;
291  stats_vector[1] = local_value;
292  stats_vector[2] = local_value;
293 }
294 
295 template <typename T>
296 inline int InferMPIType()
297 {
298  AU_EXIT("No MPI used to compile wihtout MPI compiled !");
299 }
300 
301 inline int InferMPIMergeOp(std::string &opt_str)
302 {
303  AU_EXIT("Should not be here wihtout MPI compiled !");
304 }
305 
306 #define AU_Reduce(local_buffer_p, reduced_buffer_p, size, type, op, root, comm) \
307  { \
308  AU_EXIT("Should not be here wihtout MPI compiled !"); \
309  }
310 
311 #define AU_Bcast(data_bffer_p, count_p, datatype_p, root_p, comm_p) \
312  { \
313  AU_EXIT("Should not be here wihtout MPI compiled !"); \
314  }
315 #endif
316 
317 #endif
#define AU_MAXLOC
Definition: ft_merge.h:101
#define AU_LOR
Definition: ft_merge.h:96
#define AU_BOR
Definition: ft_merge.h:97
#define AU_BXOR
Definition: ft_merge.h:99
#define AU_BAND
Definition: ft_merge.h:95
#define AU_PROD
Definition: ft_merge.h:93
#define AU_MAX
Definition: ft_merge.h:90
#define AU_LXOR
Definition: ft_merge.h:98
#define AU_SUM
Definition: ft_merge.h:92
#define AU_LAND
Definition: ft_merge.h:94
#define AU_MINLOC
Definition: ft_merge.h:100
#define AU_REPLACE
Definition: ft_merge.h:102
#define AU_MIN
Definition: ft_merge.h:91
int AU_Op
Definition: ft_merge.h:88
MPI_Datatype InferMPIType()
Definition: ft_mpi.h:121
MPI_Op InferMPIMergeOp(std::string &opt_str)
Definition: ft_mpi.h:175
void MPIReduceStats(const T local_value, std::vector< T > &stats_vector)
get max/min/sum of local_value
Definition: ft_mpi.h:247
#define AU_EXIT(info)
Definition: ft_utility_macro.h:147