fpmas 1.6
generator.h
Go to the documentation of this file.
1#ifndef FPMAS_RANDOM_GENERATOR_H
2#define FPMAS_RANDOM_GENERATOR_H
3
8#include <cstdint>
9#include <random>
10#include <sstream>
13
14namespace fpmas { namespace random {
15
16
17#ifndef DOXYGEN_BUILD
18 template<typename> class DistributedGenerator;
19#endif
20
28 template<typename Generator_t>
29 class UniformRandomBitGenerator: public api::random::Generator<typename Generator_t::result_type> {
30 protected:
34 Generator_t gen;
35
36 public:
38
44 static constexpr result_type min() {
45 return Generator_t::min();
46 }
47
53 static constexpr result_type max() {
54 return Generator_t::max();
55 }
56
63 return gen();
64 }
65 };
66
67 template<typename Generator_t>
68 class Generator;
69
78 template<typename Gen, class CharT, class Traits>
79 std::basic_ostream<CharT, Traits>& operator<<(
80 std::basic_ostream<CharT,Traits>& ost, const Generator<Gen>& g ) {
81 return ost << g.gen;
82 }
83
95 template<typename Gen, class CharT, class Traits>
96 std::basic_istream<CharT,Traits>&
97 operator>>(std::basic_istream<CharT,Traits>& ost, Generator<Gen>& g ) {
98 return ost >> g.gen;
99 }
100
112 template<typename Generator_t>
113 class Generator : public UniformRandomBitGenerator<Generator_t> {
114
115 public:
121
132 this->seed(seed);
133 }
134
135
136 void seed(result_type seed) override {
137 this->gen.seed(seed);
138 }
139
140 void discard(unsigned long long z) override {
141 this->gen.discard(z);
142 }
143
150 bool operator==(const Generator<Generator_t>& g) const {
151 return this->gen == g.gen;
152 };
153
157 bool operator!=(const Generator<Generator_t>& g) const {
158 return this->gen != g.gen;
159 };
160
161 template<typename Gen, class CharT, class Traits>
162 friend std::basic_ostream<CharT,Traits>&
163 operator<<(std::basic_ostream<CharT,Traits>& ost, const Generator<Gen>& g );
164
165 template<typename Gen, class CharT, class Traits>
166 friend std::basic_istream<CharT,Traits>&
167 operator>>(std::basic_istream<CharT,Traits>& ost, Generator<Gen>& g );
168 };
169
175 template<class CharT, class Traits>
176 std::basic_ostream<CharT, Traits>& operator<<(
177 std::basic_ostream<CharT,Traits>& ost, const Generator<std::random_device>&) {
178 return ost;
179 }
180
186 template<class CharT, class Traits>
187 std::basic_istream<CharT,Traits>&
188 operator>>(std::basic_istream<CharT,Traits>& ost, Generator<std::random_device>& ) {
189 return ost;
190 }
191
199 template<>
200 class Generator<std::random_device> : public UniformRandomBitGenerator<std::random_device> {
201 public:
206 }
210 Generator(std::random_device::result_type) {
211 }
212
221 }
222
231 }
232
241 return *this;
242 }
243
252 return *this;
253 }
254
258 void seed(std::random_device::result_type) override {
259 }
260
264 void discard(unsigned long long) override {
265 }
266
267 template<typename Gen, class CharT, class Traits>
268 friend std::basic_ostream<CharT,Traits>&
269 operator<<(std::basic_ostream<CharT,Traits>& ost, const Generator<Gen>& g );
270
271 template<typename Gen, class CharT, class Traits>
272 friend std::basic_istream<CharT,Traits>&
273 operator>>(std::basic_istream<CharT,Traits>& ost, Generator<Gen>& g );
274
275 };
276
301
321 template<typename Generator_t = mt19937_64>
322 class DistributedGenerator : public api::random::Generator<typename Generator_t::result_type> {
323 private:
325 Generator_t local_generator;
326 std::mt19937 seeder;
327
328 bool _init = false;
333 void init() {
334 int rank = comm->getRank();
335 int size = comm->getSize();
336 std::vector<std::mt19937::result_type> seed_sequence(size);
337 // Generate a different seed for each process, but poorly
338 // distributed
339 seed_sequence[0] = seeder();
340 for(int i = 1; i < size; i++)
341 seed_sequence[i]=seed_sequence[i-1]+1;
342 std::seed_seq gen(seed_sequence.begin(), seed_sequence.end());
343 // Generates an unbiased seed sequence
344 gen.generate(seed_sequence.begin(), seed_sequence.end());
345
346 // Seed for the current process
347 result_type local_seed = seed_sequence[rank];
348
349 // Seeds the local generator with the generated seed
350 local_generator.seed(local_seed);
351 _init = true;
352 }
353
354 public:
355
359 typedef typename Generator_t::result_type result_type;
360
368 : comm(&communication::WORLD) {}
369
379 : comm(&comm) {
380 }
381
391 : comm(&communication::WORLD), seeder(seed) {}
392
404 : comm(&comm), seeder(seed) {}
405
407 if(!_init)
408 init();
409 return local_generator();
410 }
411
412 void seed(result_type seed) override {
413 seeder.seed(seed);
414 _init = false;
415 }
416
417 void discard(unsigned long long z) override {
418 if(!_init)
419 init();
420 local_generator.discard(z);
421 }
422
423
429 static constexpr result_type min() {
430 return Generator_t::min();
431 }
432
438 static constexpr result_type max() {
439 return Generator_t::max();
440 }
441 };
442
443 template<>
445 };
446}}
447
448namespace nlohmann {
452 template<typename Generator_t>
453 struct adl_serializer<fpmas::random::Generator<Generator_t>> {
454
461 template<typename JsonType>
462 static void to_json(JsonType& j, const fpmas::random::Generator<Generator_t>& gen) {
463 std::stringstream str_buf;
464 str_buf << gen;
465 j = str_buf.str();
466 }
467
474 template<typename JsonType>
475 static void from_json(const JsonType& j, fpmas::random::Generator<Generator_t>& gen) {
476 std::stringstream str_buf(j.template get<std::string>());
477 str_buf >> gen;
478 }
479 };
480}
481
482namespace fpmas { namespace io { namespace datapack {
486 template<typename Generator_t>
487 struct Serializer<fpmas::random::Generator<Generator_t>> {
496 template<typename PackType>
497 static std::size_t size(
498 const PackType& pack,
500 std::ostringstream str;
501 str << gen;
502 return pack.size(str.str());
503 }
504
511 template<typename PackType>
512 static void to_datapack(PackType& pack, const fpmas::random::Generator<Generator_t>& gen) {
513 std::ostringstream str;
514 str<<gen;
515 pack.template put(str.str());
516 }
517
524 template<typename PackType>
526 const PackType& pack) {
527 std::istringstream str(pack.template get<std::string>());
529 str>>gen;
530 return gen;
531 }
532 };
533}}}
534#endif
Definition: communication.h:251
Definition: generator.h:20
T result_type
Definition: generator.h:25
Definition: generator.h:322
DistributedGenerator(result_type seed)
Definition: generator.h:390
DistributedGenerator()
Definition: generator.h:367
void seed(result_type seed) override
Definition: generator.h:412
void discard(unsigned long long z) override
Definition: generator.h:417
static constexpr result_type min()
Definition: generator.h:429
DistributedGenerator(api::communication::MpiCommunicator &comm)
Definition: generator.h:378
static constexpr result_type max()
Definition: generator.h:438
DistributedGenerator(api::communication::MpiCommunicator &comm, result_type seed)
Definition: generator.h:402
Generator_t::result_type result_type
Definition: generator.h:359
result_type operator()() override
Definition: generator.h:406
Generator(Generator< std::random_device > &&)
Definition: generator.h:230
void seed(std::random_device::result_type) override
Definition: generator.h:258
Generator(std::random_device::result_type)
Definition: generator.h:210
Generator< std::random_device > & operator=(const Generator< std::random_device > &)
Definition: generator.h:240
Generator(const Generator< std::random_device > &)
Definition: generator.h:220
void discard(unsigned long long) override
Definition: generator.h:264
Generator()
Definition: generator.h:205
Generator< std::random_device > & operator=(Generator< std::random_device > &&)
Definition: generator.h:251
Definition: generator.h:113
Generator()
Definition: generator.h:125
bool operator!=(const Generator< Generator_t > &g) const
Definition: generator.h:157
bool operator==(const Generator< Generator_t > &g) const
Definition: generator.h:150
void seed(result_type seed) override
Definition: generator.h:136
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &ost, const Generator< Gen > &g)
Definition: generator.h:79
UniformRandomBitGenerator< Generator_t >::result_type result_type
Definition: generator.h:120
Generator(result_type seed)
Definition: generator.h:131
void discard(unsigned long long z) override
Definition: generator.h:140
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &ost, Generator< Gen > &g)
Definition: generator.h:97
static constexpr result_type max()
Definition: generator.h:53
Generator_t gen
Definition: generator.h:34
result_type operator()() override
Definition: generator.h:62
static constexpr result_type min()
Definition: generator.h:44
Generator< std::minstd_rand > minstd_rand
Definition: generator.h:294
Generator< std::mt19937 > mt19937
Definition: generator.h:282
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &ost, Generator< Gen > &g)
Definition: generator.h:97
Generator< std::mt19937_64 > mt19937_64
Definition: generator.h:288
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &ost, const Generator< Gen > &g)
Definition: generator.h:79
Generator< std::random_device > random_device
Definition: generator.h:300
Definition: fpmas.cpp:3
static std::size_t size(const PackType &pack, const fpmas::random::Generator< Generator_t > &gen)
Definition: generator.h:497
static void to_datapack(PackType &pack, const fpmas::random::Generator< Generator_t > &gen)
Definition: generator.h:512
static fpmas::random::Generator< Generator_t > from_datapack(const PackType &pack)
Definition: generator.h:525
Definition: datapack.h:55
static void from_json(const JsonType &j, fpmas::random::Generator< Generator_t > &gen)
Definition: generator.h:475
static void to_json(JsonType &j, const fpmas::random::Generator< Generator_t > &gen)
Definition: generator.h:462