fml  0.1-0
Fused Matrix Library
gpurand.hh
1 // This file is part of fml which is released under the Boost Software
2 // License, Version 1.0. See accompanying file LICENSE or copy at
3 // https://www.boost.org/LICENSE_1_0.txt
4 
5 #ifndef FML_GPU_ARCH_CUDA_GPURAND_H
6 #define FML_GPU_ARCH_CUDA_GPURAND_H
7 #pragma once
8 
9 
10 #include <curand.h>
11 
12 
13 namespace fml
14 {
15 namespace gpurand
16 {
17  namespace defs
18  {
19  static const curandRngType_t gen_type = CURAND_RNG_PSEUDO_MTGP32;
20  }
21 
22 
23 
24  namespace err
25  {
26  static inline void check_init(curandStatus_t st)
27  {
28  if (st != CURAND_STATUS_SUCCESS)
29  throw std::runtime_error("unable to initialize GPU generator");
30  }
31 
32  static inline void check_seed_set(curandStatus_t st)
33  {
34  if (st != CURAND_STATUS_SUCCESS)
35  throw std::runtime_error("unable to set GPU generator seed");
36  }
37 
38  static inline void check_generation(curandStatus_t st)
39  {
40  if (st != CURAND_STATUS_SUCCESS)
41  throw std::runtime_error("unable to utilize GPU generator");
42  }
43  }
44 
45 
46 
47  namespace generics
48  {
49  static inline curandStatus_t gpu_rand_unif(curandGenerator_t generator, float *outputPtr, size_t num)
50  {
51  return curandGenerateUniform(generator, outputPtr, num);
52  }
53 
54  static inline curandStatus_t gpu_rand_unif(curandGenerator_t generator, double *outputPtr, size_t num)
55  {
56  return curandGenerateUniformDouble(generator, outputPtr, num);
57  }
58 
59 
60 
61  static inline curandStatus_t gpu_rand_norm(curandGenerator_t generator, float *outputPtr, size_t num, float mean, float stddev)
62  {
63  return curandGenerateNormal(generator, outputPtr, num, mean, stddev);
64  }
65 
66  static inline curandStatus_t gpu_rand_norm(curandGenerator_t generator, double *outputPtr, size_t num, double mean, double stddev)
67  {
68  return curandGenerateNormalDouble(generator, outputPtr, num, mean, stddev);
69  }
70  }
71 
72 
73 
74  template <typename REAL>
75  inline void gen_runif(const uint32_t seed, const size_t len, REAL *x)
76  {
77  curandStatus_t st;
78  curandGenerator_t gen;
79 
80  st = curandCreateGenerator(&gen, defs::gen_type);
81  err::check_init(st);
82 
83  st = curandSetPseudoRandomGeneratorSeed(gen, seed);
84  err::check_seed_set(st);
85  st = generics::gpu_rand_unif(gen, x, len);
86  err::check_generation(st);
87 
88  curandDestroyGenerator(gen);
89  }
90 
91 
92 
93  template <typename REAL>
94  inline void gen_rnorm(const uint32_t seed, const REAL mean, const REAL sd, const size_t len, REAL *x)
95  {
96  curandStatus_t st;
97  curandGenerator_t gen;
98 
99  st = curandCreateGenerator(&gen, defs::gen_type);
100  err::check_init(st);
101 
102  st = curandSetPseudoRandomGeneratorSeed(gen, seed);
103  err::check_seed_set(st);
104  st = generics::gpu_rand_norm(gen, x, len, mean, sd);
105  err::check_generation(st);
106 
107  curandDestroyGenerator(gen);
108  }
109 }
110 }
111 
112 
113 #endif
fml
Core namespace.
Definition: dimops.hh:10