26 #ifndef MSHADOW_RANDOM_H_
27 #define MSHADOW_RANDOM_H_
44 template<
typename Device,
typename DType MSHADOW_DEFAULT_DTYPE>
48 template<
typename DType>
65 inline void Seed(
int seed) {
66 rnd_engine_.seed(seed);
67 this->rseed_ =
static_cast<unsigned>(seed);
95 std::generate_n(dst.
dptr_, dst.
size(0), [&](){ return rnd_engine_(); });
104 template<
int dim,
class Sampler>
107 std::generate_n(dst->
dptr_, dst->
shape_.Size(), sampler);
111 std::generate_n(mat[i].dptr_, mat.
size(1), sampler);
123 template<
int dim,
typename PType>
125 PType a = 0.0f , PType b = 1.0f ) {
127 typedef typename std::conditional<std::is_floating_point<DType>::value,
128 DType,
double>::type FType;
129 typedef typename std::conditional<std::is_integral<DType>::value,
130 std::uniform_int_distribution<DType>,
131 std::uniform_real_distribution<FType>>::type GType;
132 GType dist_uniform(a, b);
133 SampleDistribution(dst, [&](){
return dist_uniform(rnd_engine_);});
143 template<
int dim,
typename PType>
145 PType mu = 0.0f, PType sigma = 1.0f ) {
149 typedef typename std::conditional<std::is_floating_point<DType>::value,
150 DType,
double>::type GType;
151 std::normal_distribution<GType> dist_normal(mu, sigma);
152 SampleDistribution(dst, [&](){
return dist_normal(rnd_engine_);});
162 template<
int dim,
typename PType>
164 PType alpha, PType beta) {
165 typedef typename std::conditional<std::is_floating_point<DType>::value,
166 DType,
double>::type GType;
167 std::gamma_distribution<GType> dist_gamma(alpha, beta);
168 SampleDistribution(dst, [&](){
return dist_gamma(rnd_engine_);});
177 template<
int dim,
typename PType>
179 typedef typename std::conditional<std::is_floating_point<DType>::value,
180 DType,
double>::type GType;
181 std::exponential_distribution<GType> dist_exp(lambda);
182 SampleDistribution(dst, [&](){
return dist_exp(rnd_engine_);});
191 template<
int dim,
typename PType>
193 typedef typename std::conditional<std::is_integral<DType>::value, DType,
int>::type GType;
194 std::poisson_distribution<GType> dist_poisson(lambda);
195 SampleDistribution(dst, [&](){
return static_cast<DType
>(dist_poisson(rnd_engine_));});
205 template<
int dim,
typename PType1,
typename PType2>
207 typedef typename std::conditional<std::is_integral<DType>::value, DType,
int>::type GType;
208 std::negative_binomial_distribution<GType> dist_negbinomial(k, p);
209 SampleDistribution(dst, [&](){
return static_cast<DType
>(dist_negbinomial(rnd_engine_));});
220 template<
int dim,
typename PType>
222 PType mu, PType alpha) {
223 if (alpha == PType(0)) {
226 PType r(PType(1) / alpha);
227 PType beta = mu * alpha;
228 std::gamma_distribution<> dist_gamma(r, beta);
229 typedef typename std::conditional<std::is_integral<DType>::value, DType,
int>::type GType;
230 SampleDistribution(dst,
231 [&](){ std::poisson_distribution<GType> dist_poisson(dist_gamma(rnd_engine_));
232 return static_cast<DType
>(dist_poisson(rnd_engine_));});
279 std::mt19937 rnd_engine_;
289 template<
typename DType>
308 curandStatus_t status;
311 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"set_stream CURAND failed";
319 if (gen_ == NULL || (curandSetGeneratorOffset(gen_, 0ULL) != CURAND_STATUS_SUCCESS))
322 curandStatus_t status;
323 status = curandSetPseudoRandomGeneratorSeed(gen_,
static_cast<uint64_t
>(seed));
324 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"Set CURAND seed failed.";
330 curandStatus_t status;
331 status = curandGenerate(gen_, dst.
dptr_, dst.
size(0));
332 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"CURAND Gen rand ints failed."
333 <<
" size = " << dst.
size(0);
344 DType a = 0.0f, DType b = 1.0f);
355 DType mu = 0.0f, DType sigma = 1.0f);
371 gaussian(
Shape<dim> shape, DType mu = 0.0f, DType sigma = 1.0f);
388 inline void GenGaussian(
float *dptr,
size_t size,
float mu,
float sigma) {
389 curandStatus_t status;
390 status = curandGenerateNormal(gen_, dptr, size, mu, sigma);
391 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"CURAND Gen Normal float failed."
392 <<
" size = " << size
394 <<
",sigma = " << sigma;
396 inline void GenGaussian(
double *dptr,
size_t size,
double mu,
double sigma) {
397 curandStatus_t status;
398 status = curandGenerateNormalDouble(gen_, dptr, size, mu, sigma);
399 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"CURAND Gen Normal double failed."
400 <<
" size = " << size
402 <<
",sigma = " << sigma;
404 inline void GenUniform(
float *dptr,
size_t size) {
405 curandStatus_t status;
406 status = curandGenerateUniform(gen_, dptr, size);
407 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"CURAND Gen Uniform float failed."
408 <<
" size = " << size;
410 inline void GenUniform(
double *dptr,
size_t size) {
411 curandStatus_t status;
412 status = curandGenerateUniformDouble(gen_, dptr, size);
413 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"CURAND Gen Uniform double failed."
414 <<
" size = " << size;
416 inline void CreateGenerator() {
419 curandStatus_t status;
420 status = curandCreateGenerator(&gen_, CURAND_RNG_PSEUDO_DEFAULT);
421 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"Cannot create CURAND Generator";
423 inline void DeleteGenerator() {
425 curandStatus_t status;
426 status = curandDestroyGenerator(gen_);
427 CHECK_EQ(status, CURAND_STATUS_SUCCESS) <<
"Destory CURAND Gen failed";
432 curandGenerator_t gen_;
434 TensorContainer<gpu, 1, DType> buffer_;
436 #endif // MSHADOW_USE_CUDA
440 template<
typename DType>
443 Tensor<gpu, dim, DType> *dst, DType a, DType b) {
444 if (a == 0.0f && b == 1.0f) {
445 if (dst->CheckContiguous()) {
446 this->GenUniform(dst->dptr_, dst->shape_.Size());
448 *dst = this->uniform(dst->shape_);
451 *dst = this->uniform(dst->shape_) * (b - a) + a;
454 template<
typename DType>
457 Tensor<gpu, dim, DType> *dst, DType mu, DType sigma) {
460 if (dst->CheckContiguous() && (dst->shape_.Size() % 2 == 0)) {
461 this->GenGaussian(dst->dptr_, dst->shape_.Size(), mu, sigma);
463 *dst = this->gaussian(dst->shape_, mu, sigma);
467 template<
typename DType>
469 inline expr::ReshapeExp<Tensor<gpu, 1, DType>, DType, dim, 1>
471 size_t aligned_sz = ((shape.Size() + 1UL) >> 1) << 1;
473 buffer_.Resize(
Shape1(aligned_sz));
474 buffer_.Resize(
Shape1(shape.Size()));
475 this->GenGaussian(buffer_.dptr_, aligned_sz, mu, sigma);
479 template<
typename DType>
481 inline expr::ReshapeExp<Tensor<gpu, 1, DType>, DType, dim, 1>
483 buffer_.Resize(
Shape1(shape.Size()));
484 this->GenUniform(buffer_.dptr_, buffer_.size(0));
489 #endif // MSHADOW_RANDOM_H_