Skip to content

Commit a476eae

Browse files
authored
Merge pull request #332 from JamesMcClung/pr/deterministic-seed
Use process-global generators with fixed seeds
2 parents 7a62436 + 2a6269c commit a476eae

1 file changed

Lines changed: 32 additions & 9 deletions

File tree

src/include/rng.hxx

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,51 @@
66
#include <random>
77
#include <chrono>
88
#include <functional>
9+
#include <memory>
10+
#include "mpi.h"
911

1012
namespace rng
1113
{
1214

15+
namespace detail
16+
{
17+
using Generator = std::default_random_engine;
18+
using ProcessGeneratorPtr = std::shared_ptr<Generator>;
19+
ProcessGeneratorPtr process_generator;
20+
21+
int get_process_seed()
22+
{
23+
int rank;
24+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
25+
return 10000 * (rank + 1);
26+
}
27+
28+
ProcessGeneratorPtr get_process_generator()
29+
{
30+
if (!process_generator) {
31+
process_generator = std::make_shared<Generator>(get_process_seed());
32+
}
33+
return process_generator;
34+
}
35+
36+
} // namespace detail
37+
1338
// ======================================================================
1439
// Uniform
1540

1641
template <typename Real>
1742
struct Uniform
1843
{
1944
Uniform(Real min, Real max)
20-
: dist(min, max),
21-
gen(std::chrono::system_clock::now().time_since_epoch().count())
45+
: dist(min, max), gen(detail::get_process_generator())
2246
{}
2347

2448
Uniform() : Uniform(0, 1) {}
2549

26-
Real get() { return dist(gen); }
50+
Real get() { return dist(*gen); }
2751

2852
private:
29-
std::default_random_engine gen;
53+
detail::ProcessGeneratorPtr gen;
3054
std::uniform_real_distribution<Real> dist;
3155
};
3256

@@ -37,21 +61,20 @@ template <typename Real>
3761
struct Normal
3862
{
3963
Normal(Real mean, Real stdev)
40-
: dist(mean, stdev),
41-
gen(std::chrono::system_clock::now().time_since_epoch().count())
64+
: dist(mean, stdev), gen(detail::get_process_generator())
4265
{}
4366
Normal() : Normal(0, 1) {}
4467

45-
Real get() { return dist(gen); }
68+
Real get() { return dist(*gen); }
4669
// FIXME remove me, or make standalone func
4770
Real get(Real mean, Real stdev)
4871
{
4972
// should be possible to pass params to existing dist
50-
return std::normal_distribution<Real>(mean, stdev)(gen);
73+
return std::normal_distribution<Real>(mean, stdev)(*gen);
5174
}
5275

5376
private:
54-
std::default_random_engine gen;
77+
detail::ProcessGeneratorPtr gen;
5578
std::normal_distribution<Real> dist;
5679
};
5780

0 commit comments

Comments
 (0)