Skip to content

Commit

Permalink
Merge pull request #15 from cppalliance/NVRTC_6_test
Browse files Browse the repository at this point in the history
NVRTC Batch 6
  • Loading branch information
mborland authored Aug 16, 2024
2 parents 837a582 + c16413b commit cc34154
Show file tree
Hide file tree
Showing 24 changed files with 1,625 additions and 275 deletions.
5 changes: 3 additions & 2 deletions include/boost/math/policies/error_handling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <boost/math/tools/config.hpp>
#include <boost/math/tools/numeric_limits.hpp>
#include <boost/math/tools/type_traits.hpp>
#include <boost/math/tools/cstdint.hpp>

#ifndef BOOST_MATH_HAS_NVRTC

Expand Down Expand Up @@ -1017,7 +1018,7 @@ BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE R checked_narrowing_cast(T val, co
}

template <class T, class Policy>
BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function, BOOST_MATH_UINTMAX_T max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v<T>)
BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function, boost::math::uintmax_t max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v<T>)
{
if(max_iter >= policies::get_max_series_iterations<Policy>())
raise_evaluation_error<T>(
Expand All @@ -1026,7 +1027,7 @@ BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function,
}

template <class T, class Policy>
BOOST_MATH_GPU_ENABLED inline void check_root_iterations(const char* function, BOOST_MATH_UINTMAX_T max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v<T>)
BOOST_MATH_GPU_ENABLED inline void check_root_iterations(const char* function, boost::math::uintmax_t max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v<T>)
{
if(max_iter >= policies::get_max_root_iterations<Policy>())
raise_evaluation_error<T>(
Expand Down
11 changes: 6 additions & 5 deletions include/boost/math/policies/policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <boost/math/tools/mp.hpp>
#include <boost/math/tools/numeric_limits.hpp>
#include <boost/math/tools/type_traits.hpp>
#include <boost/math/tools/cstdint.hpp>

namespace boost{ namespace math{

Expand Down Expand Up @@ -313,7 +314,7 @@ class is_default_policy
};
};

template <class Seq, class T, BOOST_MATH_SIZE_T N>
template <class Seq, class T, boost::math::size_t N>
struct append_N
{
using type = typename append_N<mp::mp_push_back<Seq, T>, T, N-1>::type;
Expand Down Expand Up @@ -402,7 +403,7 @@ class policy
// Typelist of the arguments:
//
using arg_list = mp::mp_list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13>;
static constexpr BOOST_MATH_SIZE_T arg_list_size = mp::mp_size<arg_list>::value;
static constexpr boost::math::size_t arg_list_size = mp::mp_size<arg_list>::value;

template<typename A, typename B, bool b>
struct pick_arg
Expand Down Expand Up @@ -533,7 +534,7 @@ class normalise
{
private:
using arg_list = mp::mp_list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13>;
static constexpr BOOST_MATH_SIZE_T arg_list_size = mp::mp_size<arg_list>::value;
static constexpr boost::math::size_t arg_list_size = mp::mp_size<arg_list>::value;

template<typename A, typename B, bool b>
struct pick_arg
Expand Down Expand Up @@ -882,7 +883,7 @@ struct series_factor_calc<T, Digits, boost::math::true_type, boost::math::false_
{
BOOST_MATH_GPU_ENABLED static constexpr T get() noexcept(boost::math::is_floating_point<T>::value)
{
return 1 / static_cast<T>(static_cast<BOOST_MATH_UINTMAX_T>(1u) << (Digits::value - 1));
return 1 / static_cast<T>(static_cast<boost::math::uintmax_t>(1u) << (Digits::value - 1));
}
};
template <class T, class Digits>
Expand All @@ -901,7 +902,7 @@ BOOST_MATH_GPU_ENABLED constexpr T get_epsilon_imp(boost::math::true_type const&
static_assert(boost::math::numeric_limits<T>::radix == 2, "boost::math::numeric_limits<T>::radix == 2");

typedef typename boost::math::policies::precision<T, Policy>::type p_t;
typedef boost::math::integral_constant<bool, p_t::value <= boost::math::numeric_limits<BOOST_MATH_UINTMAX_T>::digits> is_small_int;
typedef boost::math::integral_constant<bool, p_t::value <= boost::math::numeric_limits<boost::math::uintmax_t>::digits> is_small_int;
typedef boost::math::integral_constant<bool, p_t::value >= boost::math::numeric_limits<T>::digits> is_default_value;
return series_factor_calc<T, p_t, is_small_int, is_default_value>::get();
}
Expand Down
68 changes: 48 additions & 20 deletions include/boost/math/special_functions/beta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,31 @@
#pragma once
#endif

#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/tools/config.hpp>
#include <boost/math/tools/type_traits.hpp>
#include <boost/math/tools/assert.hpp>
#include <boost/math/tools/precision.hpp>
#include <boost/math/tools/numeric_limits.hpp>
#include <boost/math/tools/tuple.hpp>
#include <boost/math/tools/promotion.hpp>
#include <boost/math/tools/cstdint.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <boost/math/special_functions/binomial.hpp>
#include <boost/math/special_functions/factorials.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/expm1.hpp>
#include <boost/math/special_functions/trunc.hpp>
#include <boost/math/special_functions/lanczos.hpp>
#include <boost/math/policies/policy.hpp>
#include <boost/math/policies/error_handling.hpp>
#include <boost/math/constants/constants.hpp>

#ifndef BOOST_MATH_HAS_NVRTC
#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/special_functions/binomial.hpp>
#include <boost/math/special_functions/factorials.hpp>
#include <boost/math/tools/roots.hpp>
#include <boost/math/tools/assert.hpp>
#include <cmath>
#endif

namespace boost{ namespace math{

Expand Down Expand Up @@ -124,6 +136,7 @@ BOOST_MATH_GPU_ENABLED T beta_imp(T a, T b, const Lanczos&, const Policy& pol)
// Generic implementation of Beta(a,b) without Lanczos approximation support
// (Caution this is slow!!!):
//
#ifndef BOOST_MATH_HAS_NVRTC
template <class T, class Policy>
BOOST_MATH_GPU_ENABLED T beta_imp(T a, T b, const lanczos::undefined_lanczos& l, const Policy& pol)
{
Expand Down Expand Up @@ -194,7 +207,7 @@ BOOST_MATH_GPU_ENABLED T beta_imp(T a, T b, const lanczos::undefined_lanczos& l,
}

} // template <class T>T beta_imp(T a, T b, const lanczos::undefined_lanczos& l)

#endif

//
// Compute the leading power terms in the incomplete Beta:
Expand Down Expand Up @@ -246,11 +259,11 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
// l1 and l2 are the base of the exponents minus one:
T l1 = (x * b - y * agh) / agh;
T l2 = (y * a - x * bgh) / bgh;
if(((std::min)(fabs(l1), fabs(l2)) < 0.2))
if((BOOST_MATH_GPU_SAFE_MIN(fabs(l1), fabs(l2)) < 0.2))
{
// when the base of the exponent is very near 1 we get really
// gross errors unless extra care is taken:
if((l1 * l2 > 0) || ((std::min)(a, b) < 1))
if((l1 * l2 > 0) || (BOOST_MATH_GPU_SAFE_MIN(a, b) < 1))
{
//
// This first branch handles the simple cases where either:
Expand Down Expand Up @@ -286,7 +299,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
BOOST_MATH_INSTRUMENT_VARIABLE(result);
}
}
else if((std::max)(fabs(l1), fabs(l2)) < 0.5)
else if(BOOST_MATH_GPU_SAFE_MAX(fabs(l1), fabs(l2)) < 0.5)
{
//
// Both exponents are near one and both the exponents are
Expand Down Expand Up @@ -448,6 +461,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
//
// This version is generic, slow, and does not use the Lanczos approximation.
//
#ifndef BOOST_MATH_HAS_NVRTC
template <class T, class Policy>
BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
T b,
Expand Down Expand Up @@ -484,7 +498,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
bool need_logs = false;
if (a < b)
{
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_infinity)
BOOST_MATH_IF_CONSTEXPR(boost::math::numeric_limits<T>::has_infinity)
{
power1 = pow((x * y * c * c) / (a * b), a);
power2 = pow((y * c) / b, b - a);
Expand All @@ -507,7 +521,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
}
else
{
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_infinity)
BOOST_MATH_IF_CONSTEXPR(boost::math::numeric_limits<T>::has_infinity)
{
power1 = pow((x * y * c * c) / (a * b), b);
power2 = pow((x * c) / a, a - b);
Expand All @@ -526,7 +540,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
need_logs = true;
}
}
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_infinity)
BOOST_MATH_IF_CONSTEXPR(boost::math::numeric_limits<T>::has_infinity)
{
if (!(boost::math::isnormal)(power1) || !(boost::math::isnormal)(power2))
{
Expand Down Expand Up @@ -625,6 +639,8 @@ BOOST_MATH_GPU_ENABLED T ibeta_power_terms(T a,
}
return prefix * power1 * (power2 / bet);
}

#endif
//
// Series approximation to the incomplete beta:
//
Expand Down Expand Up @@ -717,14 +733,15 @@ BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool
if(result < tools::min_value<T>())
return s0; // Safeguard: series can't cope with denorms.
ibeta_series_t<T> s(a, b, x, result);
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
boost::math::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, s0);
policies::check_series_iterations<T>("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (with lanczos)", max_iter, pol);
return result;
}
//
// Incomplete Beta series again, this time without Lanczos support:
//
#ifndef BOOST_MATH_HAS_NVRTC
template <class T, class Policy>
BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const boost::math::lanczos::undefined_lanczos& l, bool normalised, T* p_derivative, T y, const Policy& pol)
{
Expand Down Expand Up @@ -778,7 +795,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const boost::math::la
if(result < tools::min_value<T>())
return s0; // Safeguard: series can't cope with denorms.
ibeta_series_t<T> s(a, b, x, result);
std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
boost::math::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, s0);
policies::check_series_iterations<T>("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (without lanczos)", max_iter, pol);
return result;
Expand All @@ -790,7 +807,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const boost::math::la
template <class T>
struct ibeta_fraction2_t
{
typedef std::pair<T, T> result_type;
typedef boost::math::pair<T, T> result_type;

BOOST_MATH_GPU_ENABLED ibeta_fraction2_t(T a_, T b_, T x_, T y_) : a(a_), b(b_), x(x_), y(y_), m(0) {}

Expand All @@ -806,7 +823,7 @@ struct ibeta_fraction2_t

++m;

return std::make_pair(aN, bN);
return boost::math::make_pair(aN, bN);
}

private:
Expand Down Expand Up @@ -867,6 +884,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_a_step(T a, T b, T x, T y, int k, const Policy& p

return prefix;
}
#endif
//
// This function is only needed for the non-regular incomplete beta,
// it computes the delta in:
Expand Down Expand Up @@ -905,11 +923,15 @@ struct Pn_size
{
// This is likely to be enough for ~35-50 digit accuracy
// but it's hard to quantify exactly:
#ifndef BOOST_MATH_HAS_NVRTC
static constexpr unsigned value =
::boost::math::max_factorial<T>::value >= 100 ? 50
: ::boost::math::max_factorial<T>::value >= ::boost::math::max_factorial<double>::value ? 30
: ::boost::math::max_factorial<T>::value >= ::boost::math::max_factorial<float>::value ? 15 : 1;
static_assert(::boost::math::max_factorial<T>::value >= ::boost::math::max_factorial<float>::value, "Type does not provide for 35-50 digits of accuracy.");
#else
static constexpr unsigned value = 0; // Will never be called
#endif
};
template <>
struct Pn_size<float>
Expand All @@ -936,6 +958,7 @@ struct Pn_size<long double>
#endif
};

#ifndef BOOST_MATH_HAS_NVRTC
template <class T, class Policy>
BOOST_MATH_GPU_ENABLED T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Policy& pol, bool normalised)
{
Expand Down Expand Up @@ -1037,7 +1060,7 @@ BOOST_MATH_GPU_ENABLED T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T
}
return sum;
} // template <class T, class Lanczos>T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Lanczos& l, bool normalised)

#endif
//
// For integer arguments we can relate the incomplete beta to the
// complement of the binomial distribution cdf and use this finite sum.
Expand Down Expand Up @@ -1224,7 +1247,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, b
return p;
}

if((std::min)(a, b) <= 1)
if(BOOST_MATH_GPU_SAFE_MIN(a, b) <= 1)
{
if(x > 0.5)
{
Expand All @@ -1233,10 +1256,10 @@ BOOST_MATH_GPU_ENABLED T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, b
invert = !invert;
BOOST_MATH_INSTRUMENT_VARIABLE(invert);
}
if((std::max)(a, b) <= 1)
if(BOOST_MATH_GPU_SAFE_MAX(a, b) <= 1)
{
// Both a,b < 1:
if((a >= (std::min)(T(0.2), b)) || (pow(x, a) <= 0.9))
if((a >= BOOST_MATH_GPU_SAFE_MIN(T(0.2), b)) || (pow(x, a) <= 0.9))
{
if(!invert)
{
Expand Down Expand Up @@ -1405,7 +1428,7 @@ BOOST_MATH_GPU_ENABLED T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, b

if(b < 40)
{
if((floor(a) == a) && (floor(b) == b) && (a < static_cast<T>((std::numeric_limits<int>::max)() - 100)) && (y != 1))
if((floor(a) == a) && (floor(b) == b) && (a < static_cast<T>((boost::math::numeric_limits<int>::max)() - 100)) && (y != 1))
{
// relate to the binomial distribution and use a finite sum:
T k = a - 1;
Expand Down Expand Up @@ -1726,7 +1749,12 @@ BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<RT1, RT2, RT3>::type
} // namespace math
} // namespace boost

// TODO(mborland): Get the ibeta_inv working on NVRTC
#ifndef BOOST_MATH_HAS_NVRTC

#include <boost/math/special_functions/detail/ibeta_inverse.hpp>
#include <boost/math/special_functions/detail/ibeta_inv_ab.hpp>

#endif

#endif // BOOST_MATH_SPECIAL_BETA_HPP
5 changes: 3 additions & 2 deletions include/boost/math/special_functions/gamma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
#pragma once
#endif

#ifndef __CUDACC_RTC__

#include <boost/math/tools/config.hpp>

#ifndef BOOST_MATH_HAS_NVRTC

#include <boost/math/tools/series.hpp>
#include <boost/math/tools/fraction.hpp>
#include <boost/math/tools/precision.hpp>
Expand Down
Loading

0 comments on commit cc34154

Please sign in to comment.