1 #include <vector>
2 
3 namespace diy
4 {
5 namespace mpi
6 {
7 namespace detail
8 {
9   // send
10   template< class T, class is_mpi_datatype_ = typename is_mpi_datatype<T>::type >
11   struct send;
12 
13   template<class T>
14   struct send<T, true_type>
15   {
operator ()diy::mpi::detail::send16     void operator()(MPI_Comm comm, int dest, int tag, const T& x) const
17     {
18 #ifndef DIY_NO_MPI
19       typedef       mpi_datatype<T>     Datatype;
20       MPI_Send((void*) Datatype::address(x),
21                Datatype::count(x),
22                Datatype::datatype(),
23                dest, tag, comm);
24 #else
25       (void) comm; (void) dest; (void) tag; (void) x;
26       DIY_UNSUPPORTED_MPI_CALL(MPI_Send);
27 #endif
28     }
29   };
30 
31   // recv
32   template< class T, class is_mpi_datatype_ = typename is_mpi_datatype<T>::type >
33   struct recv;
34 
35   template<class T>
36   struct recv<T, true_type>
37   {
operator ()diy::mpi::detail::recv38     status operator()(MPI_Comm comm, int source, int tag, T& x) const
39     {
40 #ifndef DIY_NO_MPI
41       typedef       mpi_datatype<T>     Datatype;
42       status s;
43       MPI_Recv((void*) Datatype::address(x),
44                 Datatype::count(x),
45                 Datatype::datatype(),
46                 source, tag, comm, &s.s);
47       return s;
48 #else
49       (void) comm; (void) source; (void) tag; (void) x;
50       DIY_UNSUPPORTED_MPI_CALL(MPI_Recv);
51 #endif
52     }
53   };
54 
55   template<class U>
56   struct recv<std::vector<U>, true_type>
57   {
operator ()diy::mpi::detail::recv58     status operator()(MPI_Comm comm, int source, int tag, std::vector<U>& x) const
59     {
60 #ifndef DIY_NO_MPI
61       status s;
62 
63       MPI_Probe(source, tag, comm, &s.s);
64       x.resize(s.count<U>());
65       MPI_Recv(&x[0], static_cast<int>(x.size()), get_mpi_datatype<U>(), source, tag, comm, &s.s);
66       return s;
67 #else
68       (void) comm; (void) source; (void) tag; (void) x;
69       DIY_UNSUPPORTED_MPI_CALL(MPI_Recv);
70 #endif
71     }
72   };
73 
74   // isend
75   template< class T, class is_mpi_datatype_ = typename is_mpi_datatype<T>::type >
76   struct isend;
77 
78   template<class T>
79   struct isend<T, true_type>
80   {
operator ()diy::mpi::detail::isend81     request operator()(MPI_Comm comm, int dest, int tag, const T& x) const
82     {
83 #ifndef DIY_NO_MPI
84       request r;
85       typedef       mpi_datatype<T>     Datatype;
86       MPI_Isend((void*) Datatype::address(x),
87                 Datatype::count(x),
88                 Datatype::datatype(),
89                 dest, tag, comm, &r.r);
90       return r;
91 #else
92       (void) comm; (void) dest; (void) tag; (void) x;
93       DIY_UNSUPPORTED_MPI_CALL(MPI_Isend);
94 #endif
95     }
96   };
97 
98   // issend
99   template< class T, class is_mpi_datatype_ = typename is_mpi_datatype<T>::type >
100   struct issend;
101 
102   template<class T>
103   struct issend<T, true_type>
104   {
operator ()diy::mpi::detail::issend105     request operator()(MPI_Comm comm, int dest, int tag, const T& x) const
106     {
107 #ifndef DIY_NO_MPI
108       request r;
109       typedef       mpi_datatype<T>     Datatype;
110       MPI_Issend((void*) Datatype::address(x),
111                 Datatype::count(x),
112                 Datatype::datatype(),
113                 dest, tag, comm, &r.r);
114       return r;
115 #else
116       (void) comm; (void) dest; (void) tag; (void) x;
117       DIY_UNSUPPORTED_MPI_CALL(MPI_Issend);
118 #endif
119     }
120   };
121 
122   // irecv
123   template< class T, class is_mpi_datatype_ = typename is_mpi_datatype<T>::type >
124   struct irecv;
125 
126   template<class T>
127   struct irecv<T, true_type>
128   {
operator ()diy::mpi::detail::irecv129     request operator()(MPI_Comm comm, int source, int tag, T& x) const
130     {
131 #ifndef DIY_NO_MPI
132       request r;
133       typedef       mpi_datatype<T>     Datatype;
134       MPI_Irecv(Datatype::address(x),
135                 Datatype::count(x),
136                 Datatype::datatype(),
137                 source, tag, comm, &r.r);
138       return r;
139 #else
140       (void) comm; (void) source; (void) tag; (void) x;
141       DIY_UNSUPPORTED_MPI_CALL(MPI_Irecv);
142 #endif
143     }
144   };
145 }
146 }
147 }
148