Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Kokkos_ArithTraits.hpp
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //   Kokkos: Manycore Performance-Portable Multidimensional Arrays
00006 //              Copyright (2012) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 */
00043 
00044 #ifndef KOKKOS_ARITHTRAITS_HPP
00045 #define KOKKOS_ARITHTRAITS_HPP
00046 
00052 
00053 #include <cfloat>
00054 #include <climits>
00055 #include <cmath>
00056 #include <cstdlib> // strtof, strtod, strtold
00057 #include <complex> // std::complex
00058 #include <limits> // std::numeric_limits
00059 #ifdef __CUDACC__
00060 #include <math_constants.h>
00061 #endif
00062 //
00063 // mfh 24 Dec 2013: Temporary measure for testing; will go away.
00064 //
00065 #ifndef KOKKOS_FORCEINLINE_FUNCTION
00066 #  ifdef __CUDA_ARCH__
00067 #    define KOKKOS_FORCEINLINE_FUNCTION inline __host__ __device__
00068 #  else
00069 #    define KOKKOS_FORCEINLINE_FUNCTION
00070 #  endif // __CUDA_ARCH__
00071 #endif // KOKKOS_FORCEINLINE_FUNCTION
00072 
00073 namespace { // anonymous
00074 
00083 template<class IntType>
00084 KOKKOS_FORCEINLINE_FUNCTION IntType
00085 intPowImpl (const IntType x, const IntType y)
00086 {
00087   // Recursion (unrolled into while loop): pow(x, 2y) = (x^y)^2
00088   IntType prod = x;
00089   IntType y_cur = 1;
00090   // If y == 1, then prod stays x.
00091   while (y_cur < y) {
00092     prod = prod * prod;
00093     y_cur = y_cur << 1;
00094   }
00095   // abs(y - y_cur) < floor(log2(y)), so it won't hurt asymptotic run
00096   // time to finish the remainder in a linear iteration.
00097   if (y > y_cur) {
00098     const IntType left = y - y_cur;
00099     for (IntType k = 0; k < left; ++k) {
00100       prod = prod * x;
00101     }
00102   }
00103   else if (y < y_cur) {
00104     // There's probably a better way to do this in order to avoid the
00105     // (expensive) integer division, but I'm not motivated to think of
00106     // it at the moment.
00107     const IntType left = y_cur - y;
00108     for (IntType k = 0; k < left; ++k) {
00109       prod = prod / x;
00110     }
00111   }
00112   return prod;
00113 
00114   // y = 8:
00115   //
00116   // x,1   -> x^2,2
00117   // x^2,2 -> x^4,4
00118   // x^4,4 -> x^8,8
00119   //
00120   // y = 9:
00121   //
00122   // x,1   -> x^2,2
00123   // x^2,2 -> x^4,4
00124   // x^4,4 -> x^8,8
00125   //
00126   // y - y_cur is what's left over.  Just do it one at a time.
00127   //
00128   // y = 3:
00129   // x,1   -> x^2,2
00130   // x^2,2 -> x^4,4
00131 }
00132 
00133 
00134 
00142 template<class IntType>
00143 KOKKOS_FORCEINLINE_FUNCTION IntType
00144 intPowSigned (const IntType x, const IntType y)
00145 {
00146   // It's not entirely clear what to return if x and y are both zero.
00147   // In the case of floating-point numbers, 0^0 is NaN.  Here, though,
00148   // I think it's safe to return 0.
00149   if (x == 0) {
00150     return 0;
00151   } else if (y == 0) {
00152     return 1;
00153   } else if (y < 0) {
00154     if (x == 1) {
00155       return 1;
00156     }
00157     else if (x == -1) {
00158       return (y % 2 == 0) ? 1 : -1;
00159     }
00160     else {
00161       return 0; // round the fraction to zero
00162     }
00163   } else {
00164     return intPowImpl<IntType> (x, y);
00165   }
00166 }
00167 
00175 template<class IntType>
00176 KOKKOS_FORCEINLINE_FUNCTION IntType
00177 intPowUnsigned (const IntType x, const IntType y)
00178 {
00179   // It's not entirely clear what to return if x and y are both zero.
00180   // In the case of floating-point numbers, 0^0 is NaN.  Here, though,
00181   // I think it's safe to return 0.
00182   if (x == 0) {
00183     return 0;
00184   } else if (y == 0) {
00185     return 1;
00186   } else {
00187     return intPowImpl<IntType> (x, y);
00188   }
00189 }
00190 
00191 // It might make sense to use special sqrt() approximations for
00192 // integer arguments, like those presented on the following web site:
00193 //
00194 // http://www.azillionmonkeys.com/qed/sqroot.html#implementations
00195 //
00196 // Note that some of the implementations on the above page break ANSI
00197 // C(++) aliasing rules (by assigning to the results of
00198 // reinterpret_cast-ing between int and float).  It's also just a
00199 // performance optimization and not required for a reasonable
00200 // implementation.
00201 
00202 } // namespace (anonymous)
00203 
00204 namespace Kokkos {
00205 namespace Details {
00206 
00325 template<class T>
00326 class ArithTraits {
00327 public:
00329   typedef T val_type;
00336   typedef T mag_type;
00337 
00339   static const bool is_specialized = false;
00341   static const bool is_signed = false;
00343   static const bool is_integer = false;
00348   static const bool is_exact = false;
00350   static const bool is_complex = false;
00351 
00361   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const T& x);
00362 
00372   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const T& x);
00373 
00375   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const T& x);
00376 
00378   static KOKKOS_FORCEINLINE_FUNCTION T zero ();
00379 
00381   static KOKKOS_FORCEINLINE_FUNCTION T one ();
00382 
00387   static KOKKOS_FORCEINLINE_FUNCTION T min ();
00388 
00390   static KOKKOS_FORCEINLINE_FUNCTION T max ();
00391 
00395   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const T& x);
00396 
00400   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const T&);
00401 
00405   static KOKKOS_FORCEINLINE_FUNCTION T conj (const T&);
00406 
00408   static KOKKOS_FORCEINLINE_FUNCTION T pow (const T& x, const T& y);
00409 
00421   static KOKKOS_FORCEINLINE_FUNCTION T sqrt (const T& x);
00422 
00434   static KOKKOS_FORCEINLINE_FUNCTION T log (const T& x);
00435 
00447   static KOKKOS_FORCEINLINE_FUNCTION T log10 (const T& x);
00448 
00453   static KOKKOS_FORCEINLINE_FUNCTION T nan ();
00454 
00460   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon ();
00461 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00474   typedef T magnitudeType;
00475 
00479   typedef T halfPrecision;
00480 
00484   typedef T doublePrecision;
00485 
00486   static const bool isComplex = false;
00487   static const bool isOrdinal = false;
00488   static const bool isComparable = false;
00489 
00496   static const bool hasMachineParameters = false;
00497 
00499   static KOKKOS_FORCEINLINE_FUNCTION mag_type eps ();
00500 
00502   static KOKKOS_FORCEINLINE_FUNCTION mag_type sfmin ();
00503 
00505   static KOKKOS_FORCEINLINE_FUNCTION int base ();
00506 
00508   static KOKKOS_FORCEINLINE_FUNCTION mag_type prec ();
00509 
00511   static KOKKOS_FORCEINLINE_FUNCTION int t ();
00512 
00514   static KOKKOS_FORCEINLINE_FUNCTION mag_type rnd ();
00515 
00517   static KOKKOS_FORCEINLINE_FUNCTION int emin ();
00518 
00520   static KOKKOS_FORCEINLINE_FUNCTION mag_type rmin ();
00521 
00523   static KOKKOS_FORCEINLINE_FUNCTION int emax ();
00524 
00526   static KOKKOS_FORCEINLINE_FUNCTION mag_type rmax ();
00527 
00529   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const T& x);
00530 
00532   static KOKKOS_FORCEINLINE_FUNCTION T conjugate (const T& x);
00533 
00537   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const T& x);
00538 
00542   static std::string name ();
00543 
00545   static KOKKOS_FORCEINLINE_FUNCTION T squareroot (const T& x);
00547 };
00548 
00549 
00550 template<>
00551 class ArithTraits<float> {
00552 public:
00553   typedef float val_type;
00554   typedef val_type mag_type;
00555 
00556   static const bool is_specialized = true;
00557   static const bool is_signed = true;
00558   static const bool is_integer = false;
00559   static const bool is_exact = false;
00560   static const bool is_complex = false;
00561 
00562   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const float x) {
00563 #ifdef __APPLE__
00564     return std::isinf (x);
00565 #else
00566     return isinf (x);
00567 #endif // __APPLE__
00568   }
00569   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const float x) {
00570 #ifdef __APPLE__
00571     return std::isnan (x);
00572 #else
00573     return isnan (x);
00574 #endif // __APPLE__
00575   }
00576   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const float x) {
00577     return ::fabs (x);
00578   }
00579   static KOKKOS_FORCEINLINE_FUNCTION float zero () {
00580     return 0.0;
00581   }
00582   static KOKKOS_FORCEINLINE_FUNCTION float one () {
00583     return 1.0;
00584   }
00585   static KOKKOS_FORCEINLINE_FUNCTION float min () {
00586     return FLT_MIN;
00587   }
00588   static KOKKOS_FORCEINLINE_FUNCTION float max () {
00589     return FLT_MAX;
00590   }
00591   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const float x) {
00592     return x;
00593   }
00594   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const float) {
00595     return 0.0;
00596   }
00597   static KOKKOS_FORCEINLINE_FUNCTION float conj (const float x) {
00598     return x;
00599   }
00600   static KOKKOS_FORCEINLINE_FUNCTION float pow (const float x, const float y) {
00601     return ::pow (x, y);
00602   }
00603   static KOKKOS_FORCEINLINE_FUNCTION float sqrt (const float x) {
00604     return ::sqrt (x);
00605   }
00606   static KOKKOS_FORCEINLINE_FUNCTION float log (const float x) {
00607     return ::log (x);
00608   }
00609   static KOKKOS_FORCEINLINE_FUNCTION float log10 (const float x) {
00610     return ::log10 (x);
00611   }
00612   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
00613     return FLT_EPSILON;
00614   }
00615 
00616   // Backwards compatibility with Teuchos::ScalarTraits.
00617   typedef mag_type magnitudeType;
00618   // C++ doesn't have a standard "half-float" type.
00619   typedef float halfPrecision;
00620   typedef double doublePrecision;
00621 
00622   static const bool isComplex = false;
00623   static const bool isOrdinal = false;
00624   static const bool isComparable = true;
00625   static const bool hasMachineParameters = true;
00626   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const float x) {
00627     return isNan (x) || isInf (x);
00628   }
00629   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const float x) {
00630     return abs (x);
00631   }
00632   static KOKKOS_FORCEINLINE_FUNCTION float conjugate (const float x) {
00633     return conj (x);
00634   }
00635   static std::string name () {
00636     return "float";
00637   }
00638   static KOKKOS_FORCEINLINE_FUNCTION float squareroot (const float x) {
00639     return sqrt (x);
00640   }
00641   static KOKKOS_FORCEINLINE_FUNCTION float nan () {
00642 #ifdef __CUDA_ARCH__
00643     return CUDART_NAN_F;
00644     //return nan (); //this returns 0???
00645 #else
00646     // http://pubs.opengroup.org/onlinepubs/009696899/functions/nan.html
00647     return strtof ("NAN()", (char**) NULL);
00648 #endif // __CUDA_ARCH__
00649   }
00650   static KOKKOS_FORCEINLINE_FUNCTION mag_type eps () {
00651     return epsilon ();
00652   }
00653   static KOKKOS_FORCEINLINE_FUNCTION mag_type sfmin () {
00654     return FLT_MIN; // ???
00655   }
00656   static KOKKOS_FORCEINLINE_FUNCTION int base () {
00657     return FLT_RADIX;
00658   }
00659   static KOKKOS_FORCEINLINE_FUNCTION mag_type prec () {
00660     return eps () * static_cast<mag_type> (base ());
00661   }
00662   static KOKKOS_FORCEINLINE_FUNCTION int t () {
00663     return FLT_MANT_DIG;
00664   }
00665   static KOKKOS_FORCEINLINE_FUNCTION mag_type rnd () {
00666     return 1.0;
00667   }
00668   static KOKKOS_FORCEINLINE_FUNCTION int emin () {
00669     return FLT_MIN_EXP;
00670   }
00671   static KOKKOS_FORCEINLINE_FUNCTION mag_type rmin () {
00672     return FLT_MIN; // ??? // should be base^(emin-1)
00673   }
00674   static KOKKOS_FORCEINLINE_FUNCTION int emax () {
00675     return FLT_MAX_EXP;
00676   }
00677   static KOKKOS_FORCEINLINE_FUNCTION mag_type rmax () {
00678     return FLT_MAX; // ??? // should be (base^emax)*(1-eps)
00679   }
00680 };
00681 
00682 
00683 // The C++ Standard Library (with C++03 at least) only allows
00684 // std::complex<T> for T = float, double, or long double.
00685 template<class RealFloatType>
00686 class ArithTraits<std::complex<RealFloatType> > {
00687 public:
00688   typedef std::complex<RealFloatType> val_type;
00689   typedef RealFloatType mag_type;
00690 
00691   static const bool is_specialized = true;
00692   static const bool is_signed = true;
00693   static const bool is_integer = false;
00694   static const bool is_exact = false;
00695   static const bool is_complex = true;
00696 
00697   static bool isInf (const val_type& x) {
00698 #if defined(__CUDACC__) || defined(_CRAYC)
00699     return isinf (real (x)) || isinf (imag (x));
00700 #else
00701     return std::isinf (real (x)) || std::isinf (imag (x));
00702 #endif // __CUDACC__
00703   }
00704   static bool isNan (const val_type& x) {
00705 #if defined(__CUDACC__) || defined(_CRAYC)
00706     return isnan (real (x)) || isnan (imag (x));
00707 #else
00708     return std::isnan (real (x)) || std::isnan (imag (x));
00709 #endif // __CUDACC__
00710   }
00711   static mag_type abs (const val_type& x) {
00712     return std::abs (x);
00713   }
00714   static val_type zero () {
00715     return val_type (ArithTraits<mag_type>::zero (), ArithTraits<mag_type>::zero ());
00716   }
00717   static val_type one () {
00718     return val_type (ArithTraits<mag_type>::one (), ArithTraits<mag_type>::zero ());
00719   }
00720   static val_type min () {
00721     return val_type (ArithTraits<mag_type>::min (), ArithTraits<mag_type>::zero ());
00722   }
00723   static val_type max () {
00724     return val_type (ArithTraits<mag_type>::max (), ArithTraits<mag_type>::zero ());
00725   }
00726   static mag_type real (const val_type& x) {
00727     return std::real (x);
00728   }
00729   static mag_type imag (const val_type& x) {
00730     return std::imag (x);
00731   }
00732   static val_type conj (const val_type& x) {
00733     return std::conj (x);
00734   }
00735   static val_type
00736   pow (const val_type& x, const val_type& y) {
00737     // Fix for some weird gcc 4.2.1 inaccuracy.
00738     if (y == one ()) {
00739       return x;
00740     } else if (y == one () + one ()) {
00741       return x * x;
00742     } else {
00743       return std::pow (x, y);
00744     }
00745   }
00746   static val_type sqrt (const val_type& x) {
00747     return std::sqrt (x);
00748   }
00749   static val_type log (const val_type& x) {
00750     return std::log (x);
00751   }
00752   static val_type log10 (const val_type& x) {
00753     return std::log10 (x);
00754   }
00755   static val_type nan () {
00756     const mag_type mag_nan = ArithTraits<mag_type>::nan ();
00757     return val_type (mag_nan, mag_nan);
00758   }
00759   static mag_type epsilon () {
00760     return ArithTraits<mag_type>::epsilon ();
00761   }
00762 
00763   // Backwards compatibility with Teuchos::ScalarTraits.
00764   typedef mag_type magnitudeType;
00765   typedef std::complex<typename ArithTraits<mag_type>::halfPrecision> halfPrecision;
00766   typedef std::complex<typename ArithTraits<mag_type>::doublePrecision> doublePrecision;
00767 
00768   static const bool isComplex = true;
00769   static const bool isOrdinal = false;
00770   static const bool isComparable = false;
00771   static const bool hasMachineParameters = true;
00772   static bool isnaninf (const val_type& x) {
00773     return isNan (x) || isInf (x);
00774   }
00775   static mag_type magnitude (const val_type& x) {
00776     return abs (x);
00777   }
00778   static val_type conjugate (const val_type& x) {
00779     return conj (x);
00780   }
00781   static std::string name () {
00782     return std::string ("std::complex<") + ArithTraits<mag_type>::name () + ">";
00783   }
00784   static val_type squareroot (const val_type& x) {
00785     return sqrt (x);
00786   }
00787   static mag_type eps () {
00788     return epsilon ();
00789   }
00790   static mag_type sfmin () {
00791     return ArithTraits<mag_type>::sfmin ();
00792   }
00793   static int base () {
00794     return ArithTraits<mag_type>::base ();
00795   }
00796   static mag_type prec () {
00797     return ArithTraits<mag_type>::prec ();
00798   }
00799   static int t () {
00800     return ArithTraits<mag_type>::t ();
00801   }
00802   static mag_type rnd () {
00803     return ArithTraits<mag_type>::one ();
00804   }
00805   static int emin () {
00806     return ArithTraits<mag_type>::emin ();
00807   }
00808   static mag_type rmin () {
00809     return ArithTraits<mag_type>::rmin ();
00810   }
00811   static int emax () {
00812     return ArithTraits<mag_type>::emax ();
00813   }
00814   static mag_type rmax () {
00815     return ArithTraits<mag_type>::rmax ();
00816   }
00817 };
00818 
00819 
00820 template<>
00821 class ArithTraits<double> {
00822 public:
00823   typedef double val_type;
00824   typedef val_type mag_type;
00825 
00826   static const bool is_specialized = true;
00827   static const bool is_signed = true;
00828   static const bool is_integer = false;
00829   static const bool is_exact = false;
00830   static const bool is_complex = false;
00831 
00832   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
00833 #ifdef __APPLE__
00834     return std::isinf (x);
00835 #else
00836     return isinf (x);
00837 #endif // __APPLE__
00838   }
00839   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
00840 #ifdef __APPLE__
00841     return std::isnan (x);
00842 #else
00843     return isnan (x);
00844 #endif // __APPLE__
00845   }
00846   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
00847     return ::fabs (x);
00848   }
00849   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
00850     return 0.0;
00851   }
00852   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
00853     return 1.0;
00854   }
00855   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
00856     return DBL_MIN;
00857   }
00858   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
00859     return DBL_MAX;
00860   }
00861   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
00862     return x;
00863   }
00864   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type) {
00865     return 0.0;
00866   }
00867   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
00868     return x;
00869   }
00870   static KOKKOS_FORCEINLINE_FUNCTION val_type pow (const val_type x, const val_type y) {
00871     return ::pow (x, y);
00872   }
00873   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
00874     return ::sqrt (x);
00875   }
00876   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
00877     return ::log (x);
00878   }
00879   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
00880     return ::log10 (x);
00881   }
00882   static KOKKOS_FORCEINLINE_FUNCTION val_type nan () {
00883 #ifdef __CUDA_ARCH__
00884     return CUDART_NAN;
00885     //return nan (); // this returns 0 ???
00886 #else
00887     // http://pubs.opengroup.org/onlinepubs/009696899/functions/nan.html
00888     return strtod ("NAN", (char**) NULL);
00889 #endif // __CUDA_ARCH__
00890   }
00891   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
00892     return DBL_EPSILON;
00893   }
00894 
00895   // Backwards compatibility with Teuchos::ScalarTraits.
00896   typedef mag_type magnitudeType;
00897   typedef float halfPrecision;
00898 #ifdef __CUDA_ARCH__
00899   typedef double doublePrecision; // CUDA doesn't support long double, unfortunately
00900 #else
00901   typedef long double doublePrecision;
00902 #endif // __CUDA_ARCH__
00903   static const bool isComplex = false;
00904   static const bool isOrdinal = false;
00905   static const bool isComparable = true;
00906   static const bool hasMachineParameters = true;
00907   static bool isnaninf (const val_type& x) {
00908     return isNan (x) || isInf (x);
00909   }
00910   static KOKKOS_FORCEINLINE_FUNCTION mag_type magnitude (const val_type x) {
00911     return abs (x);
00912   }
00913   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
00914     return conj (x);
00915   }
00916   static std::string name () {
00917     return "double";
00918   }
00919   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
00920     return sqrt (x);
00921   }
00922   static KOKKOS_FORCEINLINE_FUNCTION mag_type eps () {
00923     return epsilon ();
00924   }
00925   static KOKKOS_FORCEINLINE_FUNCTION mag_type sfmin () {
00926     return DBL_MIN; // ???
00927   }
00928   static KOKKOS_FORCEINLINE_FUNCTION int base () {
00929     return FLT_RADIX; // same for float as for double
00930   }
00931   static KOKKOS_FORCEINLINE_FUNCTION mag_type prec () {
00932     return eps () * static_cast<mag_type> (base ());
00933   }
00934   static KOKKOS_FORCEINLINE_FUNCTION int t () {
00935     return DBL_MANT_DIG;
00936   }
00937   static KOKKOS_FORCEINLINE_FUNCTION mag_type rnd () {
00938     return 1.0;
00939   }
00940   static KOKKOS_FORCEINLINE_FUNCTION int emin () {
00941     return DBL_MIN_EXP;
00942   }
00943   static KOKKOS_FORCEINLINE_FUNCTION mag_type rmin () {
00944     return DBL_MIN; // ??? // should be base^(emin-1)
00945   }
00946   static KOKKOS_FORCEINLINE_FUNCTION int emax () {
00947     return DBL_MAX_EXP;
00948   }
00949   static KOKKOS_FORCEINLINE_FUNCTION mag_type rmax () {
00950     return DBL_MAX; // ??? // should be (base^emax)*(1-eps)
00951   }
00952 };
00953 
00954 
00955 // CUDA does not support long double in device functions, so none of
00956 // the class methods in this specialization are marked as device
00957 // functions.
00958 template<>
00959 class ArithTraits<long double> {
00960 public:
00961   typedef long double val_type;
00962   typedef long double mag_type;
00963 
00964   static const bool is_specialized = true;
00965   static const bool is_signed = true;
00966   static const bool is_integer = false;
00967   static const bool is_exact = false;
00968   static const bool is_complex = false;
00969 
00970   static bool isInf (const val_type& x) {
00971 #if defined(__CUDACC__) || defined(_CRAYC)
00972     return isinf (x);
00973 #else
00974     return std::isinf (x);
00975 #endif // __CUDACC__
00976   }
00977   static bool isNan (const val_type& x) {
00978 #if defined(__CUDACC__) || defined(_CRAYC)
00979     return isnan (x);
00980 #else
00981     return std::isnan (x);
00982 #endif // __CUDACC__
00983   }
00984   static mag_type abs (const val_type& x) {
00985     return ::fabs (x);
00986   }
00987   static val_type zero () {
00988     return 0.0;
00989   }
00990   static val_type one () {
00991     return 1.0;
00992   }
00993   static val_type min () {
00994     return LDBL_MIN;
00995   }
00996   static val_type max () {
00997     return LDBL_MAX;
00998   }
00999   static mag_type real (const val_type& x) {
01000     return x;
01001   }
01002   static mag_type imag (const val_type&) {
01003     return zero ();
01004   }
01005   static val_type conj (const val_type& x) {
01006     return x;
01007   }
01008   static val_type pow (const val_type& x, const val_type& y) {
01009     return ::pow (x, y);
01010   }
01011   static val_type sqrt (const val_type& x) {
01012     return ::sqrt (x);
01013   }
01014   static val_type log (const val_type& x) {
01015     return ::log (x);
01016   }
01017   static val_type log10 (const val_type& x) {
01018     return ::log10 (x);
01019   }
01020   static val_type nan () {
01021     return strtold ("NAN()", (char**) NULL);
01022   }
01023   static mag_type epsilon () {
01024     return LDBL_EPSILON;
01025   }
01026 
01027   // Backwards compatibility with Teuchos::ScalarTraits.
01028   typedef mag_type magnitudeType;
01029   typedef double halfPrecision;
01030   // It might be appropriate to use QD's qd_real here.
01031   // For now, long double is the most you get.
01032   typedef val_type doublePrecision;
01033 
01034   static const bool isComplex = false;
01035   static const bool isOrdinal = false;
01036   static const bool isComparable = true;
01037   static const bool hasMachineParameters = true;
01038   static bool isnaninf (const val_type& x) {
01039     return isNan (x) || isInf (x);
01040   }
01041   static mag_type magnitude (const val_type& x) {
01042     return abs (x);
01043   }
01044   static val_type conjugate (const val_type& x) {
01045     return conj (x);
01046   }
01047   static std::string name () {
01048     return "long double";
01049   }
01050   static val_type squareroot (const val_type& x) {
01051     return sqrt (x);
01052   }
01053   static mag_type eps () {
01054     return epsilon ();
01055   }
01056   static mag_type sfmin () {
01057     return LDBL_MIN; // ???
01058   }
01059   static int base () {
01060     return FLT_RADIX; // same for float as for double or long double
01061   }
01062   static mag_type prec () {
01063     return eps () * static_cast<mag_type> (base ());
01064   }
01065   static int t () {
01066     return LDBL_MANT_DIG;
01067   }
01068   static mag_type rnd () {
01069     return one ();
01070   }
01071   static int emin () {
01072     return LDBL_MIN_EXP;
01073   }
01074   static mag_type rmin () {
01075     return LDBL_MIN;
01076   }
01077   static int emax () {
01078     return LDBL_MAX_EXP;
01079   }
01080   static mag_type rmax () {
01081     return LDBL_MAX;
01082   }
01083 };
01084 
01085 
01086 template<>
01087 class ArithTraits<char> {
01088 public:
01089   typedef char val_type;
01090   typedef val_type mag_type;
01091 
01092   static const bool is_specialized = true;
01093   // The C(++) standard does not require that char be signed.  In
01094   // fact, signed char, unsigned char, and char are distinct types.
01095   // We can use std::numeric_limits here because it's a const bool,
01096   // not a class method.
01097   static const bool is_signed = std::numeric_limits<char>::is_signed;
01098   static const bool is_integer = true;
01099   static const bool is_exact = true;
01100   static const bool is_complex = false;
01101 
01102   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01103     return false;
01104   }
01105   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01106     return false;
01107   }
01108   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01109     // This may trigger a compiler warning if char is unsigned.  On
01110     // all platforms I have encountered, char is signed, but the C(++)
01111     // standard does not require this.
01112     return x >= 0 ? x : -x;
01113   }
01114   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01115     return 0;
01116   }
01117   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01118     return 1;
01119   }
01120   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01121     return CHAR_MIN;
01122   }
01123   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01124     return CHAR_MAX;
01125   }
01126   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01127     return x;
01128   }
01129   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01130     return 0;
01131   }
01132   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01133     return x;
01134   }
01135   static KOKKOS_FORCEINLINE_FUNCTION val_type
01136   pow (const val_type x, const val_type y) {
01137     if (is_signed) {
01138       return intPowSigned<val_type> (x, y);
01139     } else {
01140       return intPowUnsigned<val_type> (x, y);
01141     }
01142   }
01143   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01144     // C++11 defines std::sqrt for integer arguments.  However, we
01145     // currently can't assume C++11.
01146     //
01147     // This cast will result in no loss of accuracy, though it might
01148     // be more expensive than it should, if we were clever about using
01149     // bit operations.
01150     //
01151     // We take the absolute value first to avoid negative arguments.
01152     // Negative real arguments to sqrt(float) return (float) NaN, but
01153     // built-in integer types do not have an equivalent to NaN.
01154     // Casting NaN to an integer type will thus result in some integer
01155     // value which appears valid, but is not.  We cannot raise an
01156     // exception in device functions.  Thus, we prefer to take the
01157     // absolute value of x first, to avoid issues.  Another
01158     // possibility would be to test for a NaN output and convert it to
01159     // some reasonable value (like 0), though this might be more
01160     // expensive than the absolute value interpreted using the ternary
01161     // operator.
01162     return static_cast<val_type> ( ::sqrt (static_cast<float> (abs (x))));
01163   }
01164   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01165     return static_cast<val_type> ( ::log (static_cast<float> (abs (x))));
01166   }
01167   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01168     return static_cast<val_type> ( ::log10 (static_cast<float> (abs (x))));
01169   }
01170   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01171     return zero ();
01172   }
01173 
01174   // Backwards compatibility with Teuchos::ScalarTraits.
01175   typedef mag_type magnitudeType;
01176   typedef val_type halfPrecision;
01177   typedef val_type doublePrecision;
01178 
01179   static const bool isComplex = false;
01180   static const bool isOrdinal = true;
01181   static const bool isComparable = true;
01182   static const bool hasMachineParameters = false;
01183   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01184     return abs (x);
01185   }
01186   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01187     return conj (x);
01188   }
01189   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01190     return false;
01191   }
01192   static std::string name () {
01193     return "char";
01194   }
01195   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01196     return sqrt (x);
01197   }
01198 };
01199 
01200 
01201 template<>
01202 class ArithTraits<signed char> {
01203 public:
01204   typedef signed char val_type;
01205   typedef val_type mag_type;
01206 
01207   static const bool is_specialized = true;
01208   static const bool is_signed = true;
01209   static const bool is_integer = true;
01210   static const bool is_exact = true;
01211   static const bool is_complex = false;
01212 
01213   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01214     return false;
01215   }
01216   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01217     return false;
01218   }
01219   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01220     return x >= 0 ? x : -x;
01221   }
01222   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01223     return 0;
01224   }
01225   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01226     return 1;
01227   }
01228   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01229     return SCHAR_MIN;
01230   }
01231   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01232     return SCHAR_MAX;
01233   }
01234   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01235     return x;
01236   }
01237   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01238     return 0;
01239   }
01240   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01241     return x;
01242   }
01243   static KOKKOS_FORCEINLINE_FUNCTION val_type
01244   pow (const val_type x, const val_type y) {
01245     return intPowSigned<val_type> (x, y);
01246   }
01247   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01248     return static_cast<val_type> ( ::sqrt (static_cast<float> (abs (x))));
01249   }
01250   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01251     return static_cast<val_type> ( ::log (static_cast<float> (abs (x))));
01252   }
01253   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01254     return static_cast<val_type> ( ::log10 (static_cast<float> (abs (x))));
01255   }
01256   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01257     return zero ();
01258   }
01259 
01260   // Backwards compatibility with Teuchos::ScalarTraits.
01261   typedef mag_type magnitudeType;
01262   typedef val_type halfPrecision;
01263   typedef val_type doublePrecision;
01264 
01265   static const bool isComplex = false;
01266   static const bool isOrdinal = true;
01267   static const bool isComparable = true;
01268   static const bool hasMachineParameters = false;
01269   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01270     return abs (x);
01271   }
01272   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01273     return conj (x);
01274   }
01275   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01276     return false;
01277   }
01278   static std::string name () {
01279     return "signed char";
01280   }
01281   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01282     return sqrt (x);
01283   }
01284 };
01285 
01286 
01287 template<>
01288 class ArithTraits<unsigned char> {
01289 public:
01290   typedef unsigned char val_type;
01291   typedef val_type mag_type;
01292 
01293   static const bool is_specialized = true;
01294   static const bool is_signed = false;
01295   static const bool is_integer = true;
01296   static const bool is_exact = true;
01297   static const bool is_complex = false;
01298 
01299   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01300     return false;
01301   }
01302   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01303     return false;
01304   }
01305   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01306     return x; // it's unsigned, so it's positive
01307   }
01308   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01309     return 0;
01310   }
01311   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01312     return 1;
01313   }
01314   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01315     return 0;
01316   }
01317   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01318     return UCHAR_MAX;
01319   }
01320   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01321     return x;
01322   }
01323   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01324     return 0;
01325   }
01326   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01327     return x;
01328   }
01329   static KOKKOS_FORCEINLINE_FUNCTION val_type
01330   pow (const val_type x, const val_type y) {
01331     return intPowUnsigned<val_type> (x, y);
01332   }
01333   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01334     // This will result in no loss of accuracy, though it might be
01335     // more expensive than it should, if we were clever about using
01336     // bit operations.
01337     return static_cast<val_type> ( ::sqrt (static_cast<float> (x)));
01338   }
01339 
01340   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01341     return static_cast<val_type> ( ::log (static_cast<float> (x)));
01342   }
01343   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01344     return static_cast<val_type> ( ::log10 (static_cast<float> (x)));
01345   }
01346   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01347     return zero ();
01348   }
01349 
01350   // Backwards compatibility with Teuchos::ScalarTraits.
01351   typedef mag_type magnitudeType;
01352   typedef val_type halfPrecision;
01353   typedef val_type doublePrecision;
01354 
01355   static const bool isComplex = false;
01356   static const bool isOrdinal = true;
01357   static const bool isComparable = true;
01358   static const bool hasMachineParameters = false;
01359   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01360     return abs (x);
01361   }
01362   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01363     return conj (x);
01364   }
01365   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01366     return false;
01367   }
01368   static std::string name () {
01369     return "unsigned char";
01370   }
01371   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01372     return sqrt (x);
01373   }
01374 };
01375 
01376 
01377 template<>
01378 class ArithTraits<short> {
01379 public:
01380   typedef short val_type;
01381   typedef val_type mag_type;
01382 
01383   static const bool is_specialized = true;
01384   static const bool is_signed = true;
01385   static const bool is_integer = true;
01386   static const bool is_exact = true;
01387   static const bool is_complex = false;
01388 
01389   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01390     return false;
01391   }
01392   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01393     return false;
01394   }
01395   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01396     // std::abs appears to work with CUDA 5.5 at least, but I'll use
01397     // the ternary expression for maximum generality.  Note that this
01398     // expression does not necessarily obey the rules for fabs() with
01399     // NaN input, so it should not be used for floating-point types.
01400     // It's perfectly fine for signed integer types, though.
01401     return x >= 0 ? x : -x;
01402   }
01403   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01404     return 0;
01405   }
01406   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01407     return 1;
01408   }
01409   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01410     // Macros like this work with CUDA, but
01411     // std::numeric_limits<val_type>::min() does not, because it is
01412     // not marked as a __device__ function.
01413     return SHRT_MIN;
01414   }
01415   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01416     return SHRT_MAX;
01417   }
01418   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01419     return x;
01420   }
01421   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01422     return 0;
01423   }
01424   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01425     return x;
01426   }
01427   static KOKKOS_FORCEINLINE_FUNCTION val_type pow (const val_type x, const val_type y) {
01428     return intPowSigned<val_type> (x, y);
01429   }
01431   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01432     // This will result in no loss of accuracy, though it might be
01433     // more expensive than it should, if we were clever about using
01434     // bit operations.
01435     return static_cast<val_type> ( ::sqrt (static_cast<float> (abs (x))));
01436   }
01437   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01438     return static_cast<val_type> ( ::log (static_cast<float> (abs (x))));
01439   }
01440   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01441     return static_cast<val_type> ( ::log10 (static_cast<float> (abs (x))));
01442   }
01443   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01444     return zero ();
01445   }
01446 
01447   // Backwards compatibility with Teuchos::ScalarTraits.
01448   typedef mag_type magnitudeType;
01449   typedef val_type halfPrecision;
01450   typedef val_type doublePrecision;
01451 
01452   static const bool isComplex = false;
01453   static const bool isOrdinal = true;
01454   static const bool isComparable = true;
01455   static const bool hasMachineParameters = false;
01456   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01457     return abs (x);
01458   }
01459   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01460     return conj (x);
01461   }
01462   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01463     return false;
01464   }
01465   static std::string name () {
01466     return "short";
01467   }
01468   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01469     return sqrt (x);
01470   }
01471 };
01472 
01473 
01474 template<>
01475 class ArithTraits<unsigned short> {
01476 public:
01477   typedef unsigned short val_type;
01478   typedef val_type mag_type;
01479 
01480   static const bool is_specialized = true;
01481   static const bool is_signed = false;
01482   static const bool is_integer = true;
01483   static const bool is_exact = true;
01484   static const bool is_complex = false;
01485 
01486   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01487     return false;
01488   }
01489   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01490     return false;
01491   }
01492   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01493     return x; // it's unsigned, so it's positive
01494   }
01495   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01496     return 0;
01497   }
01498   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01499     return 1;
01500   }
01501   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01502     return 0;
01503   }
01504   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01505     return USHRT_MAX;
01506   }
01507   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01508     return x;
01509   }
01510   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01511     return 0;
01512   }
01513   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01514     return x;
01515   }
01516   static KOKKOS_FORCEINLINE_FUNCTION val_type
01517   pow (const val_type x, const val_type y) {
01518     return intPowUnsigned<val_type> (x, y);
01519   }
01520   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01521     // This will result in no loss of accuracy, though it might be
01522     // more expensive than it should, if we were clever about using
01523     // bit operations.
01524     return static_cast<val_type> ( ::sqrt (static_cast<float> (x)));
01525   }
01526   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01527     return static_cast<val_type> ( ::log (static_cast<float> (x)));
01528   }
01529   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01530     return static_cast<val_type> ( ::log10 (static_cast<float> (x)));
01531   }
01532   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01533     return zero ();
01534   }
01535 
01536   // Backwards compatibility with Teuchos::ScalarTraits.
01537   typedef mag_type magnitudeType;
01538   typedef val_type halfPrecision;
01539   typedef val_type doublePrecision;
01540 
01541   static const bool isComplex = false;
01542   static const bool isOrdinal = true;
01543   static const bool isComparable = true;
01544   static const bool hasMachineParameters = false;
01545   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01546     return abs (x);
01547   }
01548   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01549     return conj (x);
01550   }
01551   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01552     return false;
01553   }
01554   static std::string name () {
01555     return "unsigned short";
01556   }
01557   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01558     return sqrt (x);
01559   }
01560 };
01561 
01562 
01563 template<>
01564 class ArithTraits<int> {
01565 public:
01566   typedef int val_type;
01567   typedef val_type mag_type;
01568 
01569   static const bool is_specialized = true;
01570   static const bool is_signed = true;
01571   static const bool is_integer = true;
01572   static const bool is_exact = true;
01573   static const bool is_complex = false;
01574 
01575   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01576     return false;
01577   }
01578   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01579     return false;
01580   }
01581   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01582     // std::abs appears to work with CUDA 5.5 at least, but I'll use
01583     // the ternary expression for maximum generality.  Note that this
01584     // expression does not necessarily obey the rules for fabs() with
01585     // NaN input, so it should not be used for floating-point types.
01586     // It's perfectly fine for signed integer types, though.
01587     return x >= 0 ? x : -x;
01588   }
01589   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01590     return 0;
01591   }
01592   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01593     return 1;
01594   }
01595   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01596     // Macros like INT_MIN work with CUDA, but
01597     // std::numeric_limits<val_type>::min() does not, because it is
01598     // not marked as a __device__ function.
01599     return INT_MIN;
01600   }
01601   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01602     return INT_MAX;
01603   }
01604   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01605     return x;
01606   }
01607   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01608     return 0;
01609   }
01610   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01611     return x;
01612   }
01613   static KOKKOS_FORCEINLINE_FUNCTION val_type
01614   pow (const val_type x, const val_type y) {
01615     return intPowSigned<val_type> (x, y);
01616   }
01617   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01618     // This will result in no loss of accuracy, though it might be
01619     // more expensive than it should, if we were clever about using
01620     // bit operations.
01621     return static_cast<val_type> ( ::sqrt (static_cast<double> (abs (x))));
01622   }
01623   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01624     return static_cast<val_type> ( ::log (static_cast<double> (abs (x))));
01625   }
01626   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01627     return static_cast<val_type> ( ::log10 (static_cast<double> (abs (x))));
01628   }
01629   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01630     return zero ();
01631   }
01632 
01633   // Backwards compatibility with Teuchos::ScalarTraits.
01634   typedef mag_type magnitudeType;
01635   typedef val_type halfPrecision;
01636   typedef val_type doublePrecision;
01637 
01638   static const bool isComplex = false;
01639   static const bool isOrdinal = true;
01640   static const bool isComparable = true;
01641   static const bool hasMachineParameters = false;
01642   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01643     return abs (x);
01644   }
01645   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01646     return conj (x);
01647   }
01648   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01649     return false;
01650   }
01651   static std::string name () {
01652     return "int";
01653   }
01654   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01655     return sqrt (x);
01656   }
01657 };
01658 
01659 
01660 template<>
01661 class ArithTraits<unsigned int> {
01662 public:
01663   typedef unsigned int val_type;
01664   typedef val_type mag_type;
01665 
01666   static const bool is_specialized = true;
01667   static const bool is_signed = false;
01668   static const bool is_integer = true;
01669   static const bool is_exact = true;
01670   static const bool is_complex = false;
01671 
01672   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01673     return false;
01674   }
01675   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01676     return false;
01677   }
01678   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01679     return x; // it's unsigned, so it's positive
01680   }
01681   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01682     return 0;
01683   }
01684   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01685     return 1;
01686   }
01687   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01688     return 0;
01689   }
01690   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01691     return UINT_MAX;
01692   }
01693   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01694     return x;
01695   }
01696   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01697     return 0;
01698   }
01699   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01700     return x;
01701   }
01702   static KOKKOS_FORCEINLINE_FUNCTION val_type
01703   pow (const val_type x, const val_type y) {
01704     return intPowUnsigned<val_type> (x, y);
01705   }
01706   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01707     // This will result in no loss of accuracy, though it might be
01708     // more expensive than it should, if we were clever about using
01709     // bit operations.
01710     return static_cast<val_type> ( ::sqrt (static_cast<double> (x)));
01711   }
01712   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01713     return static_cast<val_type> ( ::log (static_cast<double> (x)));
01714   }
01715   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01716     return static_cast<val_type> ( ::log10 (static_cast<double> (x)));
01717   }
01718   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01719     return zero ();
01720   }
01721 
01722   // Backwards compatibility with Teuchos::ScalarTraits.
01723   typedef mag_type magnitudeType;
01724   typedef val_type halfPrecision;
01725   typedef val_type doublePrecision;
01726 
01727   static const bool isComplex = false;
01728   static const bool isOrdinal = true;
01729   static const bool isComparable = true;
01730   static const bool hasMachineParameters = false;
01731   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01732     return abs (x);
01733   }
01734   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01735     return conj (x);
01736   }
01737   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01738     return false;
01739   }
01740   static std::string name () {
01741     return "unsigned int";
01742   }
01743   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01744     return sqrt (x);
01745   }
01746 };
01747 
01748 
01749 template<>
01750 class ArithTraits<long> {
01751 public:
01752   typedef long val_type;
01753   typedef val_type mag_type;
01754 
01755   static const bool is_specialized = true;
01756   static const bool is_signed = true;
01757   static const bool is_integer = true;
01758   static const bool is_exact = true;
01759   static const bool is_complex = false;
01760 
01761   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01762     return false;
01763   }
01764   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01765     return false;
01766   }
01767   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01768     return x >= 0 ? x : -x;
01769   }
01770   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01771     return 0;
01772   }
01773   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01774     return 1;
01775   }
01776   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01777     return LONG_MIN;
01778   }
01779   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01780     return LONG_MAX;
01781   }
01782   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01783     return x;
01784   }
01785   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01786     return 0;
01787   }
01788   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01789     return x;
01790   }
01791   static KOKKOS_FORCEINLINE_FUNCTION val_type
01792   pow (const val_type x, const val_type y) {
01793     return intPowSigned<val_type> (x, y);
01794   }
01795   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01796 #ifdef __CUDA_ARCH__
01797     return static_cast<val_type> ( ::sqrt (static_cast<double> (abs (x))));
01798 #else
01799     return static_cast<val_type> ( ::sqrt (static_cast<long double> (abs (x))));
01800 #endif // __CUDA_ARCH__
01801   }
01802   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01803     return static_cast<val_type> ( ::log (static_cast<double> (abs (x))));
01804   }
01805   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01806     return static_cast<val_type> ( ::log10 (static_cast<double> (abs (x))));
01807   }
01808   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01809     return zero ();
01810   }
01811 
01812   // Backwards compatibility with Teuchos::ScalarTraits.
01813   typedef mag_type magnitudeType;
01814   typedef val_type halfPrecision;
01815   typedef val_type doublePrecision;
01816 
01817   static const bool isComplex = false;
01818   static const bool isOrdinal = true;
01819   static const bool isComparable = true;
01820   static const bool hasMachineParameters = false;
01821   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01822     return abs (x);
01823   }
01824   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01825     return conj (x);
01826   }
01827   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01828     return false;
01829   }
01830   static std::string name () {
01831     return "long";
01832   }
01833   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01834     return sqrt (x);
01835   }
01836 };
01837 
01838 
01839 template<>
01840 class ArithTraits<unsigned long> {
01841 public:
01842   typedef unsigned long val_type;
01843   typedef val_type mag_type;
01844 
01845   static const bool is_specialized = true;
01846   static const bool is_signed = false;
01847   static const bool is_integer = true;
01848   static const bool is_exact = true;
01849   static const bool is_complex = false;
01850 
01851   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01852     return false;
01853   }
01854   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01855     return false;
01856   }
01857   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01858     return x;
01859   }
01860   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01861     return 0;
01862   }
01863   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01864     return 1;
01865   }
01866   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01867     return 0;
01868   }
01869   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01870     return ULONG_MAX;
01871   }
01872   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01873     return x;
01874   }
01875   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01876     return 0;
01877   }
01878   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01879     return x;
01880   }
01881   static KOKKOS_FORCEINLINE_FUNCTION val_type pow (const val_type x, const val_type y) {
01882     return intPowUnsigned<val_type> (x, y);
01883   }
01884   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01885 #ifdef __CUDA_ARCH__
01886     return static_cast<val_type> ( ::sqrt (static_cast<double> (x)));
01887 #else
01888     return static_cast<val_type> ( ::sqrt (static_cast<long double> (x)));
01889 #endif // __CUDA_ARCH__
01890   }
01891   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01892     return static_cast<long> ( ::log (static_cast<double> (x)));
01893   }
01894   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01895     return static_cast<long> ( ::log10 (static_cast<double> (x)));
01896   }
01897   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
01898     return zero ();
01899   }
01900 
01901   // Backwards compatibility with Teuchos::ScalarTraits.
01902   typedef mag_type magnitudeType;
01903   typedef val_type halfPrecision;
01904   typedef val_type doublePrecision;
01905 
01906   static const bool isComplex = false;
01907   static const bool isOrdinal = true;
01908   static const bool isComparable = true;
01909   static const bool hasMachineParameters = false;
01910   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
01911     return abs (x);
01912   }
01913   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
01914     return conj (x);
01915   }
01916   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
01917     return false;
01918   }
01919   static std::string name () {
01920     return "unsigned long";
01921   }
01922   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
01923     return sqrt (x);
01924   }
01925 };
01926 
01927 
01928 template<>
01929 class ArithTraits<long long> {
01930 public:
01931   typedef long long val_type;
01932   typedef val_type mag_type;
01933 
01934   static const bool is_specialized = true;
01935   static const bool is_signed = true;
01936   static const bool is_integer = true;
01937   static const bool is_exact = true;
01938   static const bool is_complex = false;
01939 
01940   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
01941     return false;
01942   }
01943   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
01944     return false;
01945   }
01946   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
01947     return x >= 0 ? x : -x;
01948   }
01949   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
01950     return 0;
01951   }
01952   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
01953     return 1;
01954   }
01955   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
01956     return LLONG_MIN;
01957   }
01958   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
01959     return LLONG_MAX;
01960   }
01961   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
01962     return x;
01963   }
01964   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
01965     return 0;
01966   }
01967   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
01968     return x;
01969   }
01970   static KOKKOS_FORCEINLINE_FUNCTION val_type
01971   pow (const val_type x, const val_type y) {
01972     return intPowSigned<val_type> (x, y);
01973   }
01974   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
01975 #ifdef __CUDA_ARCH__
01976     // Casting from a 64-bit integer type to double does result in a
01977     // loss of accuracy.  However, it gives us a good first
01978     // approximation.  For very large numbers, we may lose some
01979     // significand bits, but will always get within a factor of two
01980     // (assuming correct rounding) of the exact double-precision
01981     // number.  We could then binary search between half the result
01982     // and twice the result (assuming the latter is <= INT64_MAX,
01983     // which it has to be, so we don't have to check) to ensure
01984     // correctness.  It actually should suffice to check numbers
01985     // within 1 of the result.
01986     return static_cast<val_type> ( ::sqrt (static_cast<double> (abs (x))));
01987 #else
01988     // IEEE 754 promises that long double has at least 64 significand
01989     // bits, so we can use it to represent any signed or unsigned
01990     // 64-bit integer type exactly.  However, CUDA does not implement
01991     // long double for device functions.
01992     return static_cast<val_type> ( ::sqrt (static_cast<long double> (abs (x))));
01993 #endif // __CUDA_ARCH__
01994   }
01995   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
01996     return static_cast<val_type> ( ::log (static_cast<double> (abs (x))));
01997   }
01998   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
01999     return static_cast<val_type> ( ::log10 (static_cast<double> (abs (x))));
02000   }
02001   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
02002     return zero ();
02003   }
02004 
02005   // Backwards compatibility with Teuchos::ScalarTraits.
02006   typedef mag_type magnitudeType;
02007   typedef val_type halfPrecision;
02008   typedef val_type doublePrecision;
02009 
02010   static const bool isComplex = false;
02011   static const bool isOrdinal = true;
02012   static const bool isComparable = true;
02013   static const bool hasMachineParameters = false;
02014   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
02015     return abs (x);
02016   }
02017   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
02018     return conj (x);
02019   }
02020   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
02021     return false;
02022   }
02023   static std::string name () {
02024     return "long long";
02025   }
02026   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
02027     return sqrt (x);
02028   }
02029 };
02030 
02031 
02032 template<>
02033 class ArithTraits<unsigned long long> {
02034 public:
02035   typedef unsigned long long val_type;
02036   typedef val_type mag_type;
02037 
02038   static const bool is_specialized = true;
02039   static const bool is_signed = false;
02040   static const bool is_integer = true;
02041   static const bool is_exact = true;
02042   static const bool is_complex = false;
02043 
02044   static KOKKOS_FORCEINLINE_FUNCTION bool isInf (const val_type x) {
02045     return false;
02046   }
02047   static KOKKOS_FORCEINLINE_FUNCTION bool isNan (const val_type x) {
02048     return false;
02049   }
02050   static KOKKOS_FORCEINLINE_FUNCTION mag_type abs (const val_type x) {
02051     return x; // unsigned integers are always nonnegative
02052   }
02053   static KOKKOS_FORCEINLINE_FUNCTION val_type zero () {
02054     return 0;
02055   }
02056   static KOKKOS_FORCEINLINE_FUNCTION val_type one () {
02057     return 1;
02058   }
02059   static KOKKOS_FORCEINLINE_FUNCTION val_type min () {
02060     return 0;
02061   }
02062   static KOKKOS_FORCEINLINE_FUNCTION val_type max () {
02063     return ULLONG_MAX ;
02064   }
02065   static KOKKOS_FORCEINLINE_FUNCTION mag_type real (const val_type x) {
02066     return x;
02067   }
02068   static KOKKOS_FORCEINLINE_FUNCTION mag_type imag (const val_type x) {
02069     return 0;
02070   }
02071   static KOKKOS_FORCEINLINE_FUNCTION val_type conj (const val_type x) {
02072     return x;
02073   }
02074   static KOKKOS_FORCEINLINE_FUNCTION val_type
02075   pow (const val_type x, const val_type y) {
02076     return intPowUnsigned<val_type> (x, y);
02077   }
02078   static KOKKOS_FORCEINLINE_FUNCTION val_type sqrt (const val_type x) {
02079 #ifdef __CUDA_ARCH__
02080     return static_cast<val_type> ( ::sqrt (static_cast<double> (x)));
02081 #else
02082     return static_cast<val_type> ( ::sqrt (static_cast<long double> (x)));
02083 #endif // __CUDA_ARCH__
02084   }
02085   static KOKKOS_FORCEINLINE_FUNCTION val_type log (const val_type x) {
02086     return static_cast<val_type> ( ::log (static_cast<double> (x)));
02087   }
02088   static KOKKOS_FORCEINLINE_FUNCTION val_type log10 (const val_type x) {
02089     return static_cast<val_type> ( ::log10 (static_cast<double> (x)));
02090   }
02091   static KOKKOS_FORCEINLINE_FUNCTION mag_type epsilon () {
02092     return zero ();
02093   }
02094 
02095   // Backwards compatibility with Teuchos::ScalarTraits.
02096   typedef mag_type magnitudeType;
02097   typedef val_type halfPrecision;
02098   typedef val_type doublePrecision;
02099 
02100   static const bool isComplex = false;
02101   static const bool isOrdinal = true;
02102   static const bool isComparable = true;
02103   static const bool hasMachineParameters = false;
02104   static KOKKOS_FORCEINLINE_FUNCTION magnitudeType magnitude (const val_type x) {
02105     return abs (x);
02106   }
02107   static KOKKOS_FORCEINLINE_FUNCTION val_type conjugate (const val_type x) {
02108     return conj (x);
02109   }
02110   static KOKKOS_FORCEINLINE_FUNCTION bool isnaninf (const val_type) {
02111     return false;
02112   }
02113   static std::string name () {
02114     return "unsigned long long";
02115   }
02116   static KOKKOS_FORCEINLINE_FUNCTION val_type squareroot (const val_type x) {
02117     return sqrt (x);
02118   }
02119 };
02120 
02121 // dd_real and qd_real are floating-point types provided by the QD
02122 // library of David Bailey (LBNL):
02123 //
02124 // http://crd-legacy.lbl.gov/~dhbailey/mpdist/
02125 //
02126 // dd_real uses two doubles (128 bits), and qd_real uses four doubles
02127 // (256 bits).
02128 //
02129 // Kokkos does <i>not</i> currently support these types in device
02130 // functions.  It should be possible to use Kokkos' support for
02131 // aggregate types to implement device function support for dd_real
02132 // and qd_real, but we have not done this yet (as of 07 Jan 2014).
02133 // Hence, the class methods of the ArithTraits specializations for
02134 // dd_real and qd_real are not marked as device functions.
02135 #ifdef HAVE_KOKKOS_QD
02136 template<>
02137 struct ScalarTraits<dd_real>
02138 {
02139   typedef dd_real val_type;
02140   typedef dd_real mag_type;
02141 
02142   static const bool is_specialized = true;
02143   static const bool is_signed = true;
02144   static const bool is_integer = false;
02145   static const bool is_exact = false;
02146   static const bool is_complex = false;
02147 
02148   static inline bool isInf (const val_type& x) {
02149     return isinf (x);
02150   }
02151   static inline bool isNan (const val_type& x) {
02152     return isnan (x);
02153   }
02154   static inline mag_type abs (const val_type& x) {
02155     return ::abs (x);
02156   }
02157   static inline val_type zero () {
02158     return val_type (0.0);
02159   }
02160   static inline val_type one () {
02161     return val_type (1.0);
02162   }
02163   static inline val_type min () {
02164     return std::numeric_limits<val_type>::min ();
02165   }
02166   static inline val_type max () {
02167     return std::numeric_limits<val_type>::max ();
02168   }
02169   static inline mag_type real (const val_type& x) {
02170     return x;
02171   }
02172   static inline mag_type imag (const val_type&) {
02173     return zero ();
02174   }
02175   static inline val_type conj (const val_type& x) {
02176     return x;
02177   }
02178   static inline val_type pow (const val_type& x, const val_type& y) {
02179     return ::pow(x,y);
02180   }
02181   static inline val_type sqrt (const val_type& x) {
02182       return ::sqrt (x);
02183   }
02184   static inline val_type log (const val_type& x) {
02185     // dd_real puts its transcendental functions in the global namespace.
02186     return ::log (x);
02187   }
02188   static inline val_type log10 (const val_type& x) {
02189     return ::log10 (x);
02190   }
02191   static inline val_type nan () {
02192     return val_type::_nan;
02193   }
02194   static val_type epsilon () {
02195     return std::numeric_limits<val_type>::epsilon ();
02196   }
02197 
02198   typedef dd_real magnitudeType;
02199   typedef double halfPrecision;
02200   typedef qd_real doublePrecision;
02201 
02202   static const bool isComplex = false;
02203   static const bool isOrdinal = false;
02204   static const bool isComparable = true;
02205   static const bool hasMachineParameters = true;
02206 
02207   static mag_type eps () {
02208     return epsilon ();
02209   }
02210   static mag_type sfmin () {
02211     return min ();
02212   }
02213   static int base ()  {
02214     return std::numeric_limits<val_type>::radix;
02215   }
02216   static mag_type prec () {
02217     return eps () * base ();
02218   }
02219   static int t () {
02220     return std::numeric_limits<val_type>::digits;
02221   }
02222   static mag_type rnd () {
02223     return std::numeric_limits<val_type>::round_style == std::round_to_nearest ?
02224       one () :
02225       zero ();
02226   }
02227   static int emin () {
02228     return std::numeric_limits<val_type>::min_exponent;
02229   }
02230   static mag_type rmin () {
02231     return std::numeric_limits<val_type>::min ();
02232   }
02233   static int emax () {
02234     return std::numeric_limits<val_type>::max_exponent;
02235   }
02236   static mag_type rmax () {
02237     return std::numeric_limits<val_type>::max ();
02238   }
02239   static mag_type magnitude (const val_type& x) {
02240     return ::abs (x);
02241   }
02242   static val_type conjugate (const val_type& x) {
02243     return conj (x);
02244   }
02245   static bool isnaninf (const val_type& x) {
02246     return isNan (x) || isInf (x);
02247   }
02248   static std::string name () { return "dd_real"; }
02249   static val_type squareroot (const val_type& x) {
02250     return ::sqrt (x);
02251   }
02252 };
02253 
02254 
02255 template<>
02256 struct ScalarTraits<qd_real>
02257 {
02258   typedef qd_real val_type;
02259   typedef qd_real mag_type;
02260 
02261   static const bool is_specialized = true;
02262   static const bool is_signed = true;
02263   static const bool is_integer = false;
02264   static const bool is_exact = false;
02265   static const bool is_complex = false;
02266 
02267   static inline bool isInf (const val_type& x) {
02268     return isinf (x);
02269   }
02270   static inline bool isNan (const val_type& x) {
02271     return isnan (x);
02272   }
02273   static inline mag_type abs (const val_type& x) {
02274     return ::abs (x);
02275   }
02276   static inline val_type zero () {
02277     return val_type (0.0);
02278   }
02279   static inline val_type one () {
02280     return val_type (1.0);
02281   }
02282   static inline val_type min () {
02283     return std::numeric_limits<val_type>::min ();
02284   }
02285   static inline val_type max () {
02286     return std::numeric_limits<val_type>::max ();
02287   }
02288   static inline mag_type real (const val_type& x) {
02289     return x;
02290   }
02291   static inline mag_type imag (const val_type&) {
02292     return zero ();
02293   }
02294   static inline val_type conj (const val_type& x) {
02295     return x;
02296   }
02297   static inline val_type pow (const val_type& x, const val_type& y) {
02298     return ::pow (x, y);
02299   }
02300   static inline val_type sqrt (const val_type& x) {
02301       return ::sqrt (x);
02302   }
02303   static inline val_type log (const val_type& x) {
02304     // val_type puts its transcendental functions in the global namespace.
02305     return ::log (x);
02306   }
02307   static inline val_type log10 (const val_type& x) {
02308     return ::log10 (x);
02309   }
02310   static inline val_type nan () {
02311     return val_type::_nan;
02312   }
02313   static inline val_type epsilon () {
02314     return std::numeric_limits<val_type>::epsilon ();
02315   }
02316 
02317   typedef qd_real magnitudeType;
02318   typedef dd_real halfPrecision;
02319   // The QD library does not have an "oct-double real" class.  One
02320   // could use an arbitrary-precision library like MPFR or ARPREC,
02321   // with the precision set appropriately, to get an
02322   // extended-precision type for qd_real.
02323   typedef qd_real doublePrecision;
02324 
02325   static const bool isComplex = false;
02326   static const bool isOrdinal = false;
02327   static const bool isComparable = true;
02328   static const bool hasMachineParameters = true;
02329 
02330   static mag_type eps () {
02331     return epsilon ();
02332   }
02333   static mag_type sfmin () {
02334     return min ();
02335   }
02336   static int base ()  {
02337     return std::numeric_limits<val_type>::radix;
02338   }
02339   static mag_type prec () {
02340     return eps () * base ();
02341   }
02342   static int t () {
02343     return std::numeric_limits<val_type>::digits;
02344   }
02345   static mag_type rnd () {
02346     return std::numeric_limits<val_type>::round_style == std::round_to_nearest ?
02347       one () :
02348       zero ();
02349   }
02350   static int emin () {
02351     return std::numeric_limits<val_type>::min_exponent;
02352   }
02353   static mag_type rmin () {
02354     return std::numeric_limits<val_type>::min ();
02355   }
02356   static int emax () {
02357     return std::numeric_limits<val_type>::max_exponent;
02358   }
02359   static mag_type rmax () {
02360     return std::numeric_limits<val_type>::max ();
02361   }
02362   static mag_type magnitude (const val_type& x) {
02363     return ::abs (x);
02364   }
02365   static val_type conjugate (const val_type& x) {
02366     return conj (x);
02367   }
02368   static bool isnaninf (const val_type& x) {
02369     return isNan (x) || isInf (x);
02370   }
02371   static std::string name () { return "qd_real"; }
02372   static val_type squareroot (const val_type& x) {
02373     return ::sqrt (x);
02374   }
02375 };
02376 #endif // HAVE_KOKKOS_QD
02377 
02378 } // namespace Details
02379 } // namespace Kokkos
02380 
02381 #endif // KOKKOS_ARITHTRAITS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends