LBANN  0.103.0
LivermoreBigArtificialNeuralNetworkToolkit
random.hpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2023, Lawrence Livermore National Security, LLC.
3 // Produced at the Lawrence Livermore National Laboratory.
4 // Written by the LBANN Research Team (B. Van Essen, et al.) listed in
5 // the CONTRIBUTORS file. <lbann-dev@llnl.gov>
6 //
7 // LLNL-CODE-697807.
8 // All rights reserved.
9 //
10 // This file is part of LBANN: Livermore Big Artificial Neural Network
11 // Toolkit. For details, see http://software.llnl.gov/LBANN or
12 // https://github.com/LLNL/LBANN.
13 //
14 // Licensed under the Apache License, Version 2.0 (the "Licensee"); you
15 // may not use this file except in compliance with the License. You may
16 // obtain a copy of the License at:
17 //
18 // http://www.apache.org/licenses/LICENSE-2.0
19 //
20 // Unless required by applicable law or agreed to in writing, software
21 // distributed under the License is distributed on an "AS IS" BASIS,
22 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
23 // implied. See the License for the specific language governing
24 // permissions and limitations under the license.
26 
27 #ifndef LBANN_UTILS_RANDOM_HPP
28 #define LBANN_UTILS_RANDOM_HPP
29 
30 #include "lbann/base.hpp"
31 #include "lbann/comm.hpp"
32 #include "lbann/io/persist.hpp"
35 
36 namespace lbann {
37 
40 {
41  invalid,
42  gaussian,
43  bernoulli,
44  uniform
45 };
46 
55 template <typename Generator, typename T>
56 inline T fast_rand_int(Generator& g, T max)
57 {
58 #ifdef LBANN_DEBUG
59  if (max == 0) {
60  LBANN_ERROR("fast_rand_int called with max=0");
61  }
62 #endif
63  typename Generator::result_type x;
64  do {
65  x = g();
66  } while (x >= (Generator::max() - Generator::max() % max));
67  return x % max;
68 }
69 
74 template <typename Generator, typename T>
75 inline T fast_rand_int_pow2(Generator& g, T max)
76 {
77  typename Generator::result_type x;
78  max -= 1;
79  const typename Generator::result_type upper =
80  Generator::max() -
81  (Generator::max() & (typename Generator::result_type)max);
82  do {
83  x = g();
84  } while (x >= upper);
85  return x & ((typename Generator::result_type)max);
86 }
87 
88 // Methods for generating uniformly random values in [0, 1).
89 
90 namespace details {
91 
95 template <typename Generator, typename T>
97 {
98  static T generate(Generator&);
99 };
100 template <typename Generator>
101 struct random_uniform_impl<Generator, float>
102 {
103  static float generate(Generator& g)
104  {
105  // float has a 24-bit significand, including an implicit bit. See
106  // section on converting uint64_ts to doubles in
107  // http://xoshiro.di.unimi.it/
108  constexpr uint64_t mask32 = 0xFFFFFFFFull;
109  const uint64_t r = uint64_t(g()) & mask32;
110  return (r >> 8) * (1.0f / 16777216.0f);
111  }
112 };
113 template <typename Generator>
114 struct random_uniform_impl<Generator, double>
115 {
116  static double generate(Generator& g)
117  {
118  // double has a 53-bit significand, including an implicit bit. See
119  // section on converting uint64_ts to doubles in
120  // http://xoshiro.di.unimi.it/
121  constexpr uint64_t mask32 = 0xFFFFFFFFull;
122  const uint64_t r = (uint64_t(g()) << 32) | (uint64_t(g()) & mask32);
123  return (r >> 11) * (1.0 / 9007199254740992.0);
124  }
125 };
126 
127 } // namespace details
128 
130 template <typename T, typename Generator>
131 inline T random_uniform(Generator& g)
132 {
134 }
135 
143 template <typename TensorDataType>
144 void gaussian_fill(El::AbstractDistMatrix<TensorDataType>& mat,
145  El::Int m,
146  El::Int n,
147  TensorDataType mean = 0.0,
148  TensorDataType stddev = 1.0);
154 template <typename TensorDataType>
155 void bernoulli_fill(El::AbstractDistMatrix<TensorDataType>& mat,
156  El::Int m,
157  El::Int n,
158  double p = 0.5);
164 template <typename TensorDataType>
165 void uniform_fill(El::AbstractDistMatrix<TensorDataType>& mat,
166  El::Int m,
167  El::Int n,
168  TensorDataType center = 0.0,
169  TensorDataType radius = 1.0);
170 
177 template <typename TensorDataType>
178 void gaussian_fill_procdet(El::AbstractDistMatrix<TensorDataType>& mat,
179  El::Int m,
180  El::Int n,
181  TensorDataType mean = 0.0,
182  TensorDataType stddev = 1.0);
188 template <typename TensorDataType>
189 void bernoulli_fill_procdet(El::AbstractDistMatrix<TensorDataType>& mat,
190  El::Int m,
191  El::Int n,
192  double p = 0.5);
198 template <typename TensorDataType>
199 void uniform_fill_procdet(El::AbstractDistMatrix<TensorDataType>& mat,
200  El::Int m,
201  El::Int n,
202  TensorDataType center = 0.0,
203  TensorDataType radius = 1.0);
204 
211 template <typename TensorDataType>
212 void gaussian_fill_parallel(El::AbstractDistMatrix<TensorDataType>& mat,
213  El::Int m,
214  El::Int n,
215  TensorDataType mean = 0.0,
216  TensorDataType stddev = 1.0);
217 
220 bool load_rng_from_checkpoint(persist& p, const lbann_comm* comm);
221 
222 template <typename DistType, typename DType = DataType>
223 class rng
224 {
225 
226 private:
227  DistType m_dist; // Distribution type
228 
229 public:
230  typename DistType::result_type gen() { return m_dist(get_generator()); }
231  rng() {}
232  // bernoulli_distribution with prob p
233  rng(DType p) : m_dist(p) {}
234  // (uniform) real distribution between min/mean and max/stdev
235  rng(DType a, DType b) : m_dist(a, b) {}
236 };
237 
241 template <typename DType = DataType>
242 void rng_bernoulli(const float p, DistMat* m)
243 {
244 
247  float scale = 1. / (1. - p);
248 
249  //@todo: use seed from parameter
250  rng<std::bernoulli_distribution, DType> myrn(p); // magic seed?
251 
252  for (int row = 0; row < m->LocalHeight(); ++row) {
253  for (int col = 0; col < m->LocalWidth(); ++col) {
254  m->Set(row, col, myrn.gen() * scale); // SetLocal?
255  }
256  }
257 }
258 
259 #ifndef LBANN_RANDOM_INSTANTIATE
260 #define PROTO(T) \
261  extern template void gaussian_fill<T>(El::AbstractDistMatrix<T> & mat, \
262  El::Int m, \
263  El::Int n, \
264  T mean, \
265  T stddev); \
266  extern template void bernoulli_fill<T>(El::AbstractDistMatrix<T> & mat, \
267  El::Int m, \
268  El::Int n, \
269  double p); \
270  extern template void uniform_fill<T>(El::AbstractDistMatrix<T> & mat, \
271  El::Int m, \
272  El::Int n, \
273  T center, \
274  T radius); \
275  extern template void gaussian_fill_procdet<T>(El::AbstractDistMatrix<T> & \
276  mat, \
277  El::Int m, \
278  El::Int n, \
279  T mean, \
280  T stddev); \
281  extern template void bernoulli_fill_procdet<T>(El::AbstractDistMatrix<T> & \
282  mat, \
283  El::Int m, \
284  El::Int n, \
285  double p); \
286  extern template void uniform_fill_procdet<T>(El::AbstractDistMatrix<T> & \
287  mat, \
288  El::Int m, \
289  El::Int n, \
290  T center, \
291  T radius); \
292  extern template void gaussian_fill_parallel<T>(El::AbstractDistMatrix<T> & \
293  mat, \
294  El::Int m, \
295  El::Int n, \
296  T mean, \
297  T stddev)
298 
299 #define LBANN_INSTANTIATE_CPU_HALF
300 #define LBANN_INSTANTIATE_GPU_HALF
302 #undef PROTO
303 #undef LBANN_INSTANTIATE_CPU_HALF
304 #undef LBANN_INSTANTIATE_GPU_HALF
305 #endif // LBANN_RANDOM_INSTANTIATE
306 
307 } // namespace lbann
308 #endif // LBANN_UTILS_RANDOM_HPP
rng(DType p)
Definition: random.hpp:233
T fast_rand_int(Generator &g, T max)
Definition: random.hpp:56
bool load_rng_from_checkpoint(persist &p, const lbann_comm *comm)
void rng_bernoulli(const float p, DistMat *m)
Definition: random.hpp:242
DistType::result_type gen()
Definition: random.hpp:230
MCMRMat< El::Device::CPU > DistMat
Definition: base.hpp:183
void uniform_fill_procdet(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, TensorDataType center=0.0, TensorDataType radius=1.0)
#define LBANN_ERROR(...)
Definition: exception.hpp:37
bool save_rng_to_checkpoint_distributed(persist &p, lbann_comm *comm)
void bernoulli_fill(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, double p=0.5)
static T generate(Generator &)
T random_uniform(Generator &g)
Generate uniform random value in the range [0, 1).
Definition: random.hpp:131
void gaussian_fill_procdet(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, TensorDataType mean=0.0, TensorDataType stddev=1.0)
bool save_rng_to_checkpoint_shared(persist &p, lbann_comm *comm)
void bernoulli_fill_procdet(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, double p=0.5)
rng(DType a, DType b)
Definition: random.hpp:235
DistType m_dist
Definition: random.hpp:227
void gaussian_fill(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, TensorDataType mean=0.0, TensorDataType stddev=1.0)
void gaussian_fill_parallel(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, TensorDataType mean=0.0, TensorDataType stddev=1.0)
rng_gen & get_generator()
probability_distribution
Definition: random.hpp:39
T fast_rand_int_pow2(Generator &g, T max)
Definition: random.hpp:75
void uniform_fill(El::AbstractDistMatrix< TensorDataType > &mat, El::Int m, El::Int n, TensorDataType center=0.0, TensorDataType radius=1.0)