|
Kokkos Core Kernels Package
Version of the Day
|
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
1.7.6.1