Kokkos Node API and Local Linear Algebra Kernels Version of the Day
Tsqr_MpiDatatype.cpp
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //          Kokkos: Node API and Parallel Node Kernels
00005 //              Copyright (2009) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ************************************************************************
00027 //@HEADER
00028 
00029 #include <Tsqr_ConfigDefs.hpp>
00030 #include <Tsqr_MpiDatatype.hpp>
00031 
00032 #ifdef HAVE_MPI // #defined (or not) via Teuchos_ConfigDefs.hpp
00033 #  ifdef HAVE_TSQR_COMPLEX
00034 #    include <complex>
00035 #  endif // HAVE_TSQR_COMPLEX
00036 #  include <utility> // std::pair
00037 
00038 
00039 namespace TSQR {
00040   namespace MPI {
00041 
00042     MPI_Datatype 
00043     cloneRawDatatype (MPI_Datatype in, const bool needsFree)
00044     {
00045       MPI_Datatype out;
00046       if (needsFree)
00047   {
00048     // Non-simple MPI_Datatype objects (i.e., those on which
00049     // we need to call MPI_Type_free() after we're done using
00050     // them) cannot be copied directly.  Instead, we clone
00051     // them using MPI_Type_contiguous() with a count argument
00052     // of 1.
00053     const int err = MPI_Type_contiguous (1, in, &out);
00054     if (err != MPI_SUCCESS)
00055       throw std::runtime_error("Failed to clone MPI_Datatype object");
00056   }
00057       else
00058   {
00059     // Simple MPI_Datatype objects can be copied directly.
00060     // Here, "simple" means that we don't have to call
00061     // MPI_Type_free() on them when we are done using them.
00062     out = in;
00063   }
00064       return out;
00065     }
00066 
00081     static MPI_Datatype
00082     mpi_pair_of (MPI_Datatype in)
00083     {
00084       // This is just a handle, remember?  It's ok to return it; it
00085       // won't fall out of scope.  The MPI implementation is responsible
00086       // for keeping track of these things.
00087       MPI_Datatype new_type;
00088       int err = MPI_Type_contiguous (2, in, &new_type);
00089       if (err != MPI_SUCCESS)
00090   throw std::logic_error ("Failed to create MPI_Datatype");
00091       return new_type;
00092     }
00093 
00094     template<>
00095     MpiDatatype< double >::MpiDatatype () : 
00096       type_ (MPI_DOUBLE),
00097       needsFree_ (false)
00098     {}
00099 
00100     template<>
00101     MpiDatatype< float >::MpiDatatype () :
00102       type_ (MPI_FLOAT),
00103       needsFree_ (false)
00104     {}
00105 
00106     template<>
00107     MpiDatatype< std::pair< double, double > >::MpiDatatype () : 
00108       type_ (mpi_pair_of (MPI_DOUBLE)),
00109       needsFree_ (true)
00110     {}
00111 
00112     template<>
00113     MpiDatatype< std::pair< float, float > >::MpiDatatype () : 
00114       type_ (mpi_pair_of (MPI_FLOAT)),
00115       needsFree_ (true)
00116     {}
00117 
00118 #ifdef HAVE_TSQR_COMPLEX
00119     template<>
00120     MpiDatatype< std::complex<double> >::MpiDatatype () :
00121       type_ (mpi_pair_of (MPI_DOUBLE)),
00122       needsFree_ (true)
00123     {}
00124 
00125     template<>
00126     MpiDatatype< std::complex<float> >::MpiDatatype () :
00127       type_ (mpi_pair_of (MPI_FLOAT)),
00128       needsFree_ (true)
00129     {}
00130 #endif // HAVE_TSQR_COMPLEX
00131 
00132     template<>
00133     MpiDatatype< int >::MpiDatatype () : 
00134       type_ (MPI_INT),
00135       needsFree_ (false)
00136     {}
00137 
00138     template<>
00139     MpiDatatype< std::pair<int, int> >::MpiDatatype () : 
00140       type_ (MPI_2INT),
00141       needsFree_ (false)
00142     {}
00143 
00144     template<>
00145     MpiDatatype< unsigned long >::MpiDatatype () : 
00146       type_ (MPI_UNSIGNED_LONG),
00147       needsFree_ (false)
00148     {}
00149 
00150     template<>
00151     MpiDatatype< std::pair< unsigned long, unsigned long > >::MpiDatatype () : 
00152       type_ (mpi_pair_of (MPI_UNSIGNED_LONG)),
00153       needsFree_ (true)
00154     {}
00155 
00156   } // namespace MPI
00157 } // namespace TSQR
00158 
00159 
00160 #endif // HAVE_MPI
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends