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