Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_PardisoMKL_TypeMap.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Amesos2: Templated Direct Sparse Solver Package
6 // Copyright 2011 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //
42 // @HEADER
43 
44 
56 #ifndef AMESOS2_PARDISOMKL_TYPEMAP_HPP
57 #define AMESOS2_PARDISOMKL_TYPEMAP_HPP
58 
59 #ifdef HAVE_TEUCHOS_COMPLEX
60 #include <complex>
61 #endif
62 
63 #include <Teuchos_as.hpp>
64 #ifdef HAVE_TEUCHOS_COMPLEX
65 #include <Teuchos_SerializationTraits.hpp>
66 #endif
67 
68 #include "Amesos2_TypeMap.hpp"
69 
70 namespace Amesos2{
71  namespace PMKL {
72  //Update JDB 6.25.15
73  //MKL has changed _INTEGER_t to deprecated
74  //MKL has changed _INTEGER_t to define from typedef
75  #ifdef _MKL_TYPES_H_
76  #undef _MKL_TYPES_H_
77  #endif
78  #include <mkl_types.h>
79  #ifdef __MKL_DSS_H
80  #undef __MKL_DSS_H
81  #endif
82  #include <mkl_dss.h>
83  #undef _INTEGER_t
84  typedef MKL_INT _INTEGER_t;
85  } // end namespace PMKL
86 } // end namespace Amesos2
87 
88 
89 /* ==================== Conversion ====================
90  *
91  * Define here, in the Teuchos namespace, any conversions between
92  * commonly used date types and the solver-specific data types. Use
93  * template specializations of the Teuchos::ValueTypeConversionTraits
94  * class.
95  */
96 #ifdef HAVE_TEUCHOS_COMPLEX
97 namespace Teuchos {
98 
99  template <typename TypeFrom>
100  class ValueTypeConversionTraits<Amesos2::PMKL::_MKL_Complex8, TypeFrom>
101  {
102  public:
103  static Amesos2::PMKL::_MKL_Complex8 convert( const TypeFrom t )
104  { // adapt conversion as necessary
105  Amesos2::PMKL::_MKL_Complex8 ret;
106  ret.real = Teuchos::as<float>(t.real());
107  ret.imag = Teuchos::as<float>(t.imag());
108  return( ret );
109  }
110 
111  static Amesos2::PMKL::_MKL_Complex8 safeConvert( const TypeFrom t )
112  { // adapt conversion as necessary
113  Amesos2::PMKL::_MKL_Complex8 ret;
114  ret.real = Teuchos::as<float>(t.real());
115  ret.imag = Teuchos::as<float>(t.imag());
116  return( ret );
117  }
118  };
119 
120 
121  template <typename TypeFrom>
122  class ValueTypeConversionTraits<Amesos2::PMKL::_DOUBLE_COMPLEX_t, TypeFrom>
123  {
124  public:
125  static Amesos2::PMKL::_DOUBLE_COMPLEX_t convert( const TypeFrom t )
126  { // adapt conversion as necessary
127  Amesos2::PMKL::_DOUBLE_COMPLEX_t ret;
128  ret.r = Teuchos::as<double>(t.real());
129  ret.i = Teuchos::as<double>(t.imag());
130  return( ret );
131  }
132 
133  static Amesos2::PMKL::_DOUBLE_COMPLEX_t safeConvert( const TypeFrom t )
134  { // adapt conversion as necessary
135  Amesos2::PMKL::_DOUBLE_COMPLEX_t ret;
136  ret.r = Teuchos::as<double>(t.real());
137  ret.i = Teuchos::as<double>(t.imag());
138  return( ret );
139  }
140  };
141 
142 
143  // Also convert *from* New_Solver types
144  template <typename TypeTo>
145  class ValueTypeConversionTraits<TypeTo, Amesos2::PMKL::_MKL_Complex8>
146  {
147  public:
148  static TypeTo convert( const Amesos2::PMKL::_MKL_Complex8 t )
149  { // adapt conversion as necessary
150  typedef typename TypeTo::value_type value_type;
151  value_type ret_r = Teuchos::as<value_type>( t.real );
152  value_type ret_i = Teuchos::as<value_type>( t.imag );
153  return ( TypeTo( ret_r, ret_i ) );
154  }
155 
156  static TypeTo safeConvert( const Amesos2::PMKL::_MKL_Complex8 t )
157  { // adapt conversion as necessary
158  typedef typename TypeTo::value_type value_type;
159  value_type ret_r = Teuchos::as<value_type>( t.real );
160  value_type ret_i = Teuchos::as<value_type>( t.imag );
161  return ( TypeTo( ret_r, ret_i ) );
162  }
163  };
164 
165 
166  template <typename TypeTo>
167  class ValueTypeConversionTraits<TypeTo, Amesos2::PMKL::_DOUBLE_COMPLEX_t>
168  {
169  public:
170  static TypeTo convert( const Amesos2::PMKL::_DOUBLE_COMPLEX_t t )
171  {
172  typedef typename TypeTo::value_type value_type;
173  value_type ret_r = Teuchos::as<value_type>( t.r );
174  value_type ret_i = Teuchos::as<value_type>( t.i );
175  return ( TypeTo( ret_r, ret_i ) );
176  }
177 
178  // No special checks for safe Convert
179  static TypeTo safeConvert( const Amesos2::PMKL::_DOUBLE_COMPLEX_t t )
180  {
181  typedef typename TypeTo::value_type value_type;
182  value_type ret_r = Teuchos::as<value_type>( t.r );
183  value_type ret_i = Teuchos::as<value_type>( t.i );
184  return ( TypeTo( ret_r, ret_i ) );
185  }
186  };
187 
189 
190 } // end namespace Teuchos
191 #endif
192 
193 namespace Amesos2 {
194 
195  // forward declaration due to circular reference
196  template <class, class> class PardisoMKL;
197 
198  /* Specialize the Amesos::TypeMap struct for PardisoMKL types.
199  *
200  * Additional nested types may be added without harm. For an example, look at
201  * Amesos2_Superlu_TypeMap.hpp
202  */
203 
204  template <>
205  struct TypeMap<PardisoMKL,float>
206  {
207  typedef PMKL::_REAL_t type;
208  typedef PMKL::_REAL_t magnitude_type;
209  };
210 
211 
212  template <>
213  struct TypeMap<PardisoMKL,double>
214  {
215  typedef PMKL::_DOUBLE_PRECISION_t type;
216  typedef PMKL::_DOUBLE_PRECISION_t magnitude_type;
217  };
218 
219 #ifdef HAVE_TEUCHOS_COMPLEX
220 
221  /*
222  * We map the std complex types to the appropriate PardisoMKL complex
223  * types.
224  */
225 
226  template <>
227  struct TypeMap<PardisoMKL,std::complex<float> >
228  {
229  typedef PMKL::_MKL_Complex8 type;
230  typedef PMKL::_REAL_t magnitude_type;
231  };
232 
233 
234  template <>
235  struct TypeMap<PardisoMKL,std::complex<double> >
236  {
237  typedef PMKL::_DOUBLE_COMPLEX_t type;
238  typedef PMKL::_DOUBLE_PRECISION_t magnitude_type;
239  };
240 
241 
242  template <>
243  struct TypeMap<PardisoMKL,PMKL::_MKL_Complex8>
244  {
245  typedef PMKL::_MKL_Complex8 type;
246  typedef PMKL::_REAL_t magnitude_type;
247  };
248 
249 
250  template <>
251  struct TypeMap<PardisoMKL,PMKL::_DOUBLE_COMPLEX_t>
252  {
253  typedef PMKL::_DOUBLE_COMPLEX_t type;
254  typedef PMKL::_DOUBLE_PRECISION_t magnitude_type;
255  };
256 #endif // HAVE_TEUCHOS_COMPLEX
257 
258  template <>
259  struct TypeMap<PardisoMKL,int>
260  {
261  typedef PMKL::_INTEGER_t type;
262  //typedef int type;
263  };
264 
265  template <>
266  struct TypeMap<PardisoMKL,long long int>
267  {
268  typedef long long int type;
269  };
270 
271  /*
272  * We check whether the size of long int is bigger than an int. If
273  * it is, then long int should be the same size as a long long int,
274  * so we can safely promote. Otherwise, long int will probably be
275  * the same size as int, and we can safely treat it as such.
276  */
277  template <>
278  struct TypeMap<PardisoMKL,long int>
279  {
280  typedef Meta::if_then_else<
281  sizeof(int) < sizeof(long int),
282  TypeMap<PardisoMKL,long long int>::type,
283  TypeMap<PardisoMKL,int>::type >::type type;
284  };
285 
286 } // end namespace Amesos
287 
288 #endif // AMESOS2_PARDISOMKL_TYPEMAP_HPP