COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
MPIOp.h
Go to the documentation of this file.
1#ifndef _MPI_OP_H
2#define _MPI_OP_H
3
4#include <iostream>
5#include <typeinfo>
6#include <map>
7#include <functional>
8#include <mpi.h>
9#include <stdint.h>
10#include "Operations.h"
11#include "MPIType.h" // type_info_compare definition
12
13namespace combblas {
14
16{
17private:
18 typedef std::map<std::type_info const*, MPI_Op, type_info_compare> stored_map_type;
19 stored_map_type map;
20
21public:
22 void clear()
23 {
24 int is_finalized=0;
26 if (! is_finalized ) // do not free after call to MPI_FInalize
27 {
28 // ignore errors in the destructor
29 for (stored_map_type::iterator it=map.begin(); it != map.end(); ++it)
30 {
31 MPI_Op_free(&(it->second));
32 }
33 }
34 }
36 {
37 clear();
38 }
39 MPI_Op get(const std::type_info* t)
40 {
41 stored_map_type::iterator pos = map.find(t);
42 if (pos != map.end())
43 return pos->second;
44 else
45 return MPI_OP_NULL;
46 }
47
48 void set(const std::type_info* t, MPI_Op datatype)
49 {
50#ifdef NOTGNU
51 if (map.find(t) != map.end()) map.erase(t);
52 map.insert(std::make_pair(t, datatype));
53#else
54 map[t] = datatype;
55#endif
56 }
57};
58
59extern MPIOpCache mpioc; // global variable
60
61
62// MPIOp: A class that has a static op() function that takes no arguments and returns the corresponding MPI_Op
63// if and only if the given Op has a mapping to a valid MPI_Op
64// No concepts checking for the applicability of Op on the datatype T at the moment
65// In the future, this can be implemented via metafunction forwarding using mpl::or_ and mpl::bool_
66
67template <typename Op, typename T, typename Enable = void>
68struct MPIOp
69{
70 static void funcmpi(void * invec, void * inoutvec, int * len, MPI_Datatype *datatype)
71 {
72 Op myop; // you need to create the object instance
73 T * pinvec = static_cast<T*>(invec);
74 T * pinoutvec = static_cast<T*>(inoutvec);
75 for (int i = 0; i < *len; i++)
76 {
77 pinoutvec[i] = myop(pinvec[i], pinoutvec[i]);
78 }
79 }
80 static MPI_Op op()
81 {
82 std::type_info const* t = &typeid(Op);
84
85 if (foundop == MPI_OP_NULL)
86 {
88
89 int myrank;
91 if(myrank == 0)
92 std::cout << "Creating a new MPI Op for " << t->name() << std::endl;
93
94 mpioc.set(t, foundop);
95 }
96 return foundop;
97 }
98};
99
100template<typename T> struct MPIOp< maximum<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_MAX; } };
101template<typename T> struct MPIOp< minimum<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_MIN; } };
102template<typename T> struct MPIOp< std::plus<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_SUM; } };
103template<typename T> struct MPIOp< std::multiplies<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_PROD; } };
104template<typename T> struct MPIOp< std::logical_and<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_LAND; } };
105template<typename T> struct MPIOp< std::logical_or<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_LOR; } };
106template<typename T> struct MPIOp< logical_xor<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_LXOR; } };
107template<typename T> struct MPIOp< bitwise_and<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_BAND; } };
108template<typename T> struct MPIOp< bitwise_or<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_BOR; } };
109template<typename T> struct MPIOp< bitwise_xor<T>,T,typename std::enable_if<std::is_pod<T>::value, void>::type > { static MPI_Op op() { return MPI_BXOR; } };
110
111}
112
113#endif
MPI_Op get(const std::type_info *t)
Definition MPIOp.h:39
void set(const std::type_info *t, MPI_Op datatype)
Definition MPIOp.h:48
MPIOpCache mpioc
Definition MPIOp.h:59
static MPI_Op op()
Definition MPIOp.h:80
static void funcmpi(void *invec, void *inoutvec, int *len, MPI_Datatype *datatype)
Definition MPIOp.h:70
Compute the bitwise AND of two integral values.
Definition Operations.h:234
Compute the bitwise OR of two integral values.
Definition Operations.h:252
Compute the bitwise exclusive OR of two integral values.
Definition Operations.h:287
Compute the logical exclusive OR of two integral values.
Definition Operations.h:269
Compute the maximum of two values.
Definition Operations.h:155
Compute the minimum of two values.
Definition Operations.h:173