32 #ifndef MCKL_RANDOM_SEED_HPP 33 #define MCKL_RANDOM_SEED_HPP 42 #ifndef MCKL_SEED_RANDOMIZE 43 #define MCKL_SEED_RANDOMIZE 1 48 #ifndef MCKL_SEED_ATOMIC 49 #define MCKL_SEED_ATOMIC 1 56 template <
typename ResultType,
57 typename ID = std::integral_constant<std::size_t, sizeof(ResultType)>,
58 #if MCKL_SEED_RANDOMIZE 59 bool Randomize =
true,
61 bool Randomize =
false,
71 static_assert(
sizeof(ResultType) %
sizeof(
std::uint32_t) == 0,
72 "**SeedGenerator** size of ResultType is not a multiple of uint32_t");
77 std::conditional_t<
sizeof(ResultType) %
sizeof(
std::uint64_t) == 0,
99 result_type get() {
return get(std::integral_constant<bool, (M_ > 1)>()); }
110 partition(np, rank, std::integral_constant<
bool, (M_ > 1)>());
113 template <
typename CharT,
typename Traits>
115 std::basic_ostream<CharT, Traits> &os,
123 os << sg.rank_ <<
' ';
124 os << sg.maxs_ <<
' ';
125 os << sg.seed_ <<
' ';
130 template <
typename CharT,
typename Traits>
132 std::basic_istream<CharT, Traits> &is,
144 is >> std::ws >>
rank;
145 is >> std::ws >> maxs;
146 is >> std::ws >> seed;
164 std::conditional_t<Atomic, std::atomic<seed_type>,
seed_type> seed_;
172 maxs_ = std::numeric_limits<seed_type>::max();
178 "**SeedGenerator::partition** the number of the partitions is " 185 "**SeedGenerator::partition** the rank is not smaller than the " 186 "number of partitions");
191 seed_type maxs = std::numeric_limits<seed_type>::max();
193 maxs = (maxs -
rank) / np + 1;
204 std::array<seed_type, M_> k = {{0}};
208 return randomize(k, std::integral_constant<bool, Randomize>());
217 std::array<seed_type, M_> k = {{s}};
219 return randomize(k, std::integral_constant<bool, Randomize>());
222 result_type randomize(
const std::array<seed_type, M_> &k, std::false_type)
225 std::array<seed_type, M_> k;
230 internal::union_le<seed_type>(buf.result);
235 result_type randomize(
const std::array<seed_type, M_> &k, std::true_type)
238 std::integral_constant<
int,
239 std::numeric_limits<seed_type>::digits * M_>());
244 const std::array<seed_type, M_> &k, std::integral_constant<int, D>)
247 std::array<char, sizeof(seed_type) * M_> state;
248 std::array<seed_type, M_> k;
253 internal::union_le<seed_type>(buf.state);
256 internal::union_le<char>(buf.result);
262 const std::array<seed_type, M_> &k, std::integral_constant<int, 32>)
265 std::array<std::uint16_t, 2> state;
266 std::array<seed_type, M_> k;
271 internal::union_le<seed_type>(buf.state);
272 std::uint16_t x = std::get<0>(buf.state);
273 std::uint16_t y = std::get<1>(buf.state);
274 for (
int i = 0; i != 22; ++i) {
275 x =
static_cast<std::uint16_t
>((x << 9) | (x >> 7));
277 y =
static_cast<std::uint16_t
>((y << 2) | (y >> 14));
280 std::get<0>(buf.state) = x;
281 std::get<1>(buf.state) = y;
282 internal::union_le<std::uint16_t>(buf.result);
288 const std::array<seed_type, M_> &k, std::integral_constant<int, 64>)
290 return randomize<Threefry2x32>(k);
294 const std::array<seed_type, M_> &k, std::integral_constant<int, 128>)
296 return randomize<Threefry2x64>(k);
300 const std::array<seed_type, M_> &k, std::integral_constant<int, 256>)
302 return randomize<Threefry4x64>(k);
306 const std::array<seed_type, M_> &k, std::integral_constant<int, 512>)
308 return randomize<Threefry8x64>(k);
312 const std::array<seed_type, M_> &k, std::integral_constant<int, 1024>)
314 return randomize<Threefry16x64>(k);
317 template <
typename RNGType>
318 result_type randomize(
const std::array<seed_type, M_> &k)
321 std::array<char, sizeof(seed_type) * M_> state;
322 std::array<seed_type, M_> k;
327 internal::union_le<seed_type>(buf.state);
329 rng.generator()(buf.state.data(), buf.state.data());
330 internal::union_le<char>(buf.result);
338 template <
typename RNGType>
345 #endif // MCKL_RANDOM_SEED_HPP void partition(seed_type np, seed_type rank)
Set the number of partitions and the rank of this partition.
SeedGenerator< ResultType, ID, Randomize, Atomic > & operator=(const SeedGenerator< ResultType, ID, Randomize, Atomic > &)=delete
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, SeedGenerator< ResultType, ID, Randomize, Atomic > &sg)
seed_type np() const
The number of partitions.
const char * data() const
The address of the string.
static SeedGenerator< ResultType, ID, Randomize, Atomic > & instance()
seed_type rank() const
The rank of this partition.
static void hash(const param_type &M, std::size_t N, void *H)
Simple hashing.
std::conditional_t< sizeof(ResultType) % sizeof(std::uint64_t)==0, std::uint64_t, std::uint32_t > seed_type
The type of the internal seed.
SeedType< RNGType > result_type
Type of input paramters such as keys and messages.
RNG default seed generator.
void runtime_assert(bool cond, const char *msg, bool soft=false)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const SeedGenerator< ResultType, ID, Randomize, Atomic > &sg)