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