Anasazi Version of the Day
Tsqr_MpiDatatype.cpp
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends