ArrayHandleRandomUniformReal

Add an ArrayHandle for generating random Float64 in the range of [0, 1).
This commit is contained in:
Li-Ta Lo 2020-06-02 11:58:57 -06:00
parent da6fc5e378
commit e9f584a91f
6 changed files with 92 additions and 4 deletions

@ -7,8 +7,8 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_cont_ArrayHandlePhiloxURBG_h
#define vtk_m_cont_ArrayHandlePhiloxURBG_h
#ifndef vtk_m_cont_ArrayHandleRandomUniformBits_h
#define vtk_m_cont_ArrayHandleRandomUniformBits_h
#include <random>
#include <vtkm/cont/ArrayHandleImplicit.h>
@ -96,4 +96,4 @@ namespace cont
}
} // namespace vtkm::cont
/// @endcond
#endif //vtk_m_cont_ArrayHandlePhiloxURBG_h
#endif //vtk_m_cont_ArrayHandleRandomUniformBits_h

@ -0,0 +1,58 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_count_ArrayHandleRandomUniformReal_h
#define vtk_m_count_ArrayHandleRandomUniformReal_h
#include <vtkm/cont/ArrayHandleRandomUniformBits.h>
#include <vtkm/cont/ArrayHandleTransform.h>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct CanonicalFunctor
{
/// \brief VTKm's equivalent of std::generate_canonical, turning a random bit source into
/// random real number in the range of [0, 1).
// We take 53 bits (number of bits in mantissa in a double) from the 64 bits random source
// and divide it by (1 << 53).
static constexpr vtkm::Float64 DIVISOR = static_cast<vtkm::Float64>(1UL << 53);
static constexpr vtkm::UInt64 MASK = (1UL << 53) - 1UL;
VTKM_EXEC_CONT
vtkm::Float64 operator()(vtkm::UInt64 bits) const { return (bits & MASK) / DIVISOR; }
};
} // detail
class VTKM_ALWAYS_EXPORT ArrayHandleRandomUniformReal
: public vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleRandomUniformBits,
detail::CanonicalFunctor>
{
public:
using SeedType = vtkm::Vec<vtkm::UInt32, 1>;
VTKM_ARRAY_HANDLE_SUBCLASS_NT(
ArrayHandleRandomUniformReal,
(vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleRandomUniformBits,
detail::CanonicalFunctor>));
explicit ArrayHandleRandomUniformReal(vtkm::Id length, SeedType seed = { std::random_device{}() })
: Superclass(vtkm::cont::ArrayHandleRandomUniformBits{ length, seed },
detail::CanonicalFunctor{})
{
}
};
} // cont
} // vtkm
#endif //vtk_m_count_ArrayHandleRandomUniformReal_h

@ -33,6 +33,7 @@ set(headers
ArrayHandlePermutation.h
ArrayHandleReverse.h
ArrayHandleRandomUniformBits.h
ArrayHandleRandomUniformReal.h
ArrayHandleSOA.h
ArrayHandleSwizzle.h
ArrayHandleTransform.h

@ -48,6 +48,7 @@ set(unit_tests
UnitTestArrayHandleReverse.cxx
UnitTestArrayHandlePermutation.cxx
UnitTestArrayHandleRandomUniformBits.cxx
UnitTestArrayHandleRandomUniformReal.cxx
UnitTestArrayHandleSwizzle.cxx
UnitTestArrayHandleThreadSafety.cxx
UnitTestArrayHandleTransform.cxx

@ -0,0 +1,28 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ArrayHandleRandomUniformReal.h>
#include <vtkm/cont/testing/Testing.h>
void TestArrayHandleUniformReal()
{
auto array = vtkm::cont::ArrayHandleRandomUniformReal(10);
for (vtkm::Id i = 0; i < array.GetNumberOfValues(); ++i)
{
auto value = array.ReadPortal().Get(i);
VTKM_TEST_ASSERT(0.0 <= value && value < 1.0);
}
}
int UnitTestArrayHandleRandomUniformReal(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestArrayHandleUniformReal, argc, argv);
}

@ -18,7 +18,7 @@ namespace random
{
namespace detail
{
VTKM_EXEC_CONT vtkm::Vec<vtkm::UInt32, 2> mulhilo(vtkm::UInt32 a, vtkm::UInt32 b)
static inline VTKM_EXEC_CONT vtkm::Vec<vtkm::UInt32, 2> mulhilo(vtkm::UInt32 a, vtkm::UInt32 b)
{
vtkm::UInt64 r = static_cast<vtkm::UInt64>(a) * b;
auto lo = static_cast<vtkm::UInt32>(r);