Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Superludist_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
57#ifndef AMESOS2_SUPERLUDIST_TYPEMAP_HPP
58#define AMESOS2_SUPERLUDIST_TYPEMAP_HPP
59
60//#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
61//#endif
62
63#include <functional>
64
65#include <Teuchos_as.hpp>
66#ifdef HAVE_TEUCHOS_COMPLEX
67#include <Teuchos_SerializationTraits.hpp>
68#endif
69
70#include "Amesos2_TypeMap.hpp"
71
72
73namespace SLUD {
74
75extern "C" {
76
77#if SUPERLU_DIST_MAJOR_VERSION > 4
78// SuperLU_Dist before major version 5 does not contain the config file
79#include "superlu_dist_config.h" // provides define for size 32 or 64 int_t
80#endif
81
83#define USER_FREE(addr) SLUD::superlu_free_dist(addr)
84
85 // undefine compiler guard in case we also have the sequential
86 // SuperLU enabled
87#undef __SUPERLU_SUPERMATRIX
88#include "superlu_defs.h"
89//
90
91#if SUPERLU_DIST_MAJOR_VERSION > 4
92 typedef superlu_dist_options_t amesos2_superlu_dist_options_t;
93 typedef superlu_dist_mem_usage_t amesos2_superlu_dist_mem_usage_t;
94#define AMESOS2_ENABLES_SUPERLUDIST_VERSION5_AND_HIGHER 1
95#else
96 typedef superlu_options_t amesos2_superlu_dist_options_t;
97 typedef mem_usage_t amesos2_superlu_dist_mem_usage_t;
98#endif
99
100
101 namespace D {
102#include "superlu_ddefs.h" // double-precision real definitions
103 }
104
105#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
106 namespace Z {
107#include "superlu_zdefs.h" // double-precision complex definitions
108 }
109#endif // HAVE_TEUCHOS_COMPLEX
110
111
112} // end extern "C"
113
114
115#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
116
117 // Declare and specialize a std::binary_funtion class for
118 // multiplication of SLUD types
119 template <typename slu_scalar_t, typename slu_mag_t>
120 struct slu_mt_mult {};
121
122 // This specialization handles the generic case were the scalar and
123 // magnitude types are double or float.
124 template <typename T>
125 struct slu_mt_mult<T,T> : std::multiplies<T> {};
126
127 // For namespace/macro reasons, we prefix our variables with amesos_*
128 template <>
129 struct slu_mt_mult<Z::doublecomplex,double>
130 : std::binary_function<Z::doublecomplex,double,Z::doublecomplex> {
131 Z::doublecomplex operator()(Z::doublecomplex amesos_z, double amesos_d) {
132 Z::doublecomplex amesos_zr;
133 zd_mult(&amesos_zr, &amesos_z, amesos_d); // zd_mult is a macro, so no namespacing
134 return( amesos_zr );
135 }
136 };
137
138 template <>
139 struct slu_mt_mult<Z::doublecomplex,Z::doublecomplex>
140 : std::binary_function<Z::doublecomplex,Z::doublecomplex,Z::doublecomplex> {
141 Z::doublecomplex operator()(Z::doublecomplex amesos_z1, Z::doublecomplex amesos_z2) {
142 Z::doublecomplex amesos_zr;
143 zz_mult(&amesos_zr, &amesos_z1, &amesos_z2); // zz_mult is a macro, so no namespacing
144 return( amesos_zr );
145 }
146 };
147#endif // HAVE_TEUCHOS_COMPLEX
148} // end namespace SLUD
149#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
150
151
152/* ==================== Conversion ==================== */
153namespace Teuchos {
154
165template <typename TypeFrom>
166class ValueTypeConversionTraits<SLUD::Z::doublecomplex, TypeFrom>
167{
168public:
169 static SLUD::Z::doublecomplex convert( const TypeFrom t )
170 {
171 SLUD::Z::doublecomplex ret;
172 ret.r = Teuchos::as<double>(t.real());
173 ret.i = Teuchos::as<double>(t.imag());
174 return( ret );
175 }
176
177 static SLUD::Z::doublecomplex safeConvert( const TypeFrom t )
178 {
179 SLUD::Z::doublecomplex ret;
180 ret.r = Teuchos::as<double>(t.real());
181 ret.i = Teuchos::as<double>(t.imag());
182 return( ret );
183 }
184};
185
186
187// Also convert from SLU types
188template <typename TypeTo>
189class ValueTypeConversionTraits<TypeTo, SLUD::Z::doublecomplex>
190{
191public:
192 static TypeTo convert( const SLUD::Z::doublecomplex t )
193 {
194 typedef typename TypeTo::value_type value_type;
195 value_type ret_r = Teuchos::as<value_type>( t.r );
196 value_type ret_i = Teuchos::as<value_type>( t.i );
197 return ( TypeTo( ret_r, ret_i ) );
198 }
199
200 // No special checks for safe Convert
201 static TypeTo safeConvert( const SLUD::Z::doublecomplex t )
202 {
203 typedef typename TypeTo::value_type value_type;
204 value_type ret_r = Teuchos::as<value_type>( t.r );
205 value_type ret_i = Teuchos::as<value_type>( t.i );
206 return ( TypeTo( ret_r, ret_i ) );
207 }
208};
209
210template <typename Ordinal>
211class SerializationTraits<Ordinal,SLUD::Z::doublecomplex>
212 : public DirectSerializationTraits<Ordinal,SLUD::Z::doublecomplex>
213{};
214
216
217} // end namespace Teuchos
218
219
220
226namespace std {
227 // C++-style output functions for Superludist complex types
228 ostream& operator<<(ostream& out, const SLUD::Z::doublecomplex z);
229
231}
232#endif // HAVE_TEUCHOS_COMPLEX
233
234
235
236namespace Amesos2 {
237
238template <class, class> class Superludist;
239
240/* Specialize the Amesos2::TypeMap struct for SuperLU_DIST types
241 *
242 * \cond Superludist_type_specializations
243 */
244template <>
245struct TypeMap<Superludist,double>
246{
247 static const SLUD::Dtype_t dtype = SLUD::SLU_D;
248 typedef double type;
249 typedef double magnitude_type;
250#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
251 typedef SLUD::D::dLUstruct_t LUstruct_t;
252 typedef SLUD::D::dSOLVEstruct_t SOLVEstruct_t;
253 typedef SLUD::D::dScalePermstruct_t ScalePermstruct_t;
254#else
255 typedef SLUD::D::LUstruct_t LUstruct_t;
256 typedef SLUD::D::SOLVEstruct_t SOLVEstruct_t;
257 typedef SLUD::ScalePermstruct_t ScalePermstruct_t;
258#endif
259};
260
261#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
262template <>
263struct TypeMap<Superludist,std::complex<double> >
264{
265 static const SLUD::Dtype_t dtype = SLUD::SLU_Z;
266 typedef SLUD::Z::doublecomplex type;
267 typedef double magnitude_type;
268#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
269 typedef SLUD::Z::zLUstruct_t LUstruct_t;
270 typedef SLUD::Z::zSOLVEstruct_t SOLVEstruct_t;
271 typedef SLUD::Z::zScalePermstruct_t ScalePermstruct_t;
272#else
273 typedef SLUD::Z::LUstruct_t LUstruct_t;
274 typedef SLUD::Z::SOLVEstruct_t SOLVEstruct_t;
275 typedef SLUD::ScalePermstruct_t ScalePermstruct_t;
276#endif
277};
278
279 // It probably won't happen, but what if someone does create a
280 // matrix or multivector with the SuperLU_DIST doublecomplex type
281 // directly?
282template <>
283struct TypeMap<Superludist,SLUD::Z::doublecomplex>
284{
285 static const SLUD::Dtype_t dtype = SLUD::SLU_Z;
286 typedef SLUD::Z::doublecomplex type;
287 typedef double magnitude_type;
288#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
289 typedef SLUD::Z::zLUstruct_t LUstruct_t;
290 typedef SLUD::Z::zSOLVEstruct_t SOLVEstruct_t;
291 typedef SLUD::Z::zScalePermstruct_t ScalePermstruct_t;
292#else
293 typedef SLUD::Z::LUstruct_t LUstruct_t;
294 typedef SLUD::Z::SOLVEstruct_t SOLVEstruct_t;
295 typedef SLUD::ScalePermstruct_t ScalePermstruct_t;
296#endif
297};
298
299#endif // HAVE_TEUCHOS_COMPLEX
300
301/* \endcond Superludist_type_specializations */
302
303
304} // end namespace Amesos2
305
306#endif // AMESOS2_SUPERLUDIST_TYPEMAP_HPP