vtkm::Math now doesn't require boost

This commit is contained in:
Robert Maynard 2016-09-02 13:32:26 -04:00
parent 12a0afa773
commit 801473bc58
2 changed files with 444 additions and 397 deletions

File diff suppressed because it is too large Load Diff

@ -32,7 +32,7 @@ $# expander.py Math.h.in > Math.h
$#
$# Ignore the following comment. It is meant for the generated file.
// **** DO NOT EDIT THIS FILE!!! ****
// This file is automatically generated by FunctionInterfaceDetailPre.h.in
// This file is automatically generated by Math.h.in
#ifndef vtk_m_Math_h
#define vtk_m_Math_h
@ -45,52 +45,32 @@ $# Ignore the following comment. It is meant for the generated file.
#include <limits.h>
#include <math.h>
#include <stdlib.h>
// The nonfinite and sign test functions are usually defined as macros, and
// boost seems to want to undefine those macros so that it can implement the
// C99 templates and other implementations of the same name. Get around the
// problem by using the boost version when compiling for a CPU.
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <cmath>
#define VTKM_USE_BOOST_CLASSIFY
#define VTKM_USE_BOOST_SIGN
#endif // !VTKM_CUDA
#if !defined(__CUDA_ARCH__)
#define VTKM_USE_STL_MIN_MAX
#define VTKM_USE_STL
#include <algorithm>
#endif
#if defined(VTKM_MSVC) && !defined(VTKM_CUDA)
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/math/special_functions/acosh.hpp>
#include <boost/math/special_functions/asinh.hpp>
#include <boost/math/special_functions/atanh.hpp>
#include <boost/math/special_functions/cbrt.hpp>
#include <boost/math/special_functions/expm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/round.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#define VTKM_USE_BOOST_MATH
#if (_MSC_VER <= 1600) && !defined(VTKM_USE_STL_MIN_MAX)
#define VTKM_USE_STL_MIN_MAX
#include <algorithm>
#endif
#include <math.h>
#endif
#define VTKM_SYS_MATH_FUNCTION_32(func) func ## f
#define VTKM_SYS_MATH_FUNCTION_64(func) func
#define VTKM_CUDA_MATH_FUNCTION_32(func) func ## f
#define VTKM_CUDA_MATH_FUNCTION_64(func) func
$py(
def unary_function(name, type, returntype, expression):
def unary_function(name, type, returntype, cuda_expression, std_expression):
return '''VTKM_EXEC_CONT_EXPORT
{2} {0}({1} x) {{
#ifdef VTKM_CUDA
return {3};
#else
return {4};
#endif
}}
'''.format(name, type, returntype, expression)
'''.format(name, type, returntype, cuda_expression, std_expression)
def unary_Vec_function(vtkmname):
return '''template<typename T, vtkm::IdComponent N>
@ -130,11 +110,13 @@ def unary_math_function_no_vec(vtkmname, sysname, returntype = None):
return unary_function(vtkmname,
'vtkm::Float32',
'vtkm::Float32' if returntype == None else returntype,
'VTKM_SYS_MATH_FUNCTION_32(' + sysname + ')(x)') + \
'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x)',
'std::' + sysname + '(x)') + \
unary_function(vtkmname,
'vtkm::Float64',
'vtkm::Float64' if returntype == None else returntype,
'VTKM_SYS_MATH_FUNCTION_64(' + sysname + ')(x)')
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x)',
'std::' + sysname + '(x)')
def unary_math_function(vtkmname, sysname):
return unary_math_function_no_vec(vtkmname, sysname) + \
@ -161,20 +143,26 @@ def unary_template_function_no_vec(vtkmname,
'vtkm::Float64' if returntype == None else returntype,
preexpression)
def binary_function(name, type, expression):
def binary_function(name, type, cuda_expression, std_expression):
return '''VTKM_EXEC_CONT_EXPORT
{1} {0}({1} x, {1} y) {{
#ifdef VTKM_CUDA
return {2};
#else
return {3};
#endif
}}
'''.format(name, type, expression)
'''.format(name, type, cuda_expression, std_expression)
def binary_math_function(vtkmname, sysname):
return binary_function(vtkmname,
'vtkm::Float32',
'VTKM_SYS_MATH_FUNCTION_32(' + sysname + ')(x,y)') + \
'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x,y)',
'std::' + sysname + '(x,y)') + \
binary_function(vtkmname,
'vtkm::Float64',
'VTKM_SYS_MATH_FUNCTION_64(' + sysname + ')(x,y)')
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x,y)',
'std::' + sysname + '(x,y)')
def binary_template_function(vtkmname, expression):
return '''VTKM_EXEC_CONT_EXPORT
@ -279,35 +267,20 @@ $unary_math_function('TanH', 'tanh')\
/// Compute the hyperbolic arc sine of \p x.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('ASinH', 'boost::math::asinh(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('ASinH', 'asinh')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('ASinH')\
/// Compute the hyperbolic arc cosine of \p x.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('ACosH', 'boost::math::acosh(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('ACosH', 'acosh')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('ACosH')\
/// Compute the hyperbolic arc tangent of \p x.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('ATanH', 'boost::math::atanh(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('ATanH', 'atanh')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('ATanH')\
//-----------------------------------------------------------------------------
@ -325,23 +298,31 @@ $unary_math_function('Sqrt', 'sqrt')\
/// should use this function whenever dividing by the square root.
///
#ifdef VTKM_CUDA
$unary_math_function_no_vec('RSqrt', 'rsqrt')\
$#
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 RSqrt(vtkm::Float32 x) {
return rsqrtf(x);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 RSqrt(vtkm::Float64 x) {
return rsqrt(x);
}
#else // !VTKM_CUDA
$unary_template_function_no_vec('RSqrt', '1/vtkm::Sqrt(x)')\
$#
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 RSqrt(vtkm::Float32 x) {
return 1/vtkm::Sqrt(x);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 RSqrt(vtkm::Float64 x) {
return 1/vtkm::Sqrt(x);
}
#endif // !VTKM_CUDA
$unary_Vec_function('RSqrt')\
/// Compute the cube root of \p x.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('Cbrt', 'boost::math::cbrt(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('Cbrt', 'cbrt')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('Cbrt')\
/// Compute the reciprocal cube root of \p x. The result of this function is
@ -350,12 +331,25 @@ $unary_Vec_function('Cbrt')\
/// should use this function whenever dividing by the cube root.
///
#ifdef VTKM_CUDA
$unary_math_function_no_vec('RCbrt', 'rcbrt')\
$#
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 RCbrt(vtkm::Float32 x) {
return rcbrtf(x);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 RCbrt(vtkm::Float64 x) {
return rcbrt(x);
}
#else // !VTKM_CUDA
$unary_template_function_no_vec('RCbrt', '1/vtkm::Cbrt(x)')\
$#
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 RCbrt(vtkm::Float32 x) {
return 1/vtkm::Cbrt(x);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 RCbrt(vtkm::Float64 x) {
return 1/vtkm::Cbrt(x);
}
#endif // !VTKM_CUDA
$unary_Vec_function('RCbrt')\
/// Computes e**\p x, the base-e exponential of \p x.
@ -364,36 +358,39 @@ $unary_math_function('Exp', 'exp')\
/// Computes 2**\p x, the base-2 exponential of \p x.
///
#ifdef VTKM_MSVC
$unary_template_function_no_vec('Exp2', 'vtkm::Pow(2,x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('Exp2', 'exp2')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('Exp2')\
/// Computes (e**\p x) - 1, the of base-e exponental of \p x then minus 1. The
/// accuracy of this function is good even for very small values of x.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('ExpM1', 'boost::math::expm1(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('ExpM1', 'expm1')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('ExpM1')\
/// Computes 10**\p x, the base-10 exponential of \p x.
///
#ifdef VTKM_CUDA
$unary_math_function_no_vec('Exp10', 'exp10')\
$#
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 Exp10(vtkm::Float32 x) {
return exp10f(x);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 Exp10(vtkm::Float64 x) {
return exp10(x);
}
#else // !VTKM_CUDA
$unary_template_function_no_vec('Exp10', 'vtkm::Pow(10, x);')\
$#
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 Exp10(vtkm::Float32 x) {
return vtkm::Pow(10, x);;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 Exp10(vtkm::Float64 x) {
return vtkm::Pow(10, x);;
}
#endif // !VTKM_CUDA
$unary_Vec_function('Exp10')\
/// Computes the natural logarithm of \p x.
@ -402,25 +399,8 @@ $unary_math_function('Log', 'log')\
/// Computes the logarithm base 2 of \p x.
///
#ifdef VTKM_MSVC
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 Log2(vtkm::Float32 x) {
//windows and boost don't provide log2
//0.6931471805599453 is the constant value of log(2)
const vtkm::Float32 log2v = 0.6931471805599453f;
return vtkm::Log(x)/log2v;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 Log2(vtkm::Float64 x) {
//windows and boost don't provide log2
//0.6931471805599453 is the constant value of log(2)
const vtkm::Float64 log2v = 0.6931471805599453;
return vtkm::Log(x)/log2v;
}
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('Log2', 'log2')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('Log2')\
/// Computes the logarithm base 10 of \p x.
@ -429,13 +409,8 @@ $unary_math_function('Log10', 'log10')\
/// Computes the value of log(1+x) accurately for very small values of x.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('Log1P', 'boost::math::log1p(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('Log1P', 'log1p')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('Log1P')\
//-----------------------------------------------------------------------------
@ -444,26 +419,26 @@ $unary_Vec_function('Log1P')\
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Max(const T &x, const T &y);
#ifdef VTKM_USE_STL_MIN_MAX
#ifdef VTKM_USE_STL
$binary_template_function('Max', '(std::max)(x, y)')\
$#
#else // !VTKM_USE_STL_MIN_MAX
#else // !VTKM_USE_STL
$binary_math_function('Max', 'fmax')\
$#
#endif // !VTKM_USE_STL_MIN_MAX
#endif // !VTKM_USE_STL
/// Returns \p x or \p y, whichever is smaller.
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Min(const T &x, const T &y);
#ifdef VTKM_USE_STL_MIN_MAX
#ifdef VTKM_USE_STL
$binary_template_function('Min', '(std::min)(x, y)')\
$#
#else // !VTKM_USE_STL_MIN_MAX
#else // !VTKM_USE_STL
$binary_math_function('Min', 'fmin')\
$#
#endif // !VTKM_USE_STL_MIN_MAX
#endif // !VTKM_USE_STL
namespace detail {
@ -754,9 +729,7 @@ template<typename T>
VTKM_EXEC_CONT_EXPORT
bool IsNan(T x)
{
#ifdef VTKM_USE_BOOST_CLASSIFY
using boost::math::isnan;
#endif
using std::isnan;
return (isnan(x) != 0);
}
@ -766,9 +739,7 @@ template<typename T>
VTKM_EXEC_CONT_EXPORT
bool IsInf(T x)
{
#ifdef VTKM_USE_BOOST_CLASSIFY
using boost::math::isinf;
#endif
using std::isinf;
return (isinf(x) != 0);
}
@ -778,9 +749,7 @@ template<typename T>
VTKM_EXEC_CONT_EXPORT
bool IsFinite(T x)
{
#ifdef VTKM_USE_BOOST_CLASSIFY
using boost::math::isfinite;
#endif
using std::isfinite;
return (isfinite(x) != 0);
}
@ -795,13 +764,8 @@ $unary_math_function('Floor', 'floor')\
/// Round \p x to the nearest integral value.
///
#ifdef VTKM_USE_BOOST_MATH
$unary_template_function_no_vec('Round', 'boost::math::round(x)')\
$#
#else // !VTKM_USE_BOOST_MATH
$unary_math_function_no_vec('Round', 'round')\
$#
#endif // !VTKM_USE_BOOST_MATH
$unary_Vec_function('Round')\
//-----------------------------------------------------------------------------
@ -841,16 +805,10 @@ vtkm::Float32 RemainderQuotient(vtkm::Float32 numerator,
vtkm::Float32 denominator,
QType &quotient)
{
#ifdef VTKM_USE_BOOST_MATH
quotient = static_cast<QType>(boost::math::round(numerator/denominator));
return vtkm::Remainder(numerator, denominator);
#else
int iQuotient;
vtkm::Float32 result =
VTKM_SYS_MATH_FUNCTION_32(remquo)(numerator, denominator, &iQuotient);
vtkm::Float32 result = std::remquo(numerator, denominator, &iQuotient);
quotient = iQuotient;
return result;
#endif
}
template<typename QType>
VTKM_EXEC_CONT_EXPORT
@ -858,16 +816,10 @@ vtkm::Float64 RemainderQuotient(vtkm::Float64 numerator,
vtkm::Float64 denominator,
QType &quotient)
{
#ifdef VTKM_USE_BOOST_MATH
quotient = static_cast<QType>(boost::math::round(numerator/denominator));
return vtkm::Remainder(numerator, denominator);
#else
int iQuotient;
vtkm::Float64 result =
VTKM_SYS_MATH_FUNCTION_64(remquo)(numerator, denominator, &iQuotient);
vtkm::Float64 result = std::remquo(numerator, denominator, &iQuotient);
quotient = iQuotient;
return result;
#endif
}
/// Gets the integral and fractional parts of \c x. The return value is the
@ -876,12 +828,12 @@ vtkm::Float64 RemainderQuotient(vtkm::Float64 numerator,
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 ModF(vtkm::Float32 x, vtkm::Float32 &integral)
{
return VTKM_SYS_MATH_FUNCTION_32(modf)(x, &integral);
return std::modf(x, &integral);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Float64 ModF(vtkm::Float64 x, vtkm::Float64 &integral)
{
return VTKM_SYS_MATH_FUNCTION_64(modf)(x, &integral);
return std::modf(x, &integral);
}
//-----------------------------------------------------------------------------
@ -915,9 +867,8 @@ $unary_math_function('Abs', 'fabs')\
$unary_template_function_no_vec('SignBit',
'static_cast<vtkm::Int32>(signbit(x))',
'vtkm::Int32',
'''#ifdef VTKM_USE_BOOST_SIGN
using boost::math::signbit;
#endif
'''
using std::signbit;
''')\
/// Returns true if \p x is less than zero, false otherwise.
@ -927,13 +878,9 @@ $unary_template_function_no_vec('IsNegative', '(vtkm::SignBit(x) != 0)', 'bool')
/// Copies the sign of \p y onto \p x. If \p y is positive, returns Abs(\p x).
/// If \p y is negative, returns -Abs(\p x).
///
#ifdef VTKM_USE_BOOST_SIGN
$binary_template_function('CopySign', 'boost::math::copysign(x,y)')\
$#
#else // !VTKM_USE_BOOST_SIGN
$binary_math_function('CopySign', 'copysign')\
$#
#endif // !VTKM_USE_BOOST_SIGN
template<typename T, vtkm::IdComponent N>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T,N> CopySign(const vtkm::Vec<T,N> &x, const vtkm::Vec<T,N> &y)