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
66namespace SLUMT {
67
68typedef int int_t;
69
70extern "C" {
71
72#undef __SUPERLU_SUPERMATRIX
73#include "supermatrix.h" // for Dtype_t declaration
74
75#ifdef HAVE_TEUCHOS_COMPLEX
76
77namespace C {
78#undef __SUPERLU_SCOMPLEX
79#undef SCOMPLEX_INCLUDE
80#include "slu_scomplex.h" // single-precision complex data type definitions
81}
82
83namespace 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 ==================== */
151namespace Teuchos {
152
163template <typename TypeFrom>
164class ValueTypeConversionTraits<SLUMT::C::complex, TypeFrom>
165{
166public:
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
185template <typename TypeFrom>
186class ValueTypeConversionTraits<SLUMT::Z::doublecomplex, TypeFrom>
187{
188public:
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
208template <typename TypeTo>
209class ValueTypeConversionTraits<TypeTo, SLUMT::C::complex>
210{
211public:
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
231template <typename TypeTo>
232class ValueTypeConversionTraits<TypeTo, SLUMT::Z::doublecomplex>
233{
234public:
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
253template <typename Ordinal>
254class SerializationTraits<Ordinal,SLUMT::C::complex>
255 : public DirectSerializationTraits<Ordinal,SLUMT::C::complex>
256{};
257
258template <typename Ordinal>
259class SerializationTraits<Ordinal,SLUMT::Z::doublecomplex>
260 : public DirectSerializationTraits<Ordinal,SLUMT::Z::doublecomplex>
261{};
262
264
265} // end namespace Teuchos
266
267
268
274namespace 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
286namespace Amesos2 {
287
288template <class, class> class Superlumt;
289
290/* Specialize the Amesos2::TypeMap struct for Superlumt types
291 *
292 * \cond Superlumt_type_specializations
293 */
294template <>
295struct TypeMap<Superlumt,float>
296{
297 static SLUMT::Dtype_t dtype;
298 typedef float type;
299 typedef float magnitude_type;
300};
301
302
303template <>
304struct 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
313template <>
314struct 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
322template <>
323struct 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
331template <>
332struct 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
340template <>
341struct 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