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_HIP_GPURAND_H
6 #define FML_GPU_ARCH_HIP_GPURAND_H
7 #pragma once
8 
9 
10 #include <hiprand.hpp>
11 
12 
13 namespace gpurand
14 {
15  namespace defs
16  {
17  static const hiprandRngType_t gen_type = HIPRAND_RNG_PSEUDO_MTGP32;
18  }
19 
20 
21 
22  namespace err
23  {
24  static inline void check_init(hiprandStatus_t st)
25  {
26  if (st != HIPRAND_STATUS_SUCCESS)
27  throw std::runtime_error("unable to initialize GPU generator");
28  }
29 
30  static inline void check_seed_set(hiprandStatus_t st)
31  {
32  if (st != HIPRAND_STATUS_SUCCESS)
33  throw std::runtime_error("unable to set GPU generator seed");
34  }
35 
36  static inline void check_generation(hiprandStatus_t st)
37  {
38  if (st != HIPRAND_STATUS_SUCCESS)
39  throw std::runtime_error("unable to utilize GPU generator");
40  }
41  }
42 
43 
44 
45  namespace generics
46  {
47  static inline hiprandStatus_t gpu_rand_unif(hiprandGenerator_t generator, float *outputPtr, size_t num)
48  {
49  return hiprandGenerateUniform(generator, outputPtr, num);
50  }
51 
52  static inline hiprandStatus_t gpu_rand_unif(hiprandGenerator_t generator, double *outputPtr, size_t num)
53  {
54  return hiprandGenerateUniformDouble(generator, outputPtr, num);
55  }
56 
57 
58 
59  static inline hiprandStatus_t gpu_rand_norm(hiprandGenerator_t generator, float *outputPtr, size_t num, float mean, float stddev)
60  {
61  return hiprandGenerateNormal(generator, outputPtr, num, mean, stddev);
62  }
63 
64  static inline hiprandStatus_t gpu_rand_norm(hiprandGenerator_t generator, double *outputPtr, size_t num, double mean, double stddev)
65  {
66  return hiprandGenerateNormalDouble(generator, outputPtr, num, mean, stddev);
67  }
68  }
69 
70 
71 
72  template <typename REAL>
73  inline void gen_runif(const uint32_t seed, const size_t len, REAL *x)
74  {
75  hiprandStatus_t st;
76  hiprandGenerator_t gen;
77 
78  st = hiprandCreateGenerator(&gen, defs::gen_type);
79  err::check_init(st);
80 
81  st = hiprandSetPseudoRandomGeneratorSeed(gen, seed);
82  err::check_seed_set(st);
83  st = generics::gpu_rand_unif(gen, x, len);
84  err::check_generation(st);
85 
86  hiprandDestroyGenerator(gen);
87  }
88 
89 
90 
91  template <typename REAL>
92  inline void gen_rnorm(const uint32_t seed, const REAL mean, const REAL sd, const size_t len, REAL *x)
93  {
94  hiprandStatus_t st;
95  hiprandGenerator_t gen;
96 
97  st = hiprandCreateGenerator(&gen, defs::gen_type);
98  err::check_init(st);
99 
100  st = hiprandSetPseudoRandomGeneratorSeed(gen, seed);
101  err::check_seed_set(st);
102  st = generics::gpu_rand_norm(gen, x, len, mean, sd);
103  err::check_generation(st);
104 
105  hiprandDestroyGenerator(gen);
106  }
107 }
108 
109 
110 #endif