mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 21:33:55 +00:00
Allow for different types in basic type operators
The basic type operators in `Types.h` (i.e. `vtkm::Add`, `vtkm::Subtract`, `vtkm::Multiply` and `vtkm::Divide`) required the same type for both arguments. This caused problems when used with `Reduce` and the initial value type did not match exactly. Use some tricks from `BinaryOperators.h` to be flexible about using different types.
This commit is contained in:
parent
58bd890c9c
commit
d9c988b200
68
vtkm/Types.h
68
vtkm/Types.h
@ -221,37 +221,81 @@ struct NullType
|
|||||||
#endif // gcc || clang
|
#endif // gcc || clang
|
||||||
struct Add
|
struct Add
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
inline VTKM_EXEC_CONT T operator()(const T& a, const T& b) const
|
inline VTKM_EXEC_CONT auto operator()(const T& a, const U& b) const -> decltype(a + b)
|
||||||
{
|
{
|
||||||
return T(a + b);
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both arguments are short integers, explicitly cast the result back to the
|
||||||
|
// type to avoid narrowing conversion warnings from operations that promote to
|
||||||
|
// integers.
|
||||||
|
template <typename T>
|
||||||
|
inline VTKM_EXEC_CONT
|
||||||
|
typename std::enable_if<std::is_integral<T>::value && sizeof(T) < sizeof(int), T>::type
|
||||||
|
operator()(T a, T b) const
|
||||||
|
{
|
||||||
|
return static_cast<T>(a + b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Subtract
|
struct Subtract
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
inline VTKM_EXEC_CONT T operator()(const T& a, const T& b) const
|
inline VTKM_EXEC_CONT auto operator()(const T& a, const U& b) const -> decltype(a - b)
|
||||||
{
|
{
|
||||||
return T(a - b);
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both arguments are short integers, explicitly cast the result back to the
|
||||||
|
// type to avoid narrowing conversion warnings from operations that promote to
|
||||||
|
// integers.
|
||||||
|
template <typename T>
|
||||||
|
inline VTKM_EXEC_CONT
|
||||||
|
typename std::enable_if<std::is_integral<T>::value && sizeof(T) < sizeof(int), T>::type
|
||||||
|
operator()(T a, T b) const
|
||||||
|
{
|
||||||
|
return static_cast<T>(a - b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Multiply
|
struct Multiply
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
inline VTKM_EXEC_CONT T operator()(const T& a, const T& b) const
|
inline VTKM_EXEC_CONT auto operator()(const T& a, const U& b) const -> decltype(a * b)
|
||||||
{
|
{
|
||||||
return T(a * b);
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both arguments are short integers, explicitly cast the result back to the
|
||||||
|
// type to avoid narrowing conversion warnings from operations that promote to
|
||||||
|
// integers.
|
||||||
|
template <typename T>
|
||||||
|
inline VTKM_EXEC_CONT
|
||||||
|
typename std::enable_if<std::is_integral<T>::value && sizeof(T) < sizeof(int), T>::type
|
||||||
|
operator()(T a, T b) const
|
||||||
|
{
|
||||||
|
return static_cast<T>(a * b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Divide
|
struct Divide
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
inline VTKM_EXEC_CONT T operator()(const T& a, const T& b) const
|
inline VTKM_EXEC_CONT auto operator()(const T& a, const U& b) const -> decltype(a / b)
|
||||||
{
|
{
|
||||||
return T(a / b);
|
return a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both arguments are short integers, explicitly cast the result back to the
|
||||||
|
// type to avoid narrowing conversion warnings from operations that promote to
|
||||||
|
// integers.
|
||||||
|
template <typename T>
|
||||||
|
inline VTKM_EXEC_CONT
|
||||||
|
typename std::enable_if<std::is_integral<T>::value && sizeof(T) < sizeof(int), T>::type
|
||||||
|
operator()(T a, T b) const
|
||||||
|
{
|
||||||
|
return static_cast<T>(a / b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1332,17 +1332,17 @@ private:
|
|||||||
|
|
||||||
//the output of reduce and scan inclusive should be the same
|
//the output of reduce and scan inclusive should be the same
|
||||||
std::cout << " Reduce with initial value of 0." << std::endl;
|
std::cout << " Reduce with initial value of 0." << std::endl;
|
||||||
vtkm::Id reduce_sum = Algorithm::Reduce(array, vtkm::Id(0));
|
vtkm::Id reduce_sum = Algorithm::Reduce(array, 0);
|
||||||
std::cout << " Reduce with initial value." << std::endl;
|
std::cout << " Reduce with initial value." << std::endl;
|
||||||
vtkm::Id reduce_sum_with_intial_value = Algorithm::Reduce(array, vtkm::Id(ARRAY_SIZE));
|
vtkm::Id reduce_sum_with_intial_value = Algorithm::Reduce(array, vtkm::Id(ARRAY_SIZE));
|
||||||
std::cout << " Inclusive scan to check" << std::endl;
|
std::cout << " Inclusive scan to check" << std::endl;
|
||||||
vtkm::Id inclusive_sum = Algorithm::ScanInclusive(array, array);
|
vtkm::Id inclusive_sum = Algorithm::ScanInclusive(array, array);
|
||||||
std::cout << " Reduce with 1 value." << std::endl;
|
std::cout << " Reduce with 1 value." << std::endl;
|
||||||
array.Allocate(1, vtkm::CopyFlag::On);
|
array.Allocate(1, vtkm::CopyFlag::On);
|
||||||
vtkm::Id reduce_sum_one_value = Algorithm::Reduce(array, vtkm::Id(0));
|
vtkm::Id reduce_sum_one_value = Algorithm::Reduce(array, 0);
|
||||||
std::cout << " Reduce with 0 values." << std::endl;
|
std::cout << " Reduce with 0 values." << std::endl;
|
||||||
array.Allocate(0);
|
array.Allocate(0);
|
||||||
vtkm::Id reduce_sum_no_values = Algorithm::Reduce(array, vtkm::Id(0));
|
vtkm::Id reduce_sum_no_values = Algorithm::Reduce(array, 0);
|
||||||
VTKM_TEST_ASSERT(reduce_sum == OFFSET * ARRAY_SIZE, "Got bad sum from Reduce");
|
VTKM_TEST_ASSERT(reduce_sum == OFFSET * ARRAY_SIZE, "Got bad sum from Reduce");
|
||||||
VTKM_TEST_ASSERT(reduce_sum_with_intial_value == reduce_sum + ARRAY_SIZE,
|
VTKM_TEST_ASSERT(reduce_sum_with_intial_value == reduce_sum + ARRAY_SIZE,
|
||||||
"Got bad sum from Reduce with initial value");
|
"Got bad sum from Reduce with initial value");
|
||||||
|
Loading…
Reference in New Issue
Block a user