Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_Superlu_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 
54 #ifndef AMESOS2_SUPERLU_TYPEMAP_HPP
55 #define AMESOS2_SUPERLU_TYPEMAP_HPP
56 
57 #include <functional>
58 #ifdef HAVE_TEUCHOS_COMPLEX
59 #include <complex>
60 #endif
61 
62 #include <Teuchos_as.hpp>
63 #ifdef HAVE_TEUCHOS_COMPLEX
64 #include <Teuchos_SerializationTraits.hpp>
65 #endif
66 
67 #include "Amesos2_TypeMap.hpp"
68 
69 
70 /* The SuperLU comples headers file only need to be included if
71  complex has been enabled in Teuchos. In addition we only need to
72  define the conversion and printing functions if complex has been
73  enabled. */
74 namespace SLU {
75 
76 typedef int int_t;
77 
78 extern "C" {
79 
80 #undef __SUPERLU_SUPERMATRIX
81 #include "supermatrix.h" // for Dtype_t declaration
82 
83 #ifdef HAVE_TEUCHOS_COMPLEX
84 namespace C {
85 #undef __SUPERLU_SCOMPLEX
86 #undef SCOMPLEX_INCLUDE
87 #include "slu_scomplex.h" // single-precision complex data type definitions
88 }
89 
90 namespace Z {
91 #undef __SUPERLU_DCOMPLEX
92 #undef DCOMPLEX_INCLUDE
93 #include "slu_dcomplex.h" // double-precision complex data type definitions
94 }
95 #endif // HAVE_TEUCHOS_COMPLEX
96 
97 } // end extern "C"
98 
99  // Declare and specialize a std::binary_funtion class for
100  // multiplication of SuperLU types
101  template <typename slu_scalar_t, typename slu_mag_t>
102  struct slu_mult {};
103 
104  // This specialization handles the generic case were the scalar and
105  // magnitude types are double or float.
106  template <typename T>
107  struct slu_mult<T,T> : std::multiplies<T> {};
108 
109 #ifdef HAVE_TEUCHOS_COMPLEX
110 
111  // For namespace/macro reasons, we prefix our variables with amesos_*
112  template <>
113  struct slu_mult<C::complex,float>
114  : std::binary_function<C::complex,float,C::complex> {
115  C::complex operator()(C::complex amesos_c, float amesos_f) {
116  C::complex amesos_cr;
117  cs_mult(&amesos_cr, &amesos_c, amesos_f); // cs_mult is a macro, so no namespacing
118  return( amesos_cr );
119  }
120  };
121 
122  template <>
123  struct slu_mult<C::complex,C::complex>
124  : std::binary_function<C::complex,C::complex,C::complex> {
125  C::complex operator()(C::complex amesos_c1, C::complex amesos_c2) {
126  C::complex amesos_cr;
127  cc_mult(&amesos_cr, &amesos_c1, &amesos_c2); // cc_mult is a macro, so no namespacing
128  return( amesos_cr );
129  }
130  };
131 
132  template <>
133  struct slu_mult<Z::doublecomplex,double>
134  : std::binary_function<Z::doublecomplex,double,Z::doublecomplex> {
135  Z::doublecomplex operator()(Z::doublecomplex amesos_z, double amesos_d) {
136  Z::doublecomplex amesos_zr;
137  zd_mult(&amesos_zr, &amesos_z, amesos_d); // zd_mult is a macro, so no namespacing
138  return( amesos_zr );
139  }
140  };
141 
142  template <>
143  struct slu_mult<Z::doublecomplex,Z::doublecomplex>
144  : std::binary_function<Z::doublecomplex,Z::doublecomplex,Z::doublecomplex> {
145  Z::doublecomplex operator()(Z::doublecomplex amesos_z1, Z::doublecomplex amesos_z2) {
146  Z::doublecomplex amesos_zr;
147  zz_mult(&amesos_zr, &amesos_z1, &amesos_z2); // zz_mult is a macro, so no namespacing
148  return( amesos_zr );
149  }
150  };
151 
152 #endif // HAVE_TEUCHOS_COMPLEX
153 } // end namespace SLU
154 #ifdef HAVE_TEUCHOS_COMPLEX
155 
156 /* ==================== Conversion ==================== */
157 namespace Teuchos {
158 
170 template <>
171 class ValueTypeConversionTraits<SLU::C::complex, std::complex<float>>
172 {
173 public:
174  static SLU::C::complex convert( const std::complex<float> t )
175  {
176  SLU::C::complex ret;
177  ret.r = Teuchos::as<float>(t.real());
178  ret.i = Teuchos::as<float>(t.imag());
179  return( ret );
180  }
181 
182  static SLU::C::complex safeConvert( const std::complex<float> t )
183  {
184  SLU::C::complex ret;
185  ret.r = Teuchos::as<float>(t.real());
186  ret.i = Teuchos::as<float>(t.imag());
187  return( ret );
188  }
189 };
190 
191 template <>
192 class ValueTypeConversionTraits<SLU::C::complex, std::complex<double>>
193 {
194 public:
195  static SLU::C::complex convert( const std::complex<double> t )
196  {
197  SLU::C::complex ret;
198  ret.r = Teuchos::as<float>(t.real());
199  ret.i = Teuchos::as<float>(t.imag());
200  return( ret );
201  }
202 
203  static SLU::C::complex safeConvert( const std::complex<double> t )
204  {
205  SLU::C::complex ret;
206  ret.r = Teuchos::as<float>(t.real());
207  ret.i = Teuchos::as<float>(t.imag());
208  return( ret );
209  }
210 };
211 
212 
213 template <>
214 class ValueTypeConversionTraits<SLU::Z::doublecomplex, std::complex<float>>
215 {
216 public:
217  static SLU::Z::doublecomplex convert( const std::complex<float> t )
218  {
219  SLU::Z::doublecomplex ret;
220  ret.r = Teuchos::as<double>(t.real());
221  ret.i = Teuchos::as<double>(t.imag());
222  return( ret );
223  }
224 
225  static SLU::Z::doublecomplex safeConvert( const std::complex<float> t )
226  {
227  SLU::Z::doublecomplex ret;
228  ret.r = Teuchos::as<double>(t.real());
229  ret.i = Teuchos::as<double>(t.imag());
230  return( ret );
231  }
232 };
233 
234 template <>
235 class ValueTypeConversionTraits<SLU::Z::doublecomplex, std::complex<double>>
236 {
237 public:
238  static SLU::Z::doublecomplex convert( const std::complex<double> t )
239  {
240  SLU::Z::doublecomplex ret;
241  ret.r = Teuchos::as<double>(t.real());
242  ret.i = Teuchos::as<double>(t.imag());
243  return( ret );
244  }
245 
246  static SLU::Z::doublecomplex safeConvert( const std::complex<double> t )
247  {
248  SLU::Z::doublecomplex ret;
249  ret.r = Teuchos::as<double>(t.real());
250  ret.i = Teuchos::as<double>(t.imag());
251  return( ret );
252  }
253 };
254 
255 
256 // Also convert from SLU types
257 
258 template <>
259 class ValueTypeConversionTraits<std::complex<float>, SLU::C::complex>
260 {
261 public:
262  static std::complex<float> convert( const SLU::C::complex t )
263  {
264  typedef typename std::complex<float>::value_type value_type;
265  value_type ret_r = Teuchos::as<value_type>( t.r );
266  value_type ret_i = Teuchos::as<value_type>( t.i );
267  return ( std::complex<float>( ret_r, ret_i ) );
268  }
269 
270  // No special checks for safe Convert
271  static std::complex<float> safeConvert( const SLU::C::complex t )
272  {
273  typedef typename std::complex<float>::value_type value_type;
274  value_type ret_r = Teuchos::as<value_type>( t.r );
275  value_type ret_i = Teuchos::as<value_type>( t.i );
276  return ( std::complex<float>( ret_r, ret_i ) );
277  }
278 };
279 
280 template <>
281 class ValueTypeConversionTraits<std::complex<double>, SLU::C::complex>
282 {
283 public:
284  static std::complex<double> convert( const SLU::C::complex t )
285  {
286  typedef typename std::complex<double>::value_type value_type;
287  value_type ret_r = Teuchos::as<value_type>( t.r );
288  value_type ret_i = Teuchos::as<value_type>( t.i );
289  return ( std::complex<double>( ret_r, ret_i ) );
290  }
291 
292  // No special checks for safe Convert
293  static std::complex<double> safeConvert( const SLU::C::complex t )
294  {
295  typedef typename std::complex<double>::value_type value_type;
296  value_type ret_r = Teuchos::as<value_type>( t.r );
297  value_type ret_i = Teuchos::as<value_type>( t.i );
298  return ( std::complex<double>( ret_r, ret_i ) );
299  }
300 };
301 
302 
303 template <>
304 class ValueTypeConversionTraits<std::complex<float>, SLU::Z::doublecomplex>
305 {
306 public:
307  static std::complex<float> convert( const SLU::Z::doublecomplex t )
308  {
309  typedef typename std::complex<float>::value_type value_type;
310  value_type ret_r = Teuchos::as<value_type>( t.r );
311  value_type ret_i = Teuchos::as<value_type>( t.i );
312  return ( std::complex<float>( ret_r, ret_i ) );
313  }
314 
315  // No special checks for safe Convert
316  static std::complex<float> safeConvert( const SLU::Z::doublecomplex t )
317  {
318  typedef typename std::complex<float>::value_type value_type;
319  value_type ret_r = Teuchos::as<value_type>( t.r );
320  value_type ret_i = Teuchos::as<value_type>( t.i );
321  return ( std::complex<float>( ret_r, ret_i ) );
322  }
323 };
324 
325 template <>
326 class ValueTypeConversionTraits<std::complex<double>, SLU::Z::doublecomplex>
327 {
328 public:
329  static std::complex<double> convert( const SLU::Z::doublecomplex t )
330  {
331  typedef typename std::complex<double>::value_type value_type;
332  value_type ret_r = Teuchos::as<value_type>( t.r );
333  value_type ret_i = Teuchos::as<value_type>( t.i );
334  return ( std::complex<double>( ret_r, ret_i ) );
335  }
336 
337  // No special checks for safe Convert
338  static std::complex<double> safeConvert( const SLU::Z::doublecomplex t )
339  {
340  typedef typename std::complex<double>::value_type value_type;
341  value_type ret_r = Teuchos::as<value_type>( t.r );
342  value_type ret_i = Teuchos::as<value_type>( t.i );
343  return ( std::complex<double>( ret_r, ret_i ) );
344  }
345 };
346 
347 template <typename Ordinal>
348 class SerializationTraits<Ordinal,SLU::C::complex>
349  : public DirectSerializationTraits<Ordinal,SLU::C::complex>
350 {};
351 
352 template <typename Ordinal>
353 class SerializationTraits<Ordinal,SLU::Z::doublecomplex>
354  : public DirectSerializationTraits<Ordinal,SLU::Z::doublecomplex>
355 {};
356 
358 
359 } // end namespace Teuchos
360 
361 // C++-style output functions for Superlu complex types
362 namespace std {
363  ostream& operator<<(ostream& out, const SLU::Z::doublecomplex z);
364 
365  ostream& operator<<(ostream& out, const SLU::C::complex c);
366 }
367 
368 #endif // HAVE_TEUCHOS_COMPLEX
369 
370 
371 namespace Amesos2 {
372 
373 template <class, class> class Superlu;
374 
375 /* Specialize the Amesos2::TypeMap struct for Superlu types
376  *
377  * \cond Superlu_type_specializations
378  */
379 template <>
380 struct TypeMap<Superlu,float>
381 {
382  static SLU::Dtype_t dtype;
383  typedef float type;
384  typedef float magnitude_type;
385 };
386 
387 
388 template <>
389 struct TypeMap<Superlu,double>
390 {
391  static SLU::Dtype_t dtype;
392  typedef double type;
393  typedef double magnitude_type;
394 };
395 
396 
397 #ifdef HAVE_TEUCHOS_COMPLEX
398 
399 template <>
400 struct TypeMap<Superlu,std::complex<float> >
401 {
402  static SLU::Dtype_t dtype;
403  typedef SLU::C::complex type;
404  typedef float magnitude_type;
405 };
406 
407 
408 template <>
409 struct TypeMap<Superlu,std::complex<double> >
410 {
411  static SLU::Dtype_t dtype;
412  typedef SLU::Z::doublecomplex type;
413  typedef double magnitude_type;
414 };
415 
416 
417 template <>
418 struct TypeMap<Superlu,SLU::C::complex>
419 {
420  static SLU::Dtype_t dtype;
421  typedef SLU::C::complex type;
422  typedef float magnitude_type;
423 };
424 
425 
426 template <>
427 struct TypeMap<Superlu,SLU::Z::doublecomplex>
428 {
429  static SLU::Dtype_t dtype;
430  typedef SLU::Z::doublecomplex type;
431  typedef double magnitude_type;
432 };
433 
434 
435 #endif // HAVE_TEUCHOS_COMPLEX
436 
437 /* \endcond Superlu_type_specializations */
438 
439 
440 } // end namespace Amesos2
441 
442 #endif // AMESOS2_SUPERLU_TYPEMAP_HPP