Fleet  0.0.9
Inference in the LOT
Rng.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <thread>
4 #include <mutex>
5 
6 #include <sys/syscall.h>
7 #include <sys/random.h>
8 
17 thread_local class Rng : public std::mt19937 {
18 public:
19 
20  // The first of these that is made is called the "base" and is used to seed any others.
21  // Because this variable rng is thread_local, each thread will get its own and its seed
22  // will be determined (deterministically) from base.
23  static std::mutex mymut;
24  static Rng* base;
25 
26  Rng() : std::mt19937() {
27 
28  // allow only one constructor at a time
29  std::lock_guard guard(mymut);
30 
31  if(base == nullptr) {
32  // on construction we initialize from /dev/urandom
33  std::array<unsigned long, std::mt19937::state_size> state;
34  sysrandom(state.begin(), state.size()*sizeof(unsigned long));
35  std::seed_seq seedseq(state.begin(), state.end());
36  this->std::mt19937::seed(seedseq);
37 
38  base = this;
39  }
40  else {
41 
42  // seed from base -- so we get replicable numbers assuming the
43  // order of construction is fixed
44  std::array<unsigned long, std::mt19937::state_size> state;
45  for(size_t i=0;i<state.size();i++){
46  state[i] = base->operator()();
47  }
48  std::seed_seq seedseq(state.begin(), state.end());
49  this->std::mt19937::seed(seedseq);
50  }
51  }
52 
56  void seed(unsigned long s) {
57  if(s != 0) {
58  this->std::mt19937::seed(s);
59  }
60  }
61 
62  static size_t sysrandom(void* dst, size_t dstlen) {
63  // from https://stackoverflow.com/questions/45069219/how-to-succinctly-portably-and-thoroughly-seed-the-mt19937-prng
64  char* buffer = reinterpret_cast<char*>(dst);
65  std::ifstream stream("/dev/urandom", std::ios_base::binary | std::ios_base::in);
66  stream.read(buffer, dstlen);
67  return dstlen;
68  }
69 
70 
71 } rng;
72 
73 std::mutex Rng::mymut;
74 Rng* Rng::base = nullptr;
Definition: Rng.h:17
Rng rng
Rng()
Definition: Rng.h:26
void seed(unsigned long s)
Seed only if s is nonzero.
Definition: Rng.h:56
static std::mutex mymut
Definition: Rng.h:23
static size_t sysrandom(void *dst, size_t dstlen)
Definition: Rng.h:62
static Rng * base
Definition: Rng.h:24