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