op_function.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 #ifndef LIBMESH_OP_FUNCTION_H
20 #define LIBMESH_OP_FUNCTION_H
21 
22 // C++ includes
23 #include <type_traits>
24 
25 namespace libMesh
26 {
27 
28 namespace Parallel
29 {
30 //-------------------------------------------------------------------
31 
32 // Templated helper class to be used with static_assert.
33 template<typename T>
34 struct opfunction_dependent_false : std::false_type
35 {};
36 
44 template <typename T>
46 {
47  // Get a slightly better compiler diagnostic if we have C++11
49  "Only specializations of OpFunction may be used, did you forget to include a header file (e.g. parallel_algebra.h)?");
50 
51  /*
52  * The unspecialized class defines none of these functions;
53  * specializations will need to define any functions that need to be
54  * usable.
55  *
56  * Most specializations will just return MPI_MIN, etc, but we'll use
57  * a whitelist rather than a default implementation, so that any
58  * attempt to perform a reduction on an unspecialized type will be a
59  * compile-time rather than a run-time failure.
60  */
61  // static MPI_Op max();
62  // static MPI_Op min();
63  // static MPI_Op sum();
64  // static MPI_Op product();
65  // static MPI_Op logical_and();
66  // static MPI_Op bitwise_and();
67  // static MPI_Op logical_or();
68  // static MPI_Op bitwise_or();
69  // static MPI_Op logical_xor();
70  // static MPI_Op bitwise_xor();
71  // static MPI_Op max_loc();
72  // static MPI_Op min_loc();
73 };
74 
75 
76 
77 // ------------------------------------------------------------
78 // Declare OpFunction specializations for C++ built-in types
79 
80 #ifdef LIBMESH_HAVE_MPI
81 
82 #define LIBMESH_PARALLEL_INTEGER_OPS(cxxtype) \
83  template<> \
84  class OpFunction<cxxtype> \
85  { \
86  public: \
87  static MPI_Op max() { return MPI_MAX; } \
88  static MPI_Op min() { return MPI_MIN; } \
89  static MPI_Op sum() { return MPI_SUM; } \
90  static MPI_Op product() { return MPI_PROD; } \
91  static MPI_Op logical_and() { return MPI_LAND; } \
92  static MPI_Op bitwise_and() { return MPI_BAND; } \
93  static MPI_Op logical_or() { return MPI_LOR; } \
94  static MPI_Op bitwise_or() { return MPI_BOR; } \
95  static MPI_Op logical_xor() { return MPI_LXOR; } \
96  static MPI_Op bitwise_xor() { return MPI_BXOR; } \
97  static MPI_Op max_location() { return MPI_MAXLOC; } \
98  static MPI_Op min_location() { return MPI_MINLOC; } \
99  }
100 
101 #define LIBMESH_PARALLEL_FLOAT_OPS(cxxtype) \
102  template<> \
103  class OpFunction<cxxtype> \
104  { \
105  public: \
106  static MPI_Op max() { return MPI_MAX; } \
107  static MPI_Op min() { return MPI_MIN; } \
108  static MPI_Op sum() { return MPI_SUM; } \
109  static MPI_Op product() { return MPI_PROD; } \
110  static MPI_Op max_location() { return MPI_MAXLOC; } \
111  static MPI_Op min_location() { return MPI_MINLOC; } \
112  }
113 
114 #else
115 
116 #define LIBMESH_PARALLEL_INTEGER_OPS(cxxtype) \
117  template<> \
118  class OpFunction<cxxtype> \
119  { \
120  }
121 
122 #define LIBMESH_PARALLEL_FLOAT_OPS(cxxtype) \
123  template<> \
124  class OpFunction<cxxtype> \
125  { \
126  }
127 
128 #endif
129 
131 LIBMESH_PARALLEL_INTEGER_OPS(signed char);
132 LIBMESH_PARALLEL_INTEGER_OPS(unsigned char);
134 LIBMESH_PARALLEL_INTEGER_OPS(unsigned short int);
136 LIBMESH_PARALLEL_INTEGER_OPS(unsigned int);
139 LIBMESH_PARALLEL_INTEGER_OPS(unsigned long);
140 LIBMESH_PARALLEL_INTEGER_OPS(unsigned long long); \
141 
142 LIBMESH_PARALLEL_FLOAT_OPS(float);
144 LIBMESH_PARALLEL_FLOAT_OPS(long double);
145 
146 } // namespace Parallel
147 
148 } // namespace libMesh
149 
150 #endif // LIBMESH_OP_FUNCTION_H
LIBMESH_PARALLEL_FLOAT_OPS(float)
LIBMESH_PARALLEL_INTEGER_OPS(char)