21 #ifndef viskores_Math_h
22 #define viskores_Math_h
35 #endif // !VISKORES_CUDA
37 #if !defined(VISKORES_CUDA_DEVICE_PASS)
38 #define VISKORES_USE_STL
47 #endif // VISKORES_CUDA
48 #endif // VISKORES_MSVC
50 #define VISKORES_CUDA_MATH_FUNCTION_32(func) func##f
51 #define VISKORES_CUDA_MATH_FUNCTION_64(func) func
60 struct FloatingPointReturnType
63 using representable_as_float_type =
64 std::integral_constant<bool,
65 ((
sizeof(ctype) <
sizeof(
float)) ||
66 std::is_same<ctype, viskores::Float32>::value)>;
67 using Type =
typename std::
68 conditional<representable_as_float_type::value, viskores::Float32, viskores::Float64>::type;
74 template <
typename T = viskores::Float64>
75 static constexpr
inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type TwoPi()
77 using FT =
typename detail::FloatingPointReturnType<T>::Type;
78 return static_cast<FT
>(6.28318530717958647692528676655900576);
83 template <
typename T = viskores::Float64>
84 static constexpr
inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi()
86 using FT =
typename detail::FloatingPointReturnType<T>::Type;
87 return static_cast<FT
>(3.14159265358979323846264338327950288);
92 template <
typename T = viskores::Float64>
93 static constexpr
inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_2()
95 using FT =
typename detail::FloatingPointReturnType<T>::Type;
96 return static_cast<FT
>(1.57079632679489661923132169163975144);
101 template <
typename T = viskores::Float64>
102 static constexpr
inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_3()
104 using FT =
typename detail::FloatingPointReturnType<T>::Type;
105 return static_cast<FT
>(1.04719755119659774615421446109316762);
110 template <
typename T = viskores::Float64>
111 static constexpr
inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_4()
113 using FT =
typename detail::FloatingPointReturnType<T>::Type;
114 return static_cast<FT
>(0.78539816339744830961566084581987572);
119 template <
typename T = viskores::Float64>
120 static constexpr
inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Pi_180()
122 using FT =
typename detail::FloatingPointReturnType<T>::Type;
123 return static_cast<FT
>(0.01745329251994329547437168059786927);
130 return TwoPi<viskores::Float32>();
137 return Pi<viskores::Float32>();
144 return Pi_2<viskores::Float32>();
151 return Pi_3<viskores::Float32>();
158 return Pi_4<viskores::Float32>();
165 return Pi_180<viskores::Float32>();
191 template <
typename T>
194 using RT =
typename detail::FloatingPointReturnType<T>::Type;
197 template <
typename T, viskores::IdComponent N>
208 template <
typename T>
215 template <
typename T>
222 template <
typename T>
252 template <
typename T>
255 using RT =
typename detail::FloatingPointReturnType<T>::Type;
258 template <
typename T, viskores::IdComponent N>
269 template <
typename T>
276 template <
typename T>
283 template <
typename T>
313 template <
typename T>
316 using RT =
typename detail::FloatingPointReturnType<T>::Type;
319 template <
typename T, viskores::IdComponent N>
330 template <
typename T>
337 template <
typename T>
344 template <
typename T>
374 template <
typename T>
377 using RT =
typename detail::FloatingPointReturnType<T>::Type;
380 template <
typename T, viskores::IdComponent N>
391 template <
typename T>
398 template <
typename T>
405 template <
typename T>
435 template <
typename T>
438 using RT =
typename detail::FloatingPointReturnType<T>::Type;
441 template <
typename T, viskores::IdComponent N>
452 template <
typename T>
459 template <
typename T>
466 template <
typename T>
496 template <
typename T>
499 using RT =
typename detail::FloatingPointReturnType<T>::Type;
502 template <
typename T, viskores::IdComponent N>
513 template <
typename T>
520 template <
typename T>
527 template <
typename T>
545 return std::atan2(x, y);
553 return std::atan2(x, y);
579 template <
typename T>
582 using RT =
typename detail::FloatingPointReturnType<T>::Type;
585 template <
typename T, viskores::IdComponent N>
596 template <
typename T>
603 template <
typename T>
610 template <
typename T>
640 template <
typename T>
643 using RT =
typename detail::FloatingPointReturnType<T>::Type;
646 template <
typename T, viskores::IdComponent N>
657 template <
typename T>
664 template <
typename T>
671 template <
typename T>
701 template <
typename T>
704 using RT =
typename detail::FloatingPointReturnType<T>::Type;
707 template <
typename T, viskores::IdComponent N>
718 template <
typename T>
725 template <
typename T>
732 template <
typename T>
750 return std::asinh(x);
759 return std::asinh(x);
762 template <
typename T>
765 using RT =
typename detail::FloatingPointReturnType<T>::Type;
768 template <
typename T, viskores::IdComponent N>
779 template <
typename T>
786 template <
typename T>
793 template <
typename T>
811 return std::acosh(x);
820 return std::acosh(x);
823 template <
typename T>
826 using RT =
typename detail::FloatingPointReturnType<T>::Type;
829 template <
typename T, viskores::IdComponent N>
840 template <
typename T>
847 template <
typename T>
854 template <
typename T>
872 return std::atanh(x);
881 return std::atanh(x);
884 template <
typename T>
887 using RT =
typename detail::FloatingPointReturnType<T>::Type;
890 template <
typename T, viskores::IdComponent N>
901 template <
typename T>
908 template <
typename T>
915 template <
typename T>
933 return std::pow(x, y);
941 return std::pow(x, y);
968 template <
typename T>
971 using RT =
typename detail::FloatingPointReturnType<T>::Type;
974 template <
typename T, viskores::IdComponent N>
985 template <
typename T>
992 template <
typename T>
999 template <
typename T>
1014 #ifdef VISKORES_CUDA
1023 template <
typename T>
1028 #else // !VISKORES_CUDA
1037 template <
typename T>
1042 #endif // !VISKORES_CUDA
1044 template <
typename T, viskores::IdComponent N>
1051 result[index] = viskores::RSqrt(x[index]);
1055 template <
typename T>
1060 viskores::RSqrt(x[0]), viskores::RSqrt(x[1]), viskores::RSqrt(x[2]), viskores::RSqrt(x[3]));
1062 template <
typename T>
1067 viskores::RSqrt(x[0]), viskores::RSqrt(x[1]), viskores::RSqrt(x[2]));
1069 template <
typename T>
1074 viskores::RSqrt(x[1]));
1084 #ifdef VISKORES_CUDA
1087 return std::cbrt(x);
1093 #ifdef VISKORES_CUDA
1096 return std::cbrt(x);
1099 template <
typename T>
1102 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1105 template <
typename T, viskores::IdComponent N>
1116 template <
typename T>
1123 template <
typename T>
1130 template <
typename T>
1145 #ifdef VISKORES_CUDA
1154 template <
typename T>
1159 #else // !VISKORES_CUDA
1168 template <
typename T>
1173 #endif // !VISKORES_CUDA
1175 template <
typename T, viskores::IdComponent N>
1182 result[index] = viskores::RCbrt(x[index]);
1186 template <
typename T>
1191 viskores::RCbrt(x[0]), viskores::RCbrt(x[1]), viskores::RCbrt(x[2]), viskores::RCbrt(x[3]));
1193 template <
typename T>
1198 viskores::RCbrt(x[0]), viskores::RCbrt(x[1]), viskores::RCbrt(x[2]));
1200 template <
typename T>
1205 viskores::RCbrt(x[1]));
1215 #ifdef VISKORES_CUDA
1224 #ifdef VISKORES_CUDA
1230 template <
typename T>
1233 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1236 template <
typename T, viskores::IdComponent N>
1247 template <
typename T>
1254 template <
typename T>
1261 template <
typename T>
1276 #ifdef VISKORES_CUDA
1279 return std::exp2(x);
1285 #ifdef VISKORES_CUDA
1288 return std::exp2(x);
1291 template <
typename T>
1294 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1297 template <
typename T, viskores::IdComponent N>
1308 template <
typename T>
1315 template <
typename T>
1322 template <
typename T>
1338 #ifdef VISKORES_CUDA
1341 return std::expm1(x);
1347 #ifdef VISKORES_CUDA
1350 return std::expm1(x);
1353 template <
typename T>
1356 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1359 template <
typename T, viskores::IdComponent N>
1370 template <
typename T>
1377 template <
typename T>
1384 template <
typename T>
1396 #ifdef VISKORES_CUDA
1405 template <
typename T>
1410 #else // !VISKORES_CUDA
1413 return viskores::Pow(10, x);
1417 return viskores::Pow(10, x);
1419 template <
typename T>
1424 #endif // !VISKORES_CUDA
1426 template <
typename T, viskores::IdComponent N>
1433 result[index] = viskores::Exp10(x[index]);
1437 template <
typename T>
1442 viskores::Exp10(x[0]), viskores::Exp10(x[1]), viskores::Exp10(x[2]), viskores::Exp10(x[3]));
1444 template <
typename T>
1449 viskores::Exp10(x[0]), viskores::Exp10(x[1]), viskores::Exp10(x[2]));
1451 template <
typename T>
1456 viskores::Exp10(x[1]));
1466 #ifdef VISKORES_CUDA
1475 #ifdef VISKORES_CUDA
1481 template <
typename T>
1484 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1487 template <
typename T, viskores::IdComponent N>
1498 template <
typename T>
1505 template <
typename T>
1512 template <
typename T>
1527 #ifdef VISKORES_CUDA
1530 return std::log2(x);
1536 #ifdef VISKORES_CUDA
1539 return std::log2(x);
1542 template <
typename T>
1545 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1548 template <
typename T, viskores::IdComponent N>
1559 template <
typename T>
1566 template <
typename T>
1573 template <
typename T>
1588 #ifdef VISKORES_CUDA
1591 return std::log10(x);
1597 #ifdef VISKORES_CUDA
1600 return std::log10(x);
1603 template <
typename T>
1606 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1609 template <
typename T, viskores::IdComponent N>
1620 template <
typename T>
1627 template <
typename T>
1634 template <
typename T>
1649 #ifdef VISKORES_CUDA
1652 return std::log1p(x);
1658 #ifdef VISKORES_CUDA
1661 return std::log1p(x);
1664 template <
typename T>
1667 using RT =
typename detail::FloatingPointReturnType<T>::Type;
1670 template <
typename T, viskores::IdComponent N>
1681 template <
typename T>
1688 template <
typename T>
1695 template <
typename T>
1708 template <
typename T>
1710 #ifdef VISKORES_USE_STL
1713 return (std::max)(x, y);
1717 return (std::max)(x, y);
1719 #else // !VISKORES_USE_STL
1722 #ifdef VISKORES_CUDA
1725 return std::fmax(x, y);
1730 #ifdef VISKORES_CUDA
1733 return std::fmax(x, y);
1736 #endif // !VISKORES_USE_STL
1742 template <
typename T>
1744 #if defined(VISKORES_USE_STL) && !defined(VISKORES_HIP)
1747 return (std::min)(x, y);
1751 return (std::min)(x, y);
1753 #else // !VISKORES_USE_STL OR HIP
1756 #ifdef VISKORES_CUDA
1759 return std::fmin(x, y);
1764 #ifdef VISKORES_CUDA
1767 return std::fmin(x, y);
1770 #endif // !VISKORES_USE_STL
1776 template <
typename T>
1779 return (x < y) ? y : x;
1782 template <
typename T>
1789 Traits::SetComponent(
1790 result, index, viskores::Max(Traits::GetComponent(x, index), Traits::GetComponent(y, index)));
1795 template <
typename T>
1798 return (x < y) ? x : y;
1801 template <
typename T>
1808 Traits::SetComponent(
1809 result, index, viskores::Min(Traits::GetComponent(x, index), Traits::GetComponent(y, index)));
1818 template <
typename T>
1826 template <
typename T>
1837 return x > lo ? (x < hi ? x : hi) : lo;
1842 return x > lo ? (x < hi ? x : hi) : lo;
1849 #define VISKORES_USE_IEEE_NONFINITE
1852 #ifdef VISKORES_USE_IEEE_NONFINITE
1857 union IEEE754Bits32 {
1861 #define VISKORES_NAN_BITS_32 0x7FC00000U
1862 #define VISKORES_INF_BITS_32 0x7F800000U
1863 #define VISKORES_NEG_INF_BITS_32 0xFF800000U
1864 #define VISKORES_EPSILON_32 1e-5f
1866 union IEEE754Bits64 {
1870 #define VISKORES_NAN_BITS_64 0x7FF8000000000000ULL
1871 #define VISKORES_INF_BITS_64 0x7FF0000000000000ULL
1872 #define VISKORES_NEG_INF_BITS_64 0xFFF0000000000000ULL
1873 #define VISKORES_EPSILON_64 1e-9
1875 template <
typename T>
1881 using BitsType = viskores::detail::IEEE754Bits32;
1901 return neginf.scalar;
1909 struct FloatLimits<
viskores::Vec<viskores::Float32, N>>
1911 using BitsType = viskores::detail::IEEE754Bits32;
1944 using BitsType = viskores::detail::IEEE754Bits64;
1964 return neginf.scalar;
1972 struct FloatLimits<
viskores::Vec<viskores::Float64, N>>
1974 using BitsType = viskores::detail::IEEE754Bits64;
2004 #undef VISKORES_NAN_BITS_32
2005 #undef VISKORES_INF_BITS_32
2006 #undef VISKORES_NEG_INF_BITS_32
2007 #undef VISKORES_EPSILON_32
2008 #undef VISKORES_NAN_BITS_64
2009 #undef VISKORES_INF_BITS_64
2010 #undef VISKORES_NEG_INF_BITS_64
2011 #undef VISKORES_EPSILON_64
2014 #endif //VISKORES_USE_IEEE_NONFINITE
2023 #ifdef VISKORES_USE_IEEE_NONFINITE
2024 template <
typename T>
2027 return detail::FloatLimits<T>::Nan();
2029 #else // !VISKORES_USE_IEEE_NONFINITE
2030 template <
typename T>
2033 return std::numeric_limits<T>::quiet_NaN();
2035 #endif // !VISKORES_USE_IEEE_NONFINITE
2038 return viskores::Nan<viskores::Float32>();
2042 return viskores::Nan<viskores::Float64>();
2053 #ifdef VISKORES_USE_IEEE_NONFINITE
2054 template <
typename T>
2057 return detail::FloatLimits<T>::Infinity();
2059 #else // !VISKORES_USE_IEEE_NONFINITE
2060 template <
typename T>
2063 return std::numeric_limits<T>::infinity();
2065 #endif // !VISKORES_USE_IEEE_NONFINITE
2068 return viskores::Infinity<viskores::Float32>();
2072 return viskores::Infinity<viskores::Float64>();
2084 #ifdef VISKORES_USE_IEEE_NONFINITE
2085 template <
typename T>
2088 return detail::FloatLimits<T>::NegativeInfinity();
2090 #else // !VISKORES_USE_IEEE_NONFINITE
2091 template <
typename T>
2094 return -std::numeric_limits<T>::infinity();
2096 #endif // !VISKORES_USE_IEEE_NONFINITE
2099 return viskores::NegativeInfinity<viskores::Float32>();
2103 return viskores::NegativeInfinity<viskores::Float64>();
2114 #ifdef VISKORES_USE_IEEE_NONFINITE
2115 template <
typename T>
2118 return detail::FloatLimits<T>::Epsilon();
2120 #else // !VISKORES_USE_IEEE_NONFINITE
2121 template <
typename T>
2124 return std::numeric_limits<T>::epsilon();
2126 #endif // !VISKORES_USE_IEEE_NONFINITE
2129 return viskores::Epsilon<viskores::Float32>();
2133 return viskores::Epsilon<viskores::Float64>();
2141 template <
typename T>
2144 #ifndef VISKORES_CUDA
2147 return (isnan(x) != 0);
2152 template <
typename T>
2155 #ifndef VISKORES_CUDA
2158 return (isinf(x) != 0);
2163 template <
typename T>
2166 #ifndef VISKORES_CUDA
2167 using std::isfinite;
2169 return (isfinite(x) != 0);
2179 #ifdef VISKORES_CUDA
2182 return std::ceil(x);
2188 #ifdef VISKORES_CUDA
2191 return std::ceil(x);
2194 template <
typename T>
2197 using RT =
typename detail::FloatingPointReturnType<T>::Type;
2200 template <
typename T, viskores::IdComponent N>
2211 template <
typename T>
2218 template <
typename T>
2225 template <
typename T>
2240 #ifdef VISKORES_CUDA
2243 return std::floor(x);
2249 #ifdef VISKORES_CUDA
2252 return std::floor(x);
2255 template <
typename T>
2258 using RT =
typename detail::FloatingPointReturnType<T>::Type;
2261 template <
typename T, viskores::IdComponent N>
2272 template <
typename T>
2279 template <
typename T>
2286 template <
typename T>
2301 #ifdef VISKORES_CUDA
2304 return std::round(x);
2310 #ifdef VISKORES_CUDA
2313 return std::round(x);
2316 template <
typename T>
2319 using RT =
typename detail::FloatingPointReturnType<T>::Type;
2322 template <
typename T, viskores::IdComponent N>
2333 template <
typename T>
2340 template <
typename T>
2347 template <
typename T>
2365 #ifdef VISKORES_CUDA
2368 return std::fmod(x, y);
2373 #ifdef VISKORES_CUDA
2376 return std::fmod(x, y);
2388 #ifdef VISKORES_MSVC
2389 template <
typename T>
2393 return numerator - quotient * denominator;
2395 #else // !VISKORES_MSVC
2398 #ifdef VISKORES_CUDA
2401 return std::remainder(x, y);
2406 #ifdef VISKORES_CUDA
2409 return std::remainder(x, y);
2412 #endif // !VISKORES_MSVC
2420 template <
typename QType>
2427 #if defined(VISKORES_CUDA) || defined(VISKORES_HIP)
2431 const viskores::Float32 result = std::remquo(numerator, denominator, &iQuotient);
2433 quotient =
static_cast<QType
>(iQuotient);
2436 template <
typename QType>
2442 #ifdef VISKORES_CUDA
2446 const viskores::Float64 result = std::remquo(numerator, denominator, &iQuotient);
2448 quotient =
static_cast<QType
>(iQuotient);
2460 #if defined(VISKORES_CUDA) || defined(VISKORES_HIP)
2463 return std::modf(x, &integral);
2468 #if defined(VISKORES_CUDA)
2471 return std::modf(x, &integral);
2487 #if VISKORES_SIZE_LONG == 8
2489 #elif VISKORES_SIZE_LONG_LONG == 8
2492 #error Unknown size of Int64.
2497 #ifdef VISKORES_CUDA
2500 return std::fabs(x);
2505 #ifdef VISKORES_CUDA
2508 return std::fabs(x);
2511 template <
typename T>
2512 static inline VISKORES_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Abs(T x)
2514 #ifdef VISKORES_CUDA
2520 template <
typename T, viskores::IdComponent N>
2526 result[index] = viskores::Abs(x[index]);
2530 template <
typename T>
2533 return viskores::Vec<T, 4>(viskores::Abs(x[0]), viskores::Abs(x[1]), viskores::Abs(x[2]), viskores::Abs(x[3]));
2535 template <
typename T>
2538 return viskores::Vec<T, 3>(viskores::Abs(x[0]), viskores::Abs(x[1]), viskores::Abs(x[2]));
2540 template <
typename T>
2552 #ifndef VISKORES_CUDA
2559 #ifndef VISKORES_CUDA
2571 return (viskores::SignBit(x) != 0);
2575 return (viskores::SignBit(x) != 0);
2585 #ifdef VISKORES_CUDA
2588 return std::copysign(x, y);
2593 #ifdef VISKORES_CUDA
2596 return std::copysign(x, y);
2600 template <
typename T, viskores::IdComponent N>
2607 result[index] = viskores::CopySign(x[index], y[index]);
2619 #if defined(VISKORES_CUDA) || defined(VISKORES_HIP)
2622 return std::frexp(x, exponent);
2628 #ifdef VISKORES_CUDA
2631 return std::frexp(x, exponent);
2638 #ifdef VISKORES_CUDA
2641 return std::ldexp(x, exponent);
2647 #ifdef VISKORES_CUDA
2650 return std::ldexp(x, exponent);
2709 static_assert(std::numeric_limits<viskores::Float64>::has_denorm == std::denorm_present,
"FloatDistance presumes the floating-point type has subnormal numbers.");
2711 if (!viskores::IsFinite(x) || !viskores::IsFinite(y)) {
2712 return 0xFFFFFFFFFFFFFFFFL;
2717 y = viskores::Abs(y);
2720 x = viskores::Abs(x);
2723 if ( (x < 0 && y >= 0) || (x >= 0 && y < 0) )
2727 dy = detail::FloatDistancePositive(0.0, y);
2728 dx = detail::FloatDistancePositive(0.0, -x);
2731 dy = detail::FloatDistancePositive(0.0, -y);
2732 dx = detail::FloatDistancePositive(0.0, x);
2738 if (x < 0 && y < 0) {
2739 return detail::FloatDistancePositive(-x, -y);
2742 return detail::FloatDistancePositive(x, y);
2749 static_assert(std::numeric_limits<viskores::Float32>::has_denorm == std::denorm_present,
"FloatDistance presumes the floating-point type has subnormal numbers.");
2751 if (!viskores::IsFinite(x) || !viskores::IsFinite(y)) {
2752 return 0xFFFFFFFFFFFFFFFFL;
2756 y = viskores::Abs(y);
2759 x = viskores::Abs(x);
2762 if ( (x < 0 && y >= 0) || (x >= 0 && y < 0) )
2766 dy = detail::FloatDistancePositive(0.0f, y);
2767 dx = detail::FloatDistancePositive(0.0f, -x);
2770 dy = detail::FloatDistancePositive(0.0f, -y);
2771 dx = detail::FloatDistancePositive(0.0f, x);
2776 if (x < 0 && y < 0) {
2777 return detail::FloatDistancePositive(-x, -y);
2780 return detail::FloatDistancePositive(x, y);
2785 template<
typename T>
2789 T err = std::fma(-c, d, cd);
2790 T dop = std::fma(a, b, -cd);
2802 template<
typename T>
2842 #ifdef VISKORES_CUDA_DEVICE_PASS
2848 return __ffs(
static_cast<int>(word));
2850 #else // CUDA_DEVICE_PASS
2854 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG)
2857 return __builtin_ffs(
static_cast<int>(word));
2859 # elif defined(VISKORES_MSVC)
2863 return _BitScanForward(
reinterpret_cast<DWORD*
>(&firstSet), word) != 0
2866 # elif defined(VISKORES_ICC)
2869 return word != 0 ? _bit_scan_forward(word) + 1 : 0;
2880 while ((word & 0x1) == 0)
2889 #endif // CUDA_DEVICE_PASS
2893 #ifdef VISKORES_CUDA_DEVICE_PASS
2900 return __ffsll(
static_cast<long long int>(word));
2902 #else // CUDA_DEVICE_PASS
2906 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG) || defined(VISKORES_ICC)
2909 return __builtin_ffsll(
static_cast<long long int>(word));
2911 # elif defined(VISKORES_MSVC)
2915 return _BitScanForward64(
reinterpret_cast<DWORD*
>(&firstSet), word) != 0
2927 while ((word & 0x1) == 0)
2936 #endif // CUDA_DEVICE_PASS
2939 #ifdef VISKORES_CUDA_DEVICE_PASS
2944 return __popc(word);
2946 #else // CUDA_DEVICE_PASS
2950 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG)
2952 return __builtin_popcount(word);
2954 # elif defined(VISKORES_MSVC) && !defined(_M_ARM64)
2958 # elif defined(VISKORES_ICC)
2960 return _popcnt32(
static_cast<int>(word));
2978 #endif // CUDA_DEVICE_PASS
2981 #ifdef VISKORES_CUDA_DEVICE_PASS
2986 return __popcll(word);
2988 #else // CUDA_DEVICE_PASS
2992 # if defined(VISKORES_GCC) || defined(VISKORES_CLANG)
2994 return __builtin_popcountll(word);
2996 # elif defined(VISKORES_MSVC) && !defined(_M_ARM64)
3000 # elif defined(VISKORES_ICC)
3020 #endif // CUDA_DEVICE_PASS
3025 #endif //viskores_Math_h