/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/ck_tile/host/fill.hpp Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/ck_tile/host/fill.hpp Source File#

Composable Kernel: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/ck_tile/host/fill.hpp Source File
fill.hpp
Go to the documentation of this file.
1 // Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
2 // SPDX-License-Identifier: MIT
3 
4 #pragma once
5 
6 #include <algorithm>
7 #include <cmath>
8 #include <iterator>
9 #include <optional>
10 #include <random>
11 #include <stdexcept>
12 #include <type_traits>
13 #include <utility>
14 #include <unordered_set>
15 
16 #include "ck_tile/core.hpp"
18 
19 namespace ck_tile {
20 
38 template <typename T = void>
40 {
41  float a_{-5.f};
42  float b_{5.f};
43  std::optional<uint32_t> seed_{11939};
44 
45  template <typename ForwardIter>
46  void operator()(ForwardIter first, ForwardIter last) const
47  {
48  if(first == last)
49  return;
50  using T_iter = std::decay_t<decltype(*first)>;
51  static_assert(std::is_same_v<T, T_iter> || std::is_void_v<T>,
52  "Iterator value type must match template type T");
53  constexpr auto PackedSize = numeric_traits<T_iter>::PackedSize;
54  const auto total = static_cast<size_t>(std::distance(first, last));
55  const auto total_bytes = total * sizeof(T_iter);
56 
57  // max 80 threads; at least 2MB per thread
58  const size_t available_cpu_cores = get_available_cpu_cores();
59  constexpr uint64_t MAX_THREAD_COUNT = 80;
60  const size_t num_thread = min(
61  MAX_THREAD_COUNT, available_cpu_cores, integer_divide_ceil(total_bytes, 0x200000UL));
62  constexpr size_t BLOCK_BYTES = 64;
63  constexpr size_t BLOCK_SIZE = BLOCK_BYTES / sizeof(T_iter);
64  const size_t num_blocks = integer_divide_ceil(total_bytes, BLOCK_BYTES);
65  const size_t blocks_per_thread = integer_divide_ceil(num_blocks, num_thread);
66 
67  // use minstd_rand for better performance on discard()
68  std::minstd_rand gen(seed_.has_value() ? *seed_ : std::random_device{}());
69  std::uniform_real_distribution<float> dis(a_, b_);
70 
71  std::vector<joinable_thread> threads;
72  threads.reserve(num_thread - 1); // last job run in the main thread
73  for(int it = num_thread - 1; it >= 0; --it)
74  {
75  const size_t ib_begin = it * blocks_per_thread;
76  const size_t ib_end = min(ib_begin + blocks_per_thread, num_blocks);
77 
78  auto job = [=]() {
79  auto g_ = gen; // copy
80  auto d_ = dis; // copy
81  g_.discard(ib_begin * BLOCK_SIZE * PackedSize);
82  auto t_fn = [&]() {
83  if constexpr(PackedSize == 2)
84  return type_convert<T_iter>(fp32x2_t{d_(g_), d_(g_)});
85  else
86  return type_convert<T_iter>(d_(g_));
87  };
88 
89  size_t ib = ib_begin;
90  for(; ib < ib_end - 1; ++ib) // full blocks
91  static_for<0, BLOCK_SIZE, 1>{}([&](auto iw_) {
92  constexpr size_t iw = iw_.value;
93  *(first + ib * BLOCK_SIZE + iw) = t_fn();
94  });
95  for(size_t iw = 0; iw < BLOCK_SIZE; ++iw) // last block
96  if(ib * BLOCK_SIZE + iw < total)
97  *(first + ib * BLOCK_SIZE + iw) = t_fn();
98  };
99 
100  if(it > 0)
101  threads.emplace_back(std::move(job));
102  else
103  job(); // last job run in the main thread
104  }
105  }
106 
107  template <typename ForwardRange>
108  auto operator()(ForwardRange&& range) const
109  -> std::void_t<decltype(std::declval<const FillUniformDistribution&>()(
110  std::begin(std::forward<ForwardRange>(range)),
111  std::end(std::forward<ForwardRange>(range))))>
112  {
113  (*this)(std::begin(std::forward<ForwardRange>(range)),
114  std::end(std::forward<ForwardRange>(range)));
115  }
116 };
117 
118 template <>
120 {
121  float a_{-8.f}; // same type as primary template so that
122  // `FillUniformDistribution<Type>{-5.0f, 5.0f}` works for all types
123  float b_{7.f};
124  std::optional<uint32_t> seed_{11939};
125  template <typename ForwardIter>
126  void operator()(ForwardIter first, ForwardIter last) const
127  {
128  if(a_ < -8.0f || b_ > 7.0f)
129  {
130  throw std::runtime_error(
131  "a_ or b_ of FillUniformDistribution<ck_tile::pk_int4_t> is out of range.");
132  }
133 
134  int min_value = static_cast<int>(a_);
135  int max_value = static_cast<int>(b_);
136  constexpr auto int4_array = std::array<uint8_t, 16>{0x88,
137  0x99,
138  0xaa,
139  0xbb,
140  0xcc,
141  0xdd,
142  0xee,
143  0xff,
144  0x00,
145  0x11,
146  0x22,
147  0x33,
148  0x44,
149  0x55,
150  0x66,
151  0x77};
152  std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}());
153  std::uniform_int_distribution<std::int32_t> dis(0, max_value - min_value + 1);
154  while(first != last)
155  {
156  int randomInt = dis(gen);
157  *first = int4_array[randomInt + (min_value + 8)];
158  ++first;
159  }
160  }
161  template <typename ForwardRange>
162  auto operator()(ForwardRange&& range) const
163  -> std::void_t<decltype(std::declval<const FillUniformDistribution&>()(
164  std::begin(std::forward<ForwardRange>(range)),
165  std::end(std::forward<ForwardRange>(range))))>
166  {
167  (*this)(std::begin(std::forward<ForwardRange>(range)),
168  std::end(std::forward<ForwardRange>(range)));
169  }
170 };
171 
172 namespace impl {
173 
174 // clang-format off
175 template<index_t bytes> struct RawIntegerType_ {};
176 template<> struct RawIntegerType_<1> { using type = uint8_t;};
177 template<> struct RawIntegerType_<2> { using type = uint16_t;};
178 template<> struct RawIntegerType_<4> { using type = uint32_t;};
179 template<> struct RawIntegerType_<8> { using type = uint64_t;};
180 // clang-format on
181 
182 template <typename T>
183 using RawIntegerType = typename RawIntegerType_<sizeof(T)>::type;
184 } // namespace impl
185 
186 // Note: this struct will have no const-ness will generate random
187 template <typename T>
189 {
190  float a_{-5.f};
191  float b_{5.f};
192  std::optional<uint32_t> seed_{11939};
193 
194  std::mt19937 gen_{};
195  std::unordered_set<impl::RawIntegerType<T>> set_{};
196 
198  float b = 5.f,
199  std::optional<uint32_t> seed = {11939})
200  : a_(a),
201  b_(b),
202  seed_(seed),
203  gen_{seed_.has_value() ? *seed_ : std::random_device{}()},
204  set_{}
205  {
206  }
207 
208  template <typename ForwardIter>
209  void operator()(ForwardIter first, ForwardIter last)
210  {
211  std::mt19937& gen = gen_;
212  std::uniform_real_distribution<float> dis(a_, b_);
213  auto& set = set_;
214  std::generate(first, last, [&dis, &gen, &set]() {
215  T v = static_cast<T>(0);
216  do
217  {
218  v = ck_tile::type_convert<T>(dis(gen));
219  } while(set.count(bit_cast<impl::RawIntegerType<T>>(v)) == 1);
220  set.insert(bit_cast<impl::RawIntegerType<T>>(v));
221 
222  return v;
223  });
224  }
225 
226  template <typename ForwardRange>
227  auto operator()(ForwardRange&& range)
228  -> std::void_t<decltype(std::declval<FillUniformDistribution_Unique&>()(
229  std::begin(std::forward<ForwardRange>(range)),
230  std::end(std::forward<ForwardRange>(range))))>
231  {
232  (*this)(std::begin(std::forward<ForwardRange>(range)),
233  std::end(std::forward<ForwardRange>(range)));
234  }
235 
236  void clear() { set_.clear(); }
237 };
238 
239 template <typename T>
241 {
242  float mean_{0.f};
243  float variance_{1.f};
244  std::optional<uint32_t> seed_{11939};
245  // ATTENTION: threaded does not guarantee the distribution between thread
246  bool threaded = false;
247 
248  template <typename ForwardIter>
249  void operator()(ForwardIter first, ForwardIter last) const
250  {
251  if(threaded)
252  {
253  uint32_t num_thread = std::thread::hardware_concurrency();
254  auto total = static_cast<std::size_t>(std::distance(first, last));
255  auto work_per_thread = static_cast<std::size_t>((total + num_thread - 1) / num_thread);
256 
257  std::vector<joinable_thread> threads(num_thread);
258  for(std::size_t it = 0; it < num_thread; ++it)
259  {
260  std::size_t iw_begin = it * work_per_thread;
261  std::size_t iw_end = std::min((it + 1) * work_per_thread, total);
262  auto thread_f = [this, total, iw_begin, iw_end, &first] {
263  if(iw_begin > total || iw_end > total)
264  return;
265  // need to make each thread unique, add an offset to current seed
266  std::mt19937 gen(seed_.has_value() ? (*seed_ + iw_begin)
267  : std::random_device{}());
268  std::normal_distribution<float> dis(mean_, std::sqrt(variance_));
269  std::generate(first + iw_begin, first + iw_end, [&dis, &gen]() {
270  return ck_tile::type_convert<T>(dis(gen));
271  });
272  };
273  threads[it] = joinable_thread(thread_f);
274  }
275  }
276  else
277  {
278  std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}());
279  std::normal_distribution<float> dis(mean_, std::sqrt(variance_));
280  std::generate(
281  first, last, [&dis, &gen]() { return ck_tile::type_convert<T>(dis(gen)); });
282  }
283  }
284 
285  template <typename ForwardRange>
286  auto operator()(ForwardRange&& range) const
287  -> std::void_t<decltype(std::declval<const FillNormalDistribution&>()(
288  std::begin(std::forward<ForwardRange>(range)),
289  std::end(std::forward<ForwardRange>(range))))>
290  {
291  (*this)(std::begin(std::forward<ForwardRange>(range)),
292  std::end(std::forward<ForwardRange>(range)));
293  }
294 };
295 
296 // Normally FillUniformDistributionIntegerValue should use std::uniform_int_distribution as below.
297 // However this produces segfaults in std::mt19937 which look like inifite loop.
298 // template <typename T>
299 // struct FillUniformDistributionIntegerValue
300 // {
301 // int a_{-5};
302 // int b_{5};
303 //
304 // template <typename ForwardIter>
305 // void operator()(ForwardIter first, ForwardIter last) const
306 // {
307 // std::mt19937 gen(11939);
308 // std::uniform_int_distribution<int> dis(a_, b_);
309 // std::generate(
310 // first, last, [&dis, &gen]() { return ck_tile::type_convert<T>(dis(gen)); });
311 // }
312 // };
313 
314 // Workaround for uniform_int_distribution not working as expected. See note above.<
315 template <typename T>
317 {
318  float a_{-5.f};
319  float b_{5.f};
320  std::optional<uint32_t> seed_{11939};
321 
322  template <typename ForwardIter>
323  void operator()(ForwardIter first, ForwardIter last) const
324  {
325  std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}());
326  std::uniform_real_distribution<float> dis(a_, b_);
327  std::generate(
328  first, last, [&dis, &gen]() { return ck_tile::type_convert<T>(std::round(dis(gen))); });
329  }
330 
331  template <typename ForwardRange>
332  auto operator()(ForwardRange&& range) const
333  -> std::void_t<decltype(std::declval<const FillUniformDistributionIntegerValue&>()(
334  std::begin(std::forward<ForwardRange>(range)),
335  std::end(std::forward<ForwardRange>(range))))>
336  {
337  (*this)(std::begin(std::forward<ForwardRange>(range)),
338  std::end(std::forward<ForwardRange>(range)));
339  }
340 };
341 
342 template <typename T>
344 {
345  float mean_{0.f};
346  float variance_{1.f};
347  std::optional<uint32_t> seed_{11939};
348 
349  template <typename ForwardIter>
350  void operator()(ForwardIter first, ForwardIter last) const
351  {
352  std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}());
353  std::normal_distribution<float> dis(mean_, std::sqrt(variance_));
354  std::generate(
355  first, last, [&dis, &gen]() { return ck_tile::type_convert<T>(std::round(dis(gen))); });
356  }
357 
358  template <typename ForwardRange>
359  auto operator()(ForwardRange&& range) const
360  -> std::void_t<decltype(std::declval<const FillNormalDistributionIntegerValue&>()(
361  std::begin(std::forward<ForwardRange>(range)),
362  std::end(std::forward<ForwardRange>(range))))>
363  {
364  (*this)(std::begin(std::forward<ForwardRange>(range)),
365  std::end(std::forward<ForwardRange>(range)));
366  }
367 };
368 
369 template <typename T>
371 {
373  T step_{1};
374 
375  template <typename ForwardIter>
376  void operator()(ForwardIter first, ForwardIter last) const
377  {
378  std::generate(first, last, [=, *this, n = init_value_]() mutable {
379  auto tmp = n;
380  if constexpr(std::is_same_v<decltype(tmp), pk_int4_t>)
381  {
382  n.data += step_.data;
383  }
384  else
385  {
386  n += step_;
387  }
388  return tmp;
389  });
390  }
391 
392  template <typename ForwardRange>
393  auto operator()(ForwardRange&& range) const
394  -> std::void_t<decltype(std::declval<const FillMonotonicSeq&>()(
395  std::begin(std::forward<ForwardRange>(range)),
396  std::end(std::forward<ForwardRange>(range))))>
397  {
398  (*this)(std::begin(std::forward<ForwardRange>(range)),
399  std::end(std::forward<ForwardRange>(range)));
400  }
401 };
402 
403 template <typename T, bool IsAscending = true>
405 {
406  float start_value_{0};
407  float end_value_{3};
408  float step_{1};
409 
410  template <typename ForwardIter>
411  void operator()(ForwardIter first, ForwardIter last) const
412  {
413  std::generate(first, last, [=, *this, n = start_value_]() mutable {
414  auto tmp = n;
415  n += step_;
416  if constexpr(IsAscending)
417  {
418  if(n > end_value_)
419  n = start_value_;
420  }
421  else
422  {
423  if(n < end_value_)
424  n = start_value_;
425  }
426 
427  return type_convert<T>(tmp);
428  });
429  }
430 
431  template <typename ForwardRange>
432  auto operator()(ForwardRange&& range) const
433  -> std::void_t<decltype(std::declval<const FillStepRange&>()(
434  std::begin(std::forward<ForwardRange>(range)),
435  std::end(std::forward<ForwardRange>(range))))>
436  {
437  (*this)(std::begin(std::forward<ForwardRange>(range)),
438  std::end(std::forward<ForwardRange>(range)));
439  }
440 };
441 
442 template <typename T>
444 {
445  T value_{0};
446 
447  template <typename ForwardIter>
448  void operator()(ForwardIter first, ForwardIter last) const
449  {
450  std::fill(first, last, value_);
451  }
452 
453  template <typename ForwardRange>
454  auto operator()(ForwardRange&& range) const
455  -> std::void_t<decltype(std::declval<const FillConstant&>()(
456  std::begin(std::forward<ForwardRange>(range)),
457  std::end(std::forward<ForwardRange>(range))))>
458  {
459  (*this)(std::begin(std::forward<ForwardRange>(range)),
460  std::end(std::forward<ForwardRange>(range)));
461  }
462 };
463 
464 //----------------------------------------------------------------------------------------------
467 template <typename T>
469 {
470  size_t start{0};
471  // masks represent all valid 2:4 structured sparsity permutations
472  // clang-format off
473  static constexpr int32_t masks[] = {0, 0, 1, 1,
474  0, 1, 0, 1,
475  0, 1, 1, 0,
476  1, 0, 0, 1,
477  1, 0, 1, 0,
478  1, 1, 0, 0,
479  0, 0, 0, 1,
480  0, 0, 1, 0,
481  0, 1, 0, 0,
482  1, 0, 0, 0};
483  // clang-format on
484 
485  template <typename ForwardIter>
486  void operator()(ForwardIter first, ForwardIter last) const
487  {
488  std::transform(first, last, first, [=, *this, index = start](T val) mutable {
489  auto tmp = val * masks[index % (sizeof(masks) / sizeof(int32_t))];
490  index += 1;
491 
492  return type_convert<T>(tmp);
493  });
494  }
495 
496  template <typename ForwardRange>
497  auto operator()(ForwardRange&& range) const
498  -> std::void_t<decltype(std::declval<const AdjustToStructuredSparsity&>()(
499  std::begin(std::forward<ForwardRange>(range)),
500  std::end(std::forward<ForwardRange>(range))))>
501  {
502  (*this)(std::begin(std::forward<ForwardRange>(range)),
503  std::end(std::forward<ForwardRange>(range)));
504  }
505 };
506 
507 template <typename T, bool UseCos = true, bool UseAbs = false>
509 {
510  template <typename T_, bool UseCos_ = true, bool UseAbs_ = false>
512  {
513  int i{0};
514  auto operator()()
515  {
516  float v = 0;
517  if constexpr(UseCos_)
518  {
519  v = cos(i);
520  }
521  else
522  {
523  v = sin(i);
524  }
525  if constexpr(UseAbs_)
526  v = abs(v);
527  i++;
528  return ck_tile::type_convert<T_>(v);
529  }
530  };
531  template <typename ForwardIter>
532  void operator()(ForwardIter first, ForwardIter last) const
533  {
535  std::generate(first, last, gen);
536  }
537 
538  template <typename ForwardRange>
539  auto operator()(ForwardRange&& range) const
540  -> std::void_t<decltype(std::declval<const FillTrigValue&>()(
541  std::begin(std::forward<ForwardRange>(range)),
542  std::end(std::forward<ForwardRange>(range))))>
543  {
544  (*this)(std::begin(std::forward<ForwardRange>(range)),
545  std::end(std::forward<ForwardRange>(range)));
546  }
547 };
548 
549 } // namespace ck_tile
__host__ constexpr __device__ T min(T x)
Definition: math.hpp:116
auto fill(OutputRange &&range, const T &init) -> std::void_t< decltype(std::fill(std::begin(std::forward< OutputRange >(range)), std::end(std::forward< OutputRange >(range)), init))>
Definition: algorithm.hpp:25
auto transform(InputRange &&range, OutputIterator iter, UnaryOperation unary_op) -> decltype(std::transform(std::begin(range), std::end(range), iter, unary_op))
Definition: algorithm.hpp:36
typename RawIntegerType_< sizeof(T)>::type RawIntegerType
Definition: fill.hpp:183
Definition: cluster_descriptor.hpp:13
constexpr CK_TILE_HOST_DEVICE auto integer_divide_ceil(X x, Y y)
Definition: math.hpp:145
constexpr CK_TILE_HOST_DEVICE Y bit_cast(const X &x)
Definition: bit_cast.hpp:11
CK_TILE_HOST T cos(T x)
Definition: math.hpp:745
float fp32x2_t
Definition: bfloat16.hpp:434
CK_TILE_HOST T sin(T x)
Definition: math.hpp:691
int32_t int32_t
Definition: integer.hpp:10
CK_TILE_HOST_DEVICE bfloat16_t abs(const bfloat16_t &x)
Definition: bfloat16.hpp:403
unsigned int get_available_cpu_cores()
Definition: joinable_thread.hpp:31
constexpr CK_TILE_HOST_DEVICE T min(T x)
Definition: math.hpp:206
constexpr bool is_same_v
Definition: type.hpp:283
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1517
unsigned short uint16_t
Definition: stdint.h:125
unsigned int uint32_t
Definition: stdint.h:126
unsigned char uint8_t
Definition: stdint.h:124
unsigned __int64 uint64_t
Definition: stdint.h:136
Transforms given input to fit 2:4 structured sparsity pattern so every subgroup of 4 elements contain...
Definition: fill.hpp:469
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const AdjustToStructuredSparsity & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:497
size_t start
Definition: fill.hpp:470
static constexpr int32_t masks[]
Definition: fill.hpp:473
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:486
Definition: fill.hpp:444
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillConstant & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:454
T value_
Definition: fill.hpp:445
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:448
Definition: fill.hpp:371
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillMonotonicSeq & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:393
T init_value_
Definition: fill.hpp:372
T step_
Definition: fill.hpp:373
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:376
Definition: fill.hpp:241
std::optional< uint32_t > seed_
Definition: fill.hpp:244
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:249
float variance_
Definition: fill.hpp:243
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillNormalDistribution & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:286
bool threaded
Definition: fill.hpp:246
float mean_
Definition: fill.hpp:242
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:350
float mean_
Definition: fill.hpp:345
float variance_
Definition: fill.hpp:346
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillNormalDistributionIntegerValue & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:359
std::optional< uint32_t > seed_
Definition: fill.hpp:347
Definition: fill.hpp:405
float end_value_
Definition: fill.hpp:407
float start_value_
Definition: fill.hpp:406
float step_
Definition: fill.hpp:408
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:411
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillStepRange & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:432
int i
Definition: fill.hpp:513
auto operator()()
Definition: fill.hpp:514
Definition: fill.hpp:509
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:532
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillTrigValue & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:539
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:126
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillUniformDistribution & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:162
void operator()(ForwardIter first, ForwardIter last)
Definition: fill.hpp:209
std::optional< uint32_t > seed_
Definition: fill.hpp:192
float a_
Definition: fill.hpp:190
FillUniformDistribution_Unique(float a=-5.f, float b=5.f, std::optional< uint32_t > seed={11939})
Definition: fill.hpp:197
auto operator()(ForwardRange &&range) -> std::void_t< decltype(std::declval< FillUniformDistribution_Unique & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:227
std::mt19937 gen_
Definition: fill.hpp:194
void clear()
Definition: fill.hpp:236
float b_
Definition: fill.hpp:191
std::unordered_set< impl::RawIntegerType< T > > set_
Definition: fill.hpp:195
Definition: fill.hpp:40
float b_
Definition: fill.hpp:42
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:46
float a_
Definition: fill.hpp:41
std::optional< uint32_t > seed_
Definition: fill.hpp:43
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillUniformDistribution & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:108
std::optional< uint32_t > seed_
Definition: fill.hpp:320
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const FillUniformDistributionIntegerValue & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:332
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:323
float b_
Definition: fill.hpp:319
float a_
Definition: fill.hpp:318
uint8_t type
Definition: fill.hpp:176
uint16_t type
Definition: fill.hpp:177
uint32_t type
Definition: fill.hpp:178
uint64_t type
Definition: fill.hpp:179
Definition: fill.hpp:175
Definition: joinable_thread.hpp:15
Definition: numeric.hpp:81
Definition: pk_int4.hpp:21
Definition: functional.hpp:43