llvm.org GIT mirror llvm / 6a59bc7
Make RandomNumberGenerator compatible with <random> LLVM's RandomNumberGenerator wasn't compatible with the random distribution from <random>. Fixes PR25105 Patch by: Serge Guelton <serge.guelton@telecom-bretagne.eu> Differential Revision: https://reviews.llvm.org/D25443 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283854 91177308-0d34-0410-b5e6-96231b3b80d8 Mehdi Amini 4 years ago
3 changed file(s) with 41 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
3030 /// Module::createRNG to create a new RNG instance for use with that
3131 /// module.
3232 class RandomNumberGenerator {
33
34 // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000
35 // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
36 // This RNG is deterministically portable across C++11
37 // implementations.
38 using generator_type = std::mt19937_64;
39
3340 public:
41 using result_type = generator_type::result_type;
42
3443 /// Returns a random number in the range [0, Max).
35 uint_fast64_t operator()();
44 result_type operator()();
45 static constexpr result_type min() { return generator_type::min(); }
46 static constexpr result_type max() { return generator_type::max(); }
3647
3748 private:
3849 /// Seeds and salts the underlying RNG engine.
4152 /// Module::createRNG to create a new RNG salted with the Module ID.
4253 RandomNumberGenerator(StringRef Salt);
4354
44 // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000
45 // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
46 // This RNG is deterministically portable across C++11
47 // implementations.
48 std::mt19937_64 Generator;
55 generator_type Generator;
4956
5057 // Noncopyable.
5158 RandomNumberGenerator(const RandomNumberGenerator &other) = delete;
5656 Generator.seed(SeedSeq);
5757 }
5858
59 uint_fast64_t RandomNumberGenerator::operator()() {
59 RandomNumberGenerator::result_type RandomNumberGenerator::operator()() {
6060 return Generator();
6161 }
6262
88
99 #include "llvm/IR/GlobalVariable.h"
1010 #include "llvm/IR/Module.h"
11 #include "llvm/Support/RandomNumberGenerator.h"
1112 #include "gtest/gtest.h"
13
14 #include
1215
1316 using namespace llvm;
1417
4447 }
4548 }
4649
50 TEST(ModuleTest, randomNumberGenerator) {
51 LLVMContext Context;
52 static char ID;
53 struct DummyPass : ModulePass {
54 DummyPass() : ModulePass(ID) {}
55 bool runOnModule(Module &) { return true; }
56 } DP;
57
58 Module M("R", Context);
59
60 std::uniform_int_distribution dist;
61 constexpr std::size_t NBCheck = 10;
62
63 std::array RandomStreams[2];
64 for (auto &RandomStream : RandomStreams) {
65 std::unique_ptr RNG{M.createRNG(&DP)};
66 std::generate(RandomStream.begin(), RandomStream.end(),
67 [&]() { return dist(*RNG); });
68 }
69
70 EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(),
71 RandomStreams[1].begin()));
72 }
73
4774 } // end namespace