From e9f584a91fc9b6996c4510a4588f70aa40164c6b Mon Sep 17 00:00:00 2001 From: Li-Ta Lo Date: Tue, 2 Jun 2020 11:58:57 -0600 Subject: [PATCH] ArrayHandleRandomUniformReal Add an ArrayHandle for generating random Float64 in the range of [0, 1). --- vtkm/cont/ArrayHandleRandomUniformBits.h | 6 +- vtkm/cont/ArrayHandleRandomUniformReal.h | 58 +++++++++++++++++++ vtkm/cont/CMakeLists.txt | 1 + vtkm/cont/testing/CMakeLists.txt | 1 + .../UnitTestArrayHandleRandomUniformReal.cxx | 28 +++++++++ vtkm/random/Philox.h | 2 +- 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 vtkm/cont/ArrayHandleRandomUniformReal.h create mode 100644 vtkm/cont/testing/UnitTestArrayHandleRandomUniformReal.cxx diff --git a/vtkm/cont/ArrayHandleRandomUniformBits.h b/vtkm/cont/ArrayHandleRandomUniformBits.h index feb243c78..a7c17caef 100644 --- a/vtkm/cont/ArrayHandleRandomUniformBits.h +++ b/vtkm/cont/ArrayHandleRandomUniformBits.h @@ -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 #include @@ -96,4 +96,4 @@ namespace cont } } // namespace vtkm::cont /// @endcond -#endif //vtk_m_cont_ArrayHandlePhiloxURBG_h +#endif //vtk_m_cont_ArrayHandleRandomUniformBits_h diff --git a/vtkm/cont/ArrayHandleRandomUniformReal.h b/vtkm/cont/ArrayHandleRandomUniformReal.h new file mode 100644 index 000000000..544397a5a --- /dev/null +++ b/vtkm/cont/ArrayHandleRandomUniformReal.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 +#include + +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(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 +{ +public: + using SeedType = vtkm::Vec; + + VTKM_ARRAY_HANDLE_SUBCLASS_NT( + ArrayHandleRandomUniformReal, + (vtkm::cont::ArrayHandleTransform)); + + 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 diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index cbb47aff3..d7494af09 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -33,6 +33,7 @@ set(headers ArrayHandlePermutation.h ArrayHandleReverse.h ArrayHandleRandomUniformBits.h + ArrayHandleRandomUniformReal.h ArrayHandleSOA.h ArrayHandleSwizzle.h ArrayHandleTransform.h diff --git a/vtkm/cont/testing/CMakeLists.txt b/vtkm/cont/testing/CMakeLists.txt index 0fb27dc53..a73c57b07 100644 --- a/vtkm/cont/testing/CMakeLists.txt +++ b/vtkm/cont/testing/CMakeLists.txt @@ -48,6 +48,7 @@ set(unit_tests UnitTestArrayHandleReverse.cxx UnitTestArrayHandlePermutation.cxx UnitTestArrayHandleRandomUniformBits.cxx + UnitTestArrayHandleRandomUniformReal.cxx UnitTestArrayHandleSwizzle.cxx UnitTestArrayHandleThreadSafety.cxx UnitTestArrayHandleTransform.cxx diff --git a/vtkm/cont/testing/UnitTestArrayHandleRandomUniformReal.cxx b/vtkm/cont/testing/UnitTestArrayHandleRandomUniformReal.cxx new file mode 100644 index 000000000..d64df4e69 --- /dev/null +++ b/vtkm/cont/testing/UnitTestArrayHandleRandomUniformReal.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 +#include + +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); +} diff --git a/vtkm/random/Philox.h b/vtkm/random/Philox.h index 413d1933b..8b2a981d6 100644 --- a/vtkm/random/Philox.h +++ b/vtkm/random/Philox.h @@ -18,7 +18,7 @@ namespace random { namespace detail { -VTKM_EXEC_CONT vtkm::Vec mulhilo(vtkm::UInt32 a, vtkm::UInt32 b) +static inline VTKM_EXEC_CONT vtkm::Vec mulhilo(vtkm::UInt32 a, vtkm::UInt32 b) { vtkm::UInt64 r = static_cast(a) * b; auto lo = static_cast(r);