Add statistics base testing, add Flot32 RNG

This commit is contained in:
Li-Ta Lo 2020-06-17 12:01:10 -06:00
parent b8f5e9f080
commit e69308047b
3 changed files with 45 additions and 9 deletions

@ -45,7 +45,9 @@ struct PhiloxFunctor
}
private:
const SeedType Seed{};
// This is logically a const, however, this make the Functor non-copyable which is required
// by VTKm infrastructure (e.g. ArrayHandleTransform.)
SeedType Seed{};
}; // class PhiloxFunctor
} // namespace detail

@ -20,7 +20,11 @@ namespace cont
namespace detail
{
struct CanonicalFunctor
template <typename Real>
struct CanonicalFunctor;
template <>
struct CanonicalFunctor<vtkm::Float64>
{
/// \brief VTKm's equivalent of std::generate_canonical, turning a random bit source into
/// random real number in the range of [0, 1).
@ -32,23 +36,37 @@ struct CanonicalFunctor
VTKM_EXEC_CONT
vtkm::Float64 operator()(vtkm::UInt64 bits) const { return (bits & MASK) / DIVISOR; }
};
template <>
struct CanonicalFunctor<vtkm::Float32>
{
// We take 24 bits (number of bits in mantissa in a double) from the 32 bits random source
// and divide it by (1 << 24).
static constexpr vtkm::Float32 DIVISOR = static_cast<vtkm::Float32>(vtkm::UInt32{ 1 } << 24);
static constexpr vtkm::UInt32 MASK = (vtkm::UInt32{ 1 } << 24) - vtkm::UInt32{ 1 };
VTKM_EXEC_CONT
vtkm::Float32 operator()(vtkm::UInt32 bits) const { return (bits & MASK) / DIVISOR; }
};
} // detail
template <typename Real = vtkm::Float64>
class VTKM_ALWAYS_EXPORT ArrayHandleRandomUniformReal
: public vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleRandomUniformBits,
detail::CanonicalFunctor>
detail::CanonicalFunctor<Real>>
{
public:
using SeedType = vtkm::Vec<vtkm::UInt32, 1>;
VTKM_ARRAY_HANDLE_SUBCLASS_NT(
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleRandomUniformReal,
(ArrayHandleRandomUniformReal<Real>),
(vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleRandomUniformBits,
detail::CanonicalFunctor>));
detail::CanonicalFunctor<Real>>));
explicit ArrayHandleRandomUniformReal(vtkm::Id length, SeedType seed = { std::random_device{}() })
: Superclass(vtkm::cont::ArrayHandleRandomUniformBits{ length, seed },
detail::CanonicalFunctor{})
detail::CanonicalFunctor<Real>{})
{
}
};

@ -10,10 +10,12 @@
#include <vtkm/cont/ArrayHandleRandomUniformReal.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/DescriptiveStatistics.h>
void TestArrayHandleUniformReal()
void TestRangeBounds()
{
auto array = vtkm::cont::ArrayHandleRandomUniformReal(10);
// the random numbers should fall into the range of [0, 1).
auto array = vtkm::cont::ArrayHandleRandomUniformReal<vtkm::Float32>(1000000);
for (vtkm::Id i = 0; i < array.GetNumberOfValues(); ++i)
{
auto value = array.ReadPortal().Get(i);
@ -21,8 +23,22 @@ void TestArrayHandleUniformReal()
}
}
void TestStatisticsProperty()
{
auto array = vtkm::cont::ArrayHandleRandomUniformReal<vtkm::Float32>(1000000);
auto result = vtkm::worklet::DescriptiveStatistics::Run(array);
VTKM_TEST_ASSERT(test_equal(result.Mean(), 0.5, 0.001));
VTKM_TEST_ASSERT(test_equal(result.SampleVariance(), 1.0 / 12.0, 0.001));
}
void TestArrayHandleUniformReal()
{
TestRangeBounds();
TestStatisticsProperty();
}
int UnitTestArrayHandleRandomUniformReal(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestArrayHandleUniformReal, argc, argv);
}