include/ck/library/utility/fill.hpp Source File

include/ck/library/utility/fill.hpp Source File#

Composable Kernel: include/ck/library/utility/fill.hpp Source File
fill.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: MIT
2 // Copyright (c) 2018-2024, Advanced Micro Devices, Inc. All rights reserved.
3 
4 #pragma once
5 
6 #include <algorithm>
7 #include <cmath>
8 #include <iterator>
9 #include <random>
10 #include <type_traits>
11 #include <utility>
12 
13 #include "ck/utility/data_type.hpp"
14 
15 namespace ck {
16 namespace utils {
17 
18 template <typename T>
20 {
21  float a_{-5.f};
22  float b_{5.f};
23 
24  template <typename ForwardIter>
25  void operator()(ForwardIter first, ForwardIter last) const
26  {
27  std::mt19937 gen(11939);
28  std::uniform_real_distribution<float> dis(a_, b_);
29  std::generate(first, last, [&dis, &gen]() { return ck::type_convert<T>(dis(gen)); });
30  }
31 
32  template <typename ForwardRange>
33  auto operator()(ForwardRange&& range) const
34  -> std::void_t<decltype(std::declval<const FillUniformDistribution&>()(
35  std::begin(std::forward<ForwardRange>(range)),
36  std::end(std::forward<ForwardRange>(range))))>
37  {
38  (*this)(std::begin(std::forward<ForwardRange>(range)),
39  std::end(std::forward<ForwardRange>(range)));
40  }
41 };
42 
43 // Normally FillUniformDistributionIntegerValue should use std::uniform_int_distribution as below.
44 // However this produces segfaults in std::mt19937 which look like inifite loop.
45 // template <typename T>
46 // struct FillUniformDistributionIntegerValue
47 // {
48 // int a_{-5};
49 // int b_{5};
50 //
51 // template <typename ForwardIter>
52 // void operator()(ForwardIter first, ForwardIter last) const
53 // {
54 // std::mt19937 gen(11939);
55 // std::uniform_int_distribution<int> dis(a_, b_);
56 // std::generate(
57 // first, last, [&dis, &gen]() { return ck::type_convert<T>(dis(gen)); });
58 // }
59 // };
60 
61 // Workaround for uniform_int_distribution not working as expected. See note above.<
62 template <typename T>
64 {
65  float a_{-5.f};
66  float b_{5.f};
67 
68  template <typename ForwardIter>
69  void operator()(ForwardIter first, ForwardIter last) const
70  {
71  std::mt19937 gen(11939);
72  std::uniform_real_distribution<float> dis(a_, b_);
73  std::generate(
74  first, last, [&dis, &gen]() { return ck::type_convert<T>(std::round(dis(gen))); });
75  }
76 
77  template <typename ForwardRange>
78  auto operator()(ForwardRange&& range) const
79  -> std::void_t<decltype(std::declval<const FillUniformDistributionIntegerValue&>()(
80  std::begin(std::forward<ForwardRange>(range)),
81  std::end(std::forward<ForwardRange>(range))))>
82  {
83  (*this)(std::begin(std::forward<ForwardRange>(range)),
84  std::end(std::forward<ForwardRange>(range)));
85  }
86 };
87 
88 template <typename T>
90 {
92  T step_{1};
93 
94  template <typename ForwardIter>
95  void operator()(ForwardIter first, ForwardIter last) const
96  {
97  std::generate(first, last, [=, n = init_value_]() mutable {
98  auto tmp = n;
99  n += step_;
100  return tmp;
101  });
102  }
103 
104  template <typename ForwardRange>
105  auto operator()(ForwardRange&& range) const
106  -> std::void_t<decltype(std::declval<const FillMonotonicSeq&>()(
107  std::begin(std::forward<ForwardRange>(range)),
108  std::end(std::forward<ForwardRange>(range))))>
109  {
110  (*this)(std::begin(std::forward<ForwardRange>(range)),
111  std::end(std::forward<ForwardRange>(range)));
112  }
113 };
114 
115 template <typename T>
117 {
118  T value_{0};
119 
120  template <typename ForwardIter>
121  void operator()(ForwardIter first, ForwardIter last) const
122  {
123  std::fill(first, last, value_);
124  }
125 
126  template <typename ForwardRange>
127  auto operator()(ForwardRange&& range) const -> std::void_t<
128  decltype(std::declval<const FillConstant&>()(std::begin(std::forward<ForwardRange>(range)),
129  std::end(std::forward<ForwardRange>(range))))>
130  {
131  (*this)(std::begin(std::forward<ForwardRange>(range)),
132  std::end(std::forward<ForwardRange>(range)));
133  }
134 };
135 
136 template <typename T>
138 {
139  // clang-format off
140  static constexpr T valid_sequences[] = {
141  0, 0, 1, 1,
142  0, 1, 0, 1,
143  0, 1, 1, 0,
144  1, 0, 0, 1,
145  1, 0, 1, 0,
146  1, 1, 0, 0,
147  };
148  // clang-format on
149 
150  template <typename ForwardIter>
151  void operator()(ForwardIter first, ForwardIter last) const
152  {
153  std::for_each(first, last, [=, idx = 0](T& elem) mutable {
154  auto tmp_idx = idx;
155  idx += 1;
156  return elem *= valid_sequences[tmp_idx % (sizeof(valid_sequences) / sizeof(T))];
157  });
158  }
159 
160  template <typename ForwardRange>
161  auto operator()(ForwardRange&& range) const
162  -> std::void_t<decltype(std::declval<const TransformIntoStructuralSparsity&>()(
163  std::begin(std::forward<ForwardRange>(range)),
164  std::end(std::forward<ForwardRange>(range))))>
165  {
166  (*this)(std::begin(std::forward<ForwardRange>(range)),
167  std::end(std::forward<ForwardRange>(range)));
168  }
169 };
170 
171 } // namespace utils
172 } // namespace ck
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
Definition: ck.hpp:264
Definition: fill.hpp:117
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:127
T value_
Definition: fill.hpp:118
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:121
Definition: fill.hpp:90
T step_
Definition: fill.hpp:92
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:105
T init_value_
Definition: fill.hpp:91
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:95
Definition: fill.hpp:20
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:33
float a_
Definition: fill.hpp:21
float b_
Definition: fill.hpp:22
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:25
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:78
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:69
static constexpr T valid_sequences[]
Definition: fill.hpp:140
void operator()(ForwardIter first, ForwardIter last) const
Definition: fill.hpp:151
auto operator()(ForwardRange &&range) const -> std::void_t< decltype(std::declval< const TransformIntoStructuralSparsity & >()(std::begin(std::forward< ForwardRange >(range)), std::end(std::forward< ForwardRange >(range))))>
Definition: fill.hpp:161