Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_Superlumt_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_SUPERLUMT_TYPEMAP_HPP
55 #define AMESOS2_SUPERLUMT_TYPEMAP_HPP
56 
57 #include <functional>
58 
59 #include <Teuchos_as.hpp>
60 #ifdef HAVE_TEUCHOS_COMPLEX
61 #include <Teuchos_SerializationTraits.hpp>
62 #endif
63 
64 #include "Amesos2_TypeMap.hpp"
65 
66 namespace SLUMT {
67 
68 typedef int int_t;
69 
70 extern "C" {
71 
72 #undef __SUPERLU_SUPERMATRIX
73 #include "supermatrix.h" // for Dtype_t declaration
74 
75 #ifdef HAVE_TEUCHOS_COMPLEX
76 
77 namespace C {
78 #undef __SUPERLU_SCOMPLEX
79 #undef SCOMPLEX_INCLUDE
80 #include "slu_scomplex.h" // single-precision complex data type definitions
81 }
82 
83 namespace Z {
84 #undef __SUPERLU_DCOMPLEX
85 #undef DCOMPLEX_INCLUDE
86 #include "slu_dcomplex.h" // double-precision complex data type definitions
87 }
88 
89 #endif // HAVE_TEUCHOS_COMPLEX
90 
91 } // end extern "C"
92 
93  // Declare and specialize a std::binary_funtion class for
94  // multiplication of SLUMT types
95  template <typename slu_scalar_t, typename slu_mag_t>
96  struct slu_mt_mult {};
97 
98  // This specialization handles the generic case were the scalar and
99  // magnitude types are double or float.
100  template <typename T>
101  struct slu_mt_mult<T,T> : std::multiplies<T> {};
102 
103 #ifdef HAVE_TEUCHOS_COMPLEX
104 
105  // For namespace/macro reasons, we prefix our variables with amesos_*
106  template <>
107  struct slu_mt_mult<C::complex,float>
108  : std::binary_function<C::complex,float,C::complex> {
109  C::complex operator()(C::complex amesos_c, float amesos_f) {
110  C::complex amesos_cr;
111  cs_mult(&amesos_cr, &amesos_c, amesos_f); // cs_mult is a macro, so no namespacing
112  return( amesos_cr );
113  }
114  };
115 
116  template <>
117  struct slu_mt_mult<C::complex,C::complex>
118  : std::binary_function<C::complex,C::complex,C::complex> {
119  C::complex operator()(C::complex amesos_c1, C::complex amesos_c2) {
120  C::complex amesos_cr;
121  cc_mult(&amesos_cr, &amesos_c1, &amesos_c2); // cc_mult is a macro, so no namespacing
122  return( amesos_cr );
123  }
124  };
125 
126  template <>
127  struct slu_mt_mult<Z::doublecomplex,double>
128  : std::binary_function<Z::doublecomplex,double,Z::doublecomplex> {
129  Z::doublecomplex operator()(Z::doublecomplex amesos_z, double amesos_d) {
130  Z::doublecomplex amesos_zr;
131  zd_mult(&amesos_zr, &amesos_z, amesos_d); // zd_mult is a macro, so no namespacing
132  return( amesos_zr );
133  }
134  };
135 
136  template <>
137  struct slu_mt_mult<Z::doublecomplex,Z::doublecomplex>
138  : std::binary_function<Z::doublecomplex,Z::doublecomplex,Z::doublecomplex> {
139  Z::doublecomplex operator()(Z::doublecomplex amesos_z1, Z::doublecomplex amesos_z2) {
140  Z::doublecomplex amesos_zr;
141  zz_mult(&amesos_zr, &amesos_z1, &amesos_z2); // zz_mult is a macro, so no namespacing
142  return( amesos_zr );
143  }
144  };
145 
146 #endif // HAVE_TEUCHOS_COMPLEX
147 } // end namespace SLUMt
148 #ifdef HAVE_TEUCHOS_COMPLEX
149 
150 /* ==================== Conversion ==================== */
151 namespace Teuchos {
152 
163 template <typename TypeFrom>
164 class ValueTypeConversionTraits<SLUMT::C::complex, TypeFrom>
165 {
166 public:
167  static SLUMT::C::complex convert( const TypeFrom t )
168  {
169  SLUMT::C::complex ret;
170  ret.r = Teuchos::as<float>(t.real());
171  ret.i = Teuchos::as<float>(t.imag());
172  return( ret );
173  }
174 
175  static SLUMT::C::complex safeConvert( const TypeFrom t )
176  {
177  SLUMT::C::complex ret;
178  ret.r = Teuchos::as<float>(t.real());
179  ret.i = Teuchos::as<float>(t.imag());
180  return( ret );
181  }
182 };
183 
184 
185 template <typename TypeFrom>
186 class ValueTypeConversionTraits<SLUMT::Z::doublecomplex, TypeFrom>
187 {
188 public:
189  static SLUMT::Z::doublecomplex convert( const TypeFrom t )
190  {
191  SLUMT::Z::doublecomplex ret;
192  ret.r = Teuchos::as<double>(t.real());
193  ret.i = Teuchos::as<double>(t.imag());
194  return( ret );
195  }
196 
197  static SLUMT::Z::doublecomplex safeConvert( const TypeFrom t )
198  {
199  SLUMT::Z::doublecomplex ret;
200  ret.r = Teuchos::as<double>(t.real());
201  ret.i = Teuchos::as<double>(t.imag());
202  return( ret );
203  }
204 };
205 
206 
207 // Also convert from SLU types
208 template <typename TypeTo>
209 class ValueTypeConversionTraits<TypeTo, SLUMT::C::complex>
210 {
211 public:
212  static TypeTo convert( const SLUMT::C::complex t )
213  {
214  typedef typename TypeTo::value_type value_type;
215  value_type ret_r = Teuchos::as<value_type>( t.r );
216  value_type ret_i = Teuchos::as<value_type>( t.i );
217  return ( TypeTo( ret_r, ret_i ) );
218  }
219 
220  // No special checks for safe Convert
221  static TypeTo safeConvert( const SLUMT::C::complex t )
222  {
223  typedef typename TypeTo::value_type value_type;
224  value_type ret_r = Teuchos::as<value_type>( t.r );
225  value_type ret_i = Teuchos::as<value_type>( t.i );
226  return ( TypeTo( ret_r, ret_i ) );
227  }
228 };
229 
230 
231 template <typename TypeTo>
232 class ValueTypeConversionTraits<TypeTo, SLUMT::Z::doublecomplex>
233 {
234 public:
235  static TypeTo convert( const SLUMT::Z::doublecomplex t )
236  {
237  typedef typename TypeTo::value_type value_type;
238  value_type ret_r = Teuchos::as<value_type>( t.r );
239  value_type ret_i = Teuchos::as<value_type>( t.i );
240  return ( TypeTo( ret_r, ret_i ) );
241  }
242 
243  // No special checks for safe Convert
244  static TypeTo safeConvert( const SLUMT::Z::doublecomplex t )
245  {
246  typedef typename TypeTo::value_type value_type;
247  value_type ret_r = Teuchos::as<value_type>( t.r );
248  value_type ret_i = Teuchos::as<value_type>( t.i );
249  return ( TypeTo( ret_r, ret_i ) );
250  }
251 };
252 
253 template <typename Ordinal>
254 class SerializationTraits<Ordinal,SLUMT::C::complex>
255  : public DirectSerializationTraits<Ordinal,SLUMT::C::complex>
256 {};
257 
258 template <typename Ordinal>
259 class SerializationTraits<Ordinal,SLUMT::Z::doublecomplex>
260  : public DirectSerializationTraits<Ordinal,SLUMT::Z::doublecomplex>
261 {};
262 
264 
265 } // end namespace Teuchos
266 
267 
268 
274 namespace std {
275  // C++-style output functions for Superlumt complex types
276  ostream& operator<<(ostream& out, const SLUMT::C::complex c);
277 
278  ostream& operator<<(ostream& out, const SLUMT::Z::doublecomplex z);
279 
281 }
282 
283 #endif // HAVE_TEUCHOS_COMPLEX
284 
285 
286 namespace Amesos2 {
287 
288 template <class, class> class Superlumt;
289 
290 /* Specialize the Amesos2::TypeMap struct for Superlumt types
291  *
292  * \cond Superlumt_type_specializations
293  */
294 template <>
295 struct TypeMap<Superlumt,float>
296 {
297  static SLUMT::Dtype_t dtype;
298  typedef float type;
299  typedef float magnitude_type;
300 };
301 
302 
303 template <>
304 struct TypeMap<Superlumt,double>
305 {
306  static SLUMT::Dtype_t dtype;
307  typedef double type;
308  typedef double magnitude_type;
309 };
310 
311 
312 #ifdef HAVE_TEUCHOS_COMPLEX
313 template <>
314 struct TypeMap<Superlumt,std::complex<float> >
315 {
316  static SLUMT::Dtype_t dtype;
317  typedef SLUMT::C::complex type;
318  typedef float magnitude_type;
319 };
320 
321 
322 template <>
323 struct TypeMap<Superlumt,std::complex<double> >
324 {
325  static SLUMT::Dtype_t dtype;
326  typedef SLUMT::Z::doublecomplex type;
327  typedef double magnitude_type;
328 };
329 
330 
331 template <>
332 struct TypeMap<Superlumt,SLUMT::C::complex>
333 {
334  static SLUMT::Dtype_t dtype;
335  typedef SLUMT::C::complex type;
336  typedef float magnitude_type;
337 };
338 
339 
340 template <>
341 struct TypeMap<Superlumt,SLUMT::Z::doublecomplex>
342 {
343  static SLUMT::Dtype_t dtype;
344  typedef SLUMT::Z::doublecomplex type;
345  typedef double magnitude_type;
346 };
347 
348 #endif // HAVE_TEUCHOS_COMPLEX
349 
350 /* \endcond Superlumt_type_specializations */
351 
352 
353 } // end namespace Amesos2
354 
355 #endif // AMESOS2_SUPERLUMT_TYPEMAP_HPP