|
Anasazi Version of the Day
|
00001 #include <Tsqr_Config.hpp> 00002 #include <Tsqr_MpiDatatype.hpp> 00003 00004 #ifdef HAVE_TSQR_COMPLEX 00005 # include <complex> 00006 #endif // HAVE_TSQR_COMPLEX 00007 00008 #include <utility> // std::pair 00009 00012 00013 namespace TSQR { 00014 namespace MPI { 00015 00016 MPI_Datatype 00017 cloneRawDatatype (MPI_Datatype in, const bool needsFree) 00018 { 00019 MPI_Datatype out; 00020 if (needsFree) 00021 { 00022 // Non-simple MPI_Datatype objects (i.e., those on which 00023 // we need to call MPI_Type_free() after we're done using 00024 // them) cannot be copied directly. Instead, we clone 00025 // them using MPI_Type_contiguous() with a count argument 00026 // of 1. 00027 const int err = MPI_Type_contiguous (1, in, &out); 00028 if (err != MPI_SUCCESS) 00029 throw std::runtime_error("Failed to clone MPI_Datatype object"); 00030 } 00031 else 00032 { 00033 // Simple MPI_Datatype objects can be copied directly. 00034 // Here, "simple" means that we don't have to call 00035 // MPI_Type_free() on them when we are done using them. 00036 out = in; 00037 } 00038 return out; 00039 } 00040 00055 static MPI_Datatype 00056 mpi_pair_of (MPI_Datatype in) 00057 { 00058 // This is just a handle, remember? It's ok to return it; it 00059 // won't fall out of scope. The MPI implementation is responsible 00060 // for keeping track of these things. 00061 MPI_Datatype new_type; 00062 int err = MPI_Type_contiguous (2, in, &new_type); 00063 if (err != MPI_SUCCESS) 00064 throw std::logic_error ("Failed to create MPI_Datatype"); 00065 return new_type; 00066 } 00067 00068 template<> 00069 MpiDatatype< double >::MpiDatatype () : 00070 type_ (MPI_DOUBLE), 00071 needsFree_ (false) 00072 {} 00073 00074 template<> 00075 MpiDatatype< float >::MpiDatatype () : 00076 type_ (MPI_FLOAT), 00077 needsFree_ (false) 00078 {} 00079 00080 template<> 00081 MpiDatatype< std::pair< double, double > >::MpiDatatype () : 00082 type_ (mpi_pair_of (MPI_DOUBLE)), 00083 needsFree_ (true) 00084 {} 00085 00086 template<> 00087 MpiDatatype< std::pair< float, float > >::MpiDatatype () : 00088 type_ (mpi_pair_of (MPI_FLOAT)), 00089 needsFree_ (true) 00090 {} 00091 00092 #ifdef HAVE_TSQR_COMPLEX 00093 template<> 00094 MpiDatatype< std::complex<double> >::MpiDatatype () : 00095 type_ (mpi_pair_of (MPI_DOUBLE)), 00096 needsFree_ (true) 00097 {} 00098 00099 template<> 00100 MpiDatatype< std::complex<float> >::MpiDatatype () : 00101 type_ (mpi_pair_of (MPI_FLOAT)), 00102 needsFree_ (true) 00103 {} 00104 #endif // HAVE_TSQR_COMPLEX 00105 00106 template<> 00107 MpiDatatype< int >::MpiDatatype () : 00108 type_ (MPI_INT), 00109 needsFree_ (false) 00110 {} 00111 00112 template<> 00113 MpiDatatype< std::pair<int, int> >::MpiDatatype () : 00114 type_ (MPI_2INT), 00115 needsFree_ (false) 00116 {} 00117 00118 template<> 00119 MpiDatatype< unsigned long >::MpiDatatype () : 00120 type_ (MPI_UNSIGNED_LONG), 00121 needsFree_ (false) 00122 {} 00123 00124 template<> 00125 MpiDatatype< std::pair< unsigned long, unsigned long > >::MpiDatatype () : 00126 type_ (mpi_pair_of (MPI_UNSIGNED_LONG)), 00127 needsFree_ (true) 00128 {} 00129 00130 } // namespace MPI 00131 } // namespace TSQR 00132
1.7.4