OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
Operations.h
Go to the documentation of this file.
1 //
2 // File Operations
3 // Definition of MPI operations following the implementation of Boost.MPI.
4 //
5 // Copyright (c) 2017, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved
7 //
8 // Implemented as part of the PhD thesis
9 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
10 //
11 // This file is part of OPAL.
12 //
13 // OPAL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20 //
21 #ifndef IPPL_MPI_OPERATIONS_H
22 #define IPPL_MPI_OPERATIONS_H
23 
24 #include <functional>
25 #include <mpi.h>
26 
27 template<class> struct is_ippl_mpi_type: std::false_type {};
28 
29 template <class Op> MPI_Op get_mpi_op(Op op)
30 {
31  static_assert(is_ippl_mpi_type<Op>::value,
32  "type not supported");
33  return get_mpi_op( op );
34 }
35 
36 #define IPPL_MPI_OP(CppOp, MPIOp) \
37 template <> \
38 inline MPI_Op \
39 get_mpi_op< CppOp >(CppOp) { return MPIOp; } \
40  \
41 template<> \
42 struct is_ippl_mpi_type<CppOp>: \
43  std::true_type {};
44 
45 
46 /* with C++14 we should be able
47  * to simply write
48  *
49  * IPPL_MPI_OP(std::plus<>, MPI_SUM);
50  *
51  */
52 
53 IPPL_MPI_OP(std::plus<char>, MPI_SUM);
54 IPPL_MPI_OP(std::plus<short>, MPI_SUM);
55 IPPL_MPI_OP(std::plus<int>, MPI_SUM);
56 IPPL_MPI_OP(std::plus<long>, MPI_SUM);
57 IPPL_MPI_OP(std::plus<long long>, MPI_SUM);
58 IPPL_MPI_OP(std::plus<unsigned char>, MPI_SUM);
59 IPPL_MPI_OP(std::plus<unsigned short>, MPI_SUM);
60 IPPL_MPI_OP(std::plus<unsigned int>, MPI_SUM);
61 IPPL_MPI_OP(std::plus<unsigned long>, MPI_SUM);
62 IPPL_MPI_OP(std::plus<unsigned long long>, MPI_SUM);
63 IPPL_MPI_OP(std::plus<float>, MPI_SUM);
64 IPPL_MPI_OP(std::plus<double>, MPI_SUM);
65 IPPL_MPI_OP(std::plus<long double>, MPI_SUM);
66 
67 
68 IPPL_MPI_OP(std::less<char>, MPI_MIN);
69 IPPL_MPI_OP(std::less<short>, MPI_MIN);
70 IPPL_MPI_OP(std::less<int>, MPI_MIN);
71 IPPL_MPI_OP(std::less<long>, MPI_MIN);
72 IPPL_MPI_OP(std::less<long long>, MPI_MIN);
73 IPPL_MPI_OP(std::less<unsigned char>, MPI_MIN);
74 IPPL_MPI_OP(std::less<unsigned short>, MPI_MIN);
75 IPPL_MPI_OP(std::less<unsigned int>, MPI_MIN);
76 IPPL_MPI_OP(std::less<unsigned long>, MPI_MIN);
77 IPPL_MPI_OP(std::less<unsigned long long>, MPI_MIN);
78 IPPL_MPI_OP(std::less<float>, MPI_MIN);
79 IPPL_MPI_OP(std::less<double>, MPI_MIN);
80 IPPL_MPI_OP(std::less<long double>, MPI_MIN);
81 
82 
83 IPPL_MPI_OP(std::greater<char>, MPI_MAX);
84 IPPL_MPI_OP(std::greater<short>, MPI_MAX);
85 IPPL_MPI_OP(std::greater<int>, MPI_MAX);
86 IPPL_MPI_OP(std::greater<long>, MPI_MAX);
87 IPPL_MPI_OP(std::greater<long long>, MPI_MAX);
88 IPPL_MPI_OP(std::greater<unsigned char>, MPI_MAX);
89 IPPL_MPI_OP(std::greater<unsigned short>, MPI_MAX);
90 IPPL_MPI_OP(std::greater<unsigned int>, MPI_MAX);
91 IPPL_MPI_OP(std::greater<unsigned long>, MPI_MAX);
92 IPPL_MPI_OP(std::greater<unsigned long long>, MPI_MAX);
93 IPPL_MPI_OP(std::greater<float>, MPI_MAX);
94 IPPL_MPI_OP(std::greater<double>, MPI_MAX);
95 IPPL_MPI_OP(std::greater<long double>, MPI_MAX);
96 
97 
98 IPPL_MPI_OP(std::logical_or<bool>, MPI_LOR);
99 IPPL_MPI_OP(std::logical_and<bool>, MPI_LAND);
100 
101 #endif
MPI_Op get_mpi_op(Op op)
Definition: Operations.h:29
#define IPPL_MPI_OP(CppOp, MPIOp)
Definition: Operations.h:36