Viskores  1.0
Philox.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_random_Philox_h
19 #define viskores_random_Philox_h
20 
21 #include <viskores/Types.h>
22 
23 namespace viskores
24 {
25 namespace random
26 {
27 namespace detail
28 {
31 {
32  viskores::UInt64 r = static_cast<viskores::UInt64>(a) * b;
33  auto lo = static_cast<viskores::UInt32>(r);
34  viskores::UInt32 hi = static_cast<viskores::UInt32>(r >> 32);
35  return { lo, hi };
36 }
37 
38 template <typename UIntType, std::size_t N, UIntType... consts>
39 struct philox_parameters;
40 
41 template <typename T, T M0, T C0>
42 struct philox_parameters<T, 2, M0, C0>
43 {
44  static constexpr Vec<T, 1> multipliers = { M0 };
45  static constexpr Vec<T, 1> round_consts = { C0 };
46 };
47 
48 template <typename T, T M0, T C0, T M1, T C1>
49 struct philox_parameters<T, 4, M0, C0, M1, C1>
50 {
51  static constexpr viskores::Vec<T, 2> multipliers = { M0, M1 };
52  static constexpr viskores::Vec<T, 2> round_consts = { C0, C1 };
53 };
54 
55 template <typename UIntType, std::size_t N, std::size_t R, UIntType... consts>
56 class philox_functor;
57 
58 template <typename UIntType, std::size_t R, UIntType... consts>
59 class philox_functor<UIntType, 2, R, consts...>
60 {
61 public:
62  using counters_type = viskores::Vec<UIntType, 2>;
63  using keys_type = viskores::Vec<UIntType, 1>;
64 
65  VISKORES_EXEC_CONT counters_type operator()(counters_type counters, keys_type keys) const
66  {
67  for (std::size_t i = 0; i < R; ++i)
68  {
69  counters = round(counters, keys);
70  keys = bump_keys(keys);
71  }
72  return counters;
73  }
74 
75 private:
76  static VISKORES_EXEC_CONT counters_type round(counters_type counters, keys_type round_keys)
77  {
78  auto constexpr multipliers = philox_parameters<UIntType, 2, consts...>::multipliers;
79  viskores::Vec<UIntType, 2> r = mulhilo(multipliers[0], counters[0]);
80  return { r[1] ^ round_keys[0] ^ counters[1], r[0] };
81  }
82 
83  static VISKORES_EXEC_CONT keys_type bump_keys(keys_type keys)
84  {
85  auto constexpr round_consts = philox_parameters<UIntType, 2, consts...>::round_consts;
86  return { keys[0] + round_consts[0] };
87  }
88 };
89 
90 template <typename UIntType, std::size_t R, UIntType... consts>
91 class philox_functor<UIntType, 4, R, consts...>
92 {
93  using counters_type = viskores::Vec<UIntType, 4>;
94  using keys_type = viskores::Vec<UIntType, 2>;
95 
96  static VISKORES_EXEC_CONT counters_type round(counters_type counters, keys_type round_keys)
97  {
98  auto constexpr multipliers = philox_parameters<UIntType, 4, consts...>::multipliers;
99  viskores::Vec<UIntType, 2> r0 = mulhilo(multipliers[0], counters[0]);
100  viskores::Vec<UIntType, 2> r1 = mulhilo(multipliers[1], counters[2]);
101  return {
102  r1[1] ^ round_keys[0] ^ counters[1], r1[0], r0[1] ^ round_keys[1] ^ counters[3], r0[0]
103  };
104  }
105 
106  static VISKORES_EXEC_CONT keys_type bump_key(keys_type keys)
107  {
108  auto constexpr round_consts = philox_parameters<UIntType, 4, consts...>::round_consts;
109  keys[0] += round_consts[0];
110  keys[1] += round_consts[1];
111  return keys;
112  }
113 
114 public:
115  VISKORES_EXEC_CONT counters_type operator()(counters_type counters, keys_type keys) const
116  {
117  for (std::size_t i = 0; i < R; ++i)
118  {
119  counters = round(counters, keys);
120  keys = bump_key(keys);
121  }
122  return counters;
123  }
124 };
125 
126 } // namespace detail
127 
128 using PhiloxFunctor2x32x7 = detail::philox_functor<viskores::UInt32, 2, 7, 0xD256D193, 0x9E3779B9>;
129 using PhiloxFunctor2x32x10 =
130  detail::philox_functor<viskores::UInt32, 2, 10, 0xD256D193, 0x9E3779B9>;
131 
132 } // namespace random
133 } // namespace viskores
134 #endif //viskores_random_Philox_h
Types.h
viskores::random::PhiloxFunctor2x32x7
detail::philox_functor< viskores::UInt32, 2, 7, 0xD256D193, 0x9E3779B9 > PhiloxFunctor2x32x7
Definition: Philox.h:128
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
viskores::Vec< T, 2 >
Definition: Types.h:909
viskores::random::PhiloxFunctor2x32x10
detail::philox_functor< viskores::UInt32, 2, 10, 0xD256D193, 0x9E3779B9 > PhiloxFunctor2x32x10
Definition: Philox.h:130
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::Vec< T, 1 >
Definition: Types.h:887
viskores::UInt64
unsigned long long UInt64
Base type to use for 64-bit signed integer numbers.
Definition: Types.h:215
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
viskores::UInt32
uint32_t UInt32
Base type to use for 32-bit unsigned integer numbers.
Definition: Types.h:193