Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Superludist_TypeMap.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Amesos2: Templated Direct Sparse Solver Package
4//
5// Copyright 2011 NTESS and the Amesos2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
23#ifndef AMESOS2_SUPERLUDIST_TYPEMAP_HPP
24#define AMESOS2_SUPERLUDIST_TYPEMAP_HPP
25
26//#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
27//#endif
28
29#include <functional>
30
31#include <Teuchos_as.hpp>
32#ifdef HAVE_TEUCHOS_COMPLEX
33#include <Teuchos_SerializationTraits.hpp>
34#endif
35
36#include "Amesos2_TypeMap.hpp"
37
38#ifdef KOKKOS_ENABLE_CUDA
39 #include <cublas_v2.h>
40 #include <cuda_runtime_api.h>
41#endif
42
43
44namespace SLUD {
45
46#if SUPERLU_DIST_MAJOR_VERSION > 4
47// SuperLU_Dist before major version 5 does not contain the config file
48#include "superlu_dist_config.h" // provides define for size 32 or 64 int_t
49#endif
50
52#define USER_FREE(addr) SLUD::superlu_free_dist(addr)
53
54 // undefine compiler guard in case we also have the sequential
55 // SuperLU enabled
56#undef __SUPERLU_SUPERMATRIX
57#include "superlu_defs.h"
58//
59
60#if SUPERLU_DIST_MAJOR_VERSION > 4
61 typedef superlu_dist_options_t amesos2_superlu_dist_options_t;
62 typedef superlu_dist_mem_usage_t amesos2_superlu_dist_mem_usage_t;
63#define AMESOS2_ENABLES_SUPERLUDIST_VERSION5_AND_HIGHER 1
64#else
65 typedef superlu_options_t amesos2_superlu_dist_options_t;
66 typedef mem_usage_t amesos2_superlu_dist_mem_usage_t;
67#endif
68
69
70 namespace D {
71#include "superlu_ddefs.h" // double-precision real definitions
72 }
73
74#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
75 namespace Z {
76#include "superlu_zdefs.h" // double-precision complex definitions
77 }
78#endif // HAVE_TEUCHOS_COMPLEX
79
80#undef EMPTY
81
82// multiplication of SLUD types
83template <typename slu_scalar_t, typename slu_mag_t>
84struct slu_dist_mult {};
85
86// This specialization handles the generic case were the scalar and
87// magnitude types are double or float.
88template <typename T>
89struct slu_dist_mult<T,T> : std::multiplies<T> {};
90
91// For namespace/macro reasons, we prefix our variables with amesos_*
92template <>
93struct slu_dist_mult<double,double>
94{
95 double operator()(double a, double b) {
96 return( a*b );
97 }
98};
99
100#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
101
102 template <>
103 struct slu_dist_mult<Z::doublecomplex,double>
104 {
105 Z::doublecomplex operator()(Z::doublecomplex amesos_z, double amesos_d) {
106 Z::doublecomplex amesos_zr;
107 zd_mult(&amesos_zr, &amesos_z, amesos_d); // zd_mult is a macro, so no namespacing
108 return( amesos_zr );
109 }
110 };
111
112 template <>
113 struct slu_dist_mult<Z::doublecomplex,Z::doublecomplex>
114 {
115 Z::doublecomplex operator()(Z::doublecomplex amesos_z1, Z::doublecomplex amesos_z2) {
116 Z::doublecomplex amesos_zr;
117 zz_mult(&amesos_zr, &amesos_z1, &amesos_z2); // zz_mult is a macro, so no namespacing
118 return( amesos_zr );
119 }
120 };
121#endif // HAVE_TEUCHOS_COMPLEX
122} // end namespace SLUD
123#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
124
125
126/* ==================== Conversion ==================== */
127namespace Teuchos {
128
139template <typename TypeFrom>
140class ValueTypeConversionTraits<SLUD::Z::doublecomplex, TypeFrom>
141{
142public:
143 static SLUD::Z::doublecomplex convert( const TypeFrom t )
144 {
145 SLUD::Z::doublecomplex ret;
146 ret.r = Teuchos::as<double>(t.real());
147 ret.i = Teuchos::as<double>(t.imag());
148 return( ret );
149 }
150
151 static SLUD::Z::doublecomplex safeConvert( const TypeFrom t )
152 {
153 SLUD::Z::doublecomplex ret;
154 ret.r = Teuchos::as<double>(t.real());
155 ret.i = Teuchos::as<double>(t.imag());
156 return( ret );
157 }
158};
159
160
161// Also convert from SLU types
162template <typename TypeTo>
163class ValueTypeConversionTraits<TypeTo, SLUD::Z::doublecomplex>
164{
165public:
166 static TypeTo convert( const SLUD::Z::doublecomplex t )
167 {
168 typedef typename TypeTo::value_type value_type;
169 value_type ret_r = Teuchos::as<value_type>( t.r );
170 value_type ret_i = Teuchos::as<value_type>( t.i );
171 return ( TypeTo( ret_r, ret_i ) );
172 }
173
174 // No special checks for safe Convert
175 static TypeTo safeConvert( const SLUD::Z::doublecomplex t )
176 {
177 typedef typename TypeTo::value_type value_type;
178 value_type ret_r = Teuchos::as<value_type>( t.r );
179 value_type ret_i = Teuchos::as<value_type>( t.i );
180 return ( TypeTo( ret_r, ret_i ) );
181 }
182};
183
184template <typename Ordinal>
185class SerializationTraits<Ordinal,SLUD::Z::doublecomplex>
186 : public DirectSerializationTraits<Ordinal,SLUD::Z::doublecomplex>
187{};
188
190
191} // end namespace Teuchos
192
193
194
200namespace std {
201 // C++-style output functions for Superludist complex types
202 ostream& operator<<(ostream& out, const SLUD::Z::doublecomplex z);
203
205}
206#endif // HAVE_TEUCHOS_COMPLEX
207
208
209
210namespace Amesos2 {
211
212template <class, class> class Superludist;
213
214/* Specialize the Amesos2::TypeMap struct for SuperLU_DIST types
215 *
216 * \cond Superludist_type_specializations
217 */
218template <>
219struct TypeMap<Superludist,double>
220{
221 static const SLUD::Dtype_t dtype = SLUD::SLU_D;
222 typedef double type;
223 typedef double magnitude_type;
224#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
225 typedef SLUD::D::dLUstruct_t LUstruct_t;
226 typedef SLUD::D::dSOLVEstruct_t SOLVEstruct_t;
227 typedef SLUD::D::dScalePermstruct_t ScalePermstruct_t;
228#else
229 typedef SLUD::D::LUstruct_t LUstruct_t;
230 typedef SLUD::D::SOLVEstruct_t SOLVEstruct_t;
231 typedef SLUD::ScalePermstruct_t ScalePermstruct_t;
232#endif
233};
234
235#if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
236template <>
237struct TypeMap<Superludist,std::complex<double> >
238{
239 static const SLUD::Dtype_t dtype = SLUD::SLU_Z;
240 typedef SLUD::Z::doublecomplex type;
241 typedef double magnitude_type;
242#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
243 typedef SLUD::Z::zLUstruct_t LUstruct_t;
244 typedef SLUD::Z::zSOLVEstruct_t SOLVEstruct_t;
245 typedef SLUD::Z::zScalePermstruct_t ScalePermstruct_t;
246#else
247 typedef SLUD::Z::LUstruct_t LUstruct_t;
248 typedef SLUD::Z::SOLVEstruct_t SOLVEstruct_t;
249 typedef SLUD::ScalePermstruct_t ScalePermstruct_t;
250#endif
251};
252
253 // It probably won't happen, but what if someone does create a
254 // matrix or multivector with the SuperLU_DIST doublecomplex type
255 // directly?
256template <>
257struct TypeMap<Superludist,SLUD::Z::doublecomplex>
258{
259 static const SLUD::Dtype_t dtype = SLUD::SLU_Z;
260 typedef SLUD::Z::doublecomplex type;
261 typedef double magnitude_type;
262#if SUPERLU_DIST_MAJOR_VERSION > 6 || (SUPERLU_DIST_MAJOR_VERSION == 6 && SUPERLU_DIST_MINOR_VERSION > 2)
263 typedef SLUD::Z::zLUstruct_t LUstruct_t;
264 typedef SLUD::Z::zSOLVEstruct_t SOLVEstruct_t;
265 typedef SLUD::Z::zScalePermstruct_t ScalePermstruct_t;
266#else
267 typedef SLUD::Z::LUstruct_t LUstruct_t;
268 typedef SLUD::Z::SOLVEstruct_t SOLVEstruct_t;
269 typedef SLUD::ScalePermstruct_t ScalePermstruct_t;
270#endif
271};
272
273#endif // HAVE_TEUCHOS_COMPLEX
274
275/* \endcond Superludist_type_specializations */
276
277
278} // end namespace Amesos2
279
280#endif // AMESOS2_SUPERLUDIST_TYPEMAP_HPP