IMP logo
IMP Reference Guide  develop.e1fe35f,2019/09/16
The Integrative Modeling Platform
random_utils.h
Go to the documentation of this file.
1 /**
2  * \file IMP/random_utils.h \brief Random number utility functions used by IMP.
3  *
4  * Copyright 2007-2019 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPKERNEL_RANDOM_UTILS_H
9 #define IMPKERNEL_RANDOM_UTILS_H
10 
11 #include <IMP/kernel_config.h>
12 #include <IMP/Vector.h>
13 #include <IMP/random.h>
14 #ifdef IMP_KERNEL_CUDA_LIB
15 // #warning "random_utils - kernel CUDA_LIB!"
16 #include "IMP/internal/random_number_generation_cuda.h"
17 #else
18 // #warning "random_utils - kernel CUDA_BOOST!"
19 #include "IMP/internal/random_number_generation_boost.h"
20 #endif
21 
22 #include <boost/random/mersenne_twister.hpp>
23 #include <boost/random/uniform_real.hpp>
24 
25 // #include <ctime> // DEBUG
26 //#include <sys/time.h> // DEBUG
27 
28 IMPKERNEL_BEGIN_NAMESPACE
29 
30 //! Fill the double array with random normally distributed values.
31 /** The pre-allocated array is filled with n double numbers with
32  random normally distributed values with specified mean and
33  standard deviation.
34 
35  @param v vector array that will be resized to n
36  @param n size of array
37  @param mean mean of normal distribution
38  @param stddev standard deviation
39 
40  @note Implementation relies on random_number_generator (a boost
41  random number generator), or on the CUDA random number
42  generator if kernel is built with IMP_KERNEL_CUDA_LIB cmake
43  flag. Either is initially seeded with get_random_seed().
44 */
45 template<typename RealType>
47 (Vector<RealType>& v, unsigned int n,
48  RealType mean=0.0, RealType stddev=1.0)
49 {
50  if(n==0) return;
51  if(n>v.size())
52  v.resize(n);
53  // struct timeval start_time; // DEBUG
54  //struct timeval t_time; // DEBUG
55  //gettimeofday(&start_time, 0); // DEBUG
56 #ifdef IMP_KERNEL_CUDA_LIB
57  IMPcuda::kernel::internal::init_gpu_rng_once(get_random_seed());
58  IMPcuda::kernel::internal::get_random_numbers_normal_cuda
59  (&v[0], n, mean, stddev);
60 #else
61  internal::get_random_numbers_normal_boost(&v[0], n, mean, stddev);
62 #endif
63  // gettimeofday(&t_time, 0); // DEBUG
64  // double time_diff_sec= (double)( (t_time.tv_sec - start_time.tv_sec)
65  // + 0.000001 * (t_time.tv_usec - start_time.tv_usec) ); // DEBUG
66  // std::cout << "get_random_numbers_uniform_cuda(" << n
67  // << ") " << time_diff_sec << " seconds" << std::endl; // DEBUG
68 
69 }
70 
71 //! Fill the float array with random uniformly distributed values.
72 /** Fill a pre-allocated array of n float numbers with random uniformly
73  distributed values in the [0..1) range.
74 
75  @param v vector array that will be resized to n
76  @param n size of array
77 
78  @note Implementation relies on random_number_generator (a boost
79  random number generator), or on the CUDA random number generator
80  if kernel is built with CUDA flag. Either is initially seeded with
81  get_random_seed().
82  */
83 template<typename RealType>
85 (Vector<RealType>& v, unsigned int n)
86 {
87  if(n==0) return;
88  if(n>v.size())
89  v.resize(n);
90 #ifdef IMP_KERNEL_CUDA_LIB
91  IMPcuda::kernel::internal::init_gpu_rng_once(get_random_seed());
92  IMPcuda::kernel::internal::get_random_numbers_uniform_cuda (&v[0], n);
93 #else
94  internal::get_random_numbers_uniform_boost(&v[0], n);
95 #endif
96 }
97 
98 //! Return a uniformly distributed float number in range [0..1)
99 /** @note the random number is retrieved from a cache of random
100  numbers generated using GPU if compiled with CUDA, or from boost
101  without a cache otherwise.
102  */
104 
105 //! Return a uniformly distributed float number in range [min..max)
106 /** @note the random number is retrieved from a cache of random
107  numbers generated using GPU if compiled with CUDA, or from boost
108  without a cache otherwise.
109  */
110 float get_random_float_uniform(float min, float max);
111 
112 //! Return a uniformly distributed double number in range [0..1)
113 /** @note the random number is retrieved from a cache of random
114  numbers generated using GPU if compiled with CUDA, or from boost
115  without a cache otherwise.
116  */
118 
119 //! Return a uniformly distributed double number in range [min..max)
120 /** @note the random number is retrieved from a cache of random
121  numbers generated using GPU if compiled with CUDA, or from boost
122  without a cache otherwise.
123  */
124 double get_random_double_uniform(double min, double max);
125 
126 /************ implementation of inline functions *******/
127 
128 inline float
130 {
131  // use cache only with cuda
132 #ifdef IMP_KERNEL_CUDA_LIB
133  const static unsigned int cache_n=20000000;
134  static IMP::Vector<float> cache;
135  static unsigned int i=0;
136  if(i>=cache.size()){
137  get_random_numbers_uniform(cache, cache_n);
138  i=0;
139  }
140  return cache[i++];
141 #else
142  static boost::uniform_real<float> rand(0.0, 1.0);
143  return rand(random_number_generator);
144 #endif
145 }
146 
147 inline float
148 get_random_float_uniform(float min, float max)
149 {
150  // use cache only with cuda
151 #ifdef IMP_KERNEL_CUDA_LIB
152  return get_random_float_uniform()*(max-min)+min;
153 #else
154  ::boost::uniform_real<float> rand(min, max);
155  return rand(random_number_generator);
156 #endif
157 }
158 
159 
160 inline double
162 {
163 #ifdef IMP_KERNEL_CUDA_LIB
164  const static unsigned int cache_n=2000000;
165  static IMP::Vector<double> cache;
166  static unsigned int i=0;
167  if(i>=cache.size()){
168  get_random_numbers_uniform(cache, cache_n);
169  i=0;
170  }
171  return cache[i++];
172 #else
173  static boost::uniform_real<double> rand(0.0, 1.0);
174  return rand(random_number_generator);
175 #endif
176 }
177 
178 inline double
179 get_random_double_uniform(double min, double max)
180 {
181 #ifdef IMP_KERNEL_CUDA_LIB
182  return get_random_double_uniform()*(max-min)+min;
183 #else
184  ::boost::uniform_real<double> rand(min, max);
185  return rand(random_number_generator);
186 #endif
187 }
188 
189 
190 
191 IMPKERNEL_END_NAMESPACE
192 
193 #endif /* IMPKERNEL_RANDOM_UTILS_H */
void get_random_numbers_uniform(Vector< RealType > &v, unsigned int n)
Fill the float array with random uniformly distributed values.
Definition: random_utils.h:85
A more IMP-like version of the std::vector.
Definition: Vector.h:39
boost::uint64_t get_random_seed()
Return the initial random seed.
double get_random_double_uniform(double min, double max)
Return a uniformly distributed double number in range [min..max)
Definition: random_utils.h:179
float get_random_float_uniform(float min, float max)
Return a uniformly distributed float number in range [min..max)
Definition: random_utils.h:148
A class for storing lists of IMP items.
void get_random_numbers_normal(Vector< RealType > &v, unsigned int n, RealType mean=0.0, RealType stddev=1.0)
Fill the double array with random normally distributed values.
Definition: random_utils.h:47
Random number generators used by IMP.
RandomNumberGenerator random_number_generator
A shared non-GPU random number generator.