FloatPointReturnType is float if 'T' is < 32bytes instead of being double.

Previously FloatPointReturnType would always be double for types that
are not float, which caused Int8/Int16 types to promote to double instead
of float.
This commit is contained in:
Robert Maynard 2018-01-04 13:19:39 -05:00
parent 842019023a
commit a9e64c4ba8
4 changed files with 282 additions and 369 deletions

File diff suppressed because it is too large Load Diff

@ -108,28 +108,30 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
}}
'''.format(vtkmname)
def unary_math_function_no_vec(vtkmname, sysname, returntype = None):
return unary_function(vtkmname,
'T',
'typename detail::FloatingPointReturnType<T>::Type' if returntype == None else returntype,
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(static_cast<vtkm::Float64>(x))',
'std::' + sysname + '(static_cast<vtkm::Float64>(x))',
'template <typename T>',
'static inline') + \
unary_function(vtkmname,
'vtkm::Float32',
'detail::FloatingPointReturnType<vtkm::Float32>::Type' if returntype == None else returntype,
'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x)',
'std::' + sysname + '(x)',
'template <>',
'inline') + \
unary_function(vtkmname,
'vtkm::Float64',
'detail::FloatingPointReturnType<vtkm::Float64>::Type' if returntype == None else returntype,
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x)',
'std::' + sysname + '(x)',
'template <>',
'inline')
def unary_math_function_no_vec(vtkmname, sysname):
general_type = '''template <typename T>
static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type {0}(const T& x)
{{
using RT = typename detail::FloatingPointReturnType<T>::Type;
return vtkm::{0}(static_cast<RT>(x));
}}
'''.format(vtkmname)
specialization_types = unary_function(vtkmname,
'vtkm::Float32',
'vtkm::Float32',
'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x)',
'std::' + sysname + '(x)',
'',
'inline')
specialization_types += unary_function(vtkmname,
'vtkm::Float64',
'vtkm::Float64',
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x)',
'std::' + sysname + '(x)',
'',
'inline')
return specialization_types + general_type
def unary_math_function(vtkmname, sysname):
return unary_math_function_no_vec(vtkmname, sysname) + \
@ -235,25 +237,15 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Pi_4()
namespace detail
{
template <typename T>
struct FloatingPointReturnCondition
: std::enable_if<
std::is_same<typename vtkm::VecTraits<T>::ComponentType, vtkm::Float32>::value ||
std::is_same<typename vtkm::VecTraits<T>::ComponentType, const vtkm::Float32>::value>
{
};
template <typename T, typename = void>
struct FloatingPointReturnType
{
using Type = vtkm::Float64;
};
template <typename T>
struct FloatingPointReturnType<T, typename FloatingPointReturnCondition<T>::type>
{
using Type = vtkm::Float32;
using ctype = typename vtkm::VecTraits<T>::ComponentType;
using representable_as_float_type =
std::integral_constant<bool,
((sizeof(ctype) < sizeof(float)) || std::is_same<ctype, vtkm::Float32>::value)>;
using Type =
typename std::conditional<representable_as_float_type::value, vtkm::Float32, vtkm::Float64>::type;
};
} // namespace detail

@ -71,9 +71,10 @@ VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value
/// when possible.
///
template <typename T>
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::ComponentType MagnitudeSquared(const T& x)
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type MagnitudeSquared(const T& x)
{
return vtkm::dot(x, x);
using U = typename detail::FloatingPointReturnType<T>::Type;
return static_cast<U>(vtkm::dot(x, x));
}
// ----------------------------------------------------------------------------

@ -38,7 +38,7 @@ public:
template <typename T, typename T2>
VTKM_EXEC void operator()(const T& inValue, T2& outValue) const
{
outValue = vtkm::Magnitude(inValue);
outValue = static_cast<T2>(vtkm::Magnitude(inValue));
}
};
}