Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_PardisoMKL_TypeMap.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver Package 
00006 //                  Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //
00042 // @HEADER
00043 
00044 
00056 #ifndef AMESOS2_PARDISOMKL_TYPEMAP_HPP
00057 #define AMESOS2_PARDISOMKL_TYPEMAP_HPP
00058 
00059 #ifdef HAVE_TEUCHOS_COMPLEX
00060 #include <complex>
00061 #endif
00062 
00063 #include <Teuchos_as.hpp>
00064 #ifdef HAVE_TEUCHOS_COMPLEX
00065 #include <Teuchos_SerializationTraits.hpp>
00066 #endif
00067 
00068 #include "Amesos2_TypeMap.hpp"
00069 
00070 namespace Amesos2{
00071   namespace PMKL {
00072 #   include <mkl_dss.h>
00073 #   include <mkl_types.h>
00074   } // end namespace PMKL
00075 } // end namespace Amesos2
00076 
00077 
00078 /* ==================== Conversion ====================
00079  *
00080  * Define here, in the Teuchos namespace, any conversions between
00081  * commonly used date types and the solver-specific data types.  Use
00082  * template specializations of the Teuchos::ValueTypeConversionTraits
00083  * class.
00084  */
00085 namespace Teuchos {
00086 
00087   template <typename TypeFrom>
00088   class ValueTypeConversionTraits<Amesos2::PMKL::_MKL_Complex8, TypeFrom>
00089   {
00090   public:
00091     static Amesos2::PMKL::_MKL_Complex8 convert( const TypeFrom t )
00092     {                           // adapt conversion as necessary
00093       Amesos2::PMKL::_MKL_Complex8 ret;
00094       ret.real = Teuchos::as<float>(t.real());
00095       ret.imag = Teuchos::as<float>(t.imag());
00096       return( ret );
00097     }
00098 
00099     static Amesos2::PMKL::_MKL_Complex8 safeConvert( const TypeFrom t )
00100     {                           // adapt conversion as necessary
00101       Amesos2::PMKL::_MKL_Complex8 ret;
00102       ret.real = Teuchos::as<float>(t.real());
00103       ret.imag = Teuchos::as<float>(t.imag());
00104       return( ret );
00105     }
00106   };
00107 
00108 
00109   template <typename TypeFrom>
00110   class ValueTypeConversionTraits<Amesos2::PMKL::_DOUBLE_COMPLEX_t, TypeFrom>
00111   {
00112   public:
00113     static Amesos2::PMKL::_DOUBLE_COMPLEX_t convert( const TypeFrom t )
00114     {                           // adapt conversion as necessary
00115       Amesos2::PMKL::_DOUBLE_COMPLEX_t ret;
00116       ret.r = Teuchos::as<double>(t.real());
00117       ret.i = Teuchos::as<double>(t.imag());
00118       return( ret );
00119     }
00120 
00121     static Amesos2::PMKL::_DOUBLE_COMPLEX_t safeConvert( const TypeFrom t )
00122     {                           // adapt conversion as necessary
00123       Amesos2::PMKL::_DOUBLE_COMPLEX_t ret;
00124       ret.r = Teuchos::as<double>(t.real());
00125       ret.i = Teuchos::as<double>(t.imag());
00126       return( ret );
00127     }
00128   };
00129 
00130 
00131   // Also convert *from* New_Solver types
00132   template <typename TypeTo>
00133   class ValueTypeConversionTraits<TypeTo, Amesos2::PMKL::_MKL_Complex8>
00134   {
00135   public:
00136     static TypeTo convert( const Amesos2::PMKL::_MKL_Complex8 t )
00137     {                           // adapt conversion as necessary
00138       typedef typename TypeTo::value_type value_type;
00139       value_type ret_r = Teuchos::as<value_type>( t.real );
00140       value_type ret_i = Teuchos::as<value_type>( t.imag );
00141       return ( TypeTo( ret_r, ret_i ) );
00142     }
00143 
00144     static TypeTo safeConvert( const Amesos2::PMKL::_MKL_Complex8 t )
00145     {                           // adapt conversion as necessary
00146       typedef typename TypeTo::value_type value_type;
00147       value_type ret_r = Teuchos::as<value_type>( t.real );
00148       value_type ret_i = Teuchos::as<value_type>( t.imag );
00149       return ( TypeTo( ret_r, ret_i ) );
00150     }
00151   };
00152 
00153 
00154   template <typename TypeTo>
00155   class ValueTypeConversionTraits<TypeTo, Amesos2::PMKL::_DOUBLE_COMPLEX_t>
00156   {
00157   public:
00158     static TypeTo convert( const Amesos2::PMKL::_DOUBLE_COMPLEX_t t )
00159     {
00160       typedef typename TypeTo::value_type value_type;
00161       value_type ret_r = Teuchos::as<value_type>( t.r );
00162       value_type ret_i = Teuchos::as<value_type>( t.i );
00163       return ( TypeTo( ret_r, ret_i ) );
00164     }
00165 
00166     // No special checks for safe Convert
00167     static TypeTo safeConvert( const Amesos2::PMKL::_DOUBLE_COMPLEX_t t )
00168     {
00169       typedef typename TypeTo::value_type value_type;
00170       value_type ret_r = Teuchos::as<value_type>( t.r );
00171       value_type ret_i = Teuchos::as<value_type>( t.i );
00172       return ( TypeTo( ret_r, ret_i ) );
00173     }
00174   };
00175 
00177 
00178 } // end namespace Teuchos
00179 
00180 
00181 namespace Amesos2 {
00182 
00183   // forward declaration due to circular reference
00184   template <class, class> class PardisoMKL;
00185 
00186   /* Specialize the Amesos::TypeMap struct for PardisoMKL types.
00187    *
00188    * Additional nested types may be added without harm.  For an example, look at
00189    * Amesos2_Superlu_TypeMap.hpp
00190    */
00191   template <>
00192   struct TypeMap<PardisoMKL,float>
00193   {
00194     typedef PMKL::_REAL_t type;
00195     typedef PMKL::_REAL_t magnitude_type;
00196   };
00197 
00198 
00199   template <>
00200   struct TypeMap<PardisoMKL,double>
00201   {
00202     typedef PMKL::_DOUBLE_PRECISION_t type;
00203     typedef PMKL::_DOUBLE_PRECISION_t magnitude_type;
00204   };
00205 
00206 #ifdef HAVE_TEUCHOS_COMPLEX
00207 
00208   /*
00209    * We map the std complex types to the appropriate PardisoMKL complex
00210    * types.
00211    */
00212 
00213   template <>
00214   struct TypeMap<PardisoMKL,std::complex<float> >
00215   {
00216     typedef PMKL::_MKL_Complex8 type;
00217     typedef PMKL::_REAL_t magnitude_type;
00218   };
00219 
00220 
00221   template <>
00222   struct TypeMap<PardisoMKL,std::complex<double> >
00223   {
00224     typedef PMKL::_DOUBLE_COMPLEX_t type;
00225     typedef PMKL::_DOUBLE_PRECISION_t magnitude_type;
00226   };
00227 
00228 
00229   template <>
00230   struct TypeMap<PardisoMKL,PMKL::_MKL_Complex8>
00231   {
00232     typedef PMKL::_MKL_Complex8 type;
00233     typedef PMKL::_REAL_t magnitude_type;
00234   };
00235 
00236 
00237   template <>
00238   struct TypeMap<PardisoMKL,PMKL::_DOUBLE_COMPLEX_t>
00239   {
00240     typedef PMKL::_DOUBLE_COMPLEX_t type;
00241     typedef PMKL::_DOUBLE_PRECISION_t magnitude_type;
00242   };
00243 #endif  // HAVE_TEUCHOS_COMPLEX
00244 
00245   template <>
00246   struct TypeMap<PardisoMKL,int>
00247   {
00248     typedef PMKL::_INTEGER_t type;
00249   };
00250 
00251   template <>
00252   struct TypeMap<PardisoMKL,long long int>
00253   {
00254     typedef long long int type;
00255   };
00256 
00257   /*
00258    * We check whether the size of long int is bigger than an int.  If
00259    * it is, then long int should be the same size as a long long int,
00260    * so we can safely promote.  Otherwise, long int will probably be
00261    * the same size as int, and we can safely treat it as such.
00262    */
00263   template <>
00264   struct TypeMap<PardisoMKL,long int>
00265   {
00266     typedef Meta::if_then_else<
00267       sizeof(int) < sizeof(long int),
00268       TypeMap<PardisoMKL,long long int>::type,
00269       TypeMap<PardisoMKL,int>::type >::type type;
00270   };
00271 
00272 } // end namespace Amesos
00273 
00274 #endif  // AMESOS2_PARDISOMKL_TYPEMAP_HPP