X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Frandom.hh;h=401ba086ff16d56fca9ed2fcb00e18f0e3517180;hb=2dd699ed3d31b5aee8fbb88948c4ea6083b1c8b0;hp=b5eb39f945669c17a1aa7e8bf4040da806294f64;hpb=d2d581cf01d07f6a22f02f471d23e3d31919c695;p=gem5.git diff --git a/src/base/random.hh b/src/base/random.hh index b5eb39f94..401ba086f 100644 --- a/src/base/random.hh +++ b/src/base/random.hh @@ -32,98 +32,211 @@ #ifndef __BASE_RANDOM_HH__ #define __BASE_RANDOM_HH__ -#include "sim/host.hh" - -long getLong(); -double getDouble(); -uint64_t getUniformPos(uint64_t min, uint64_t max); -int64_t getUniform(int64_t min, int64_t max); - -template -struct Random; - -template<> struct Random -{ - static int8_t get() - { return getLong() & (int8_t)-1; } - - static int8_t uniform(int8_t min, int8_t max) - { return getUniform(min, max); } -}; - -template<> struct Random -{ - static uint8_t get() - { return getLong() & (uint8_t)-1; } - - static uint8_t uniform(uint8_t min, uint8_t max) - { return getUniformPos(min, max); } -}; - -template<> struct Random -{ - static int16_t get() - { return getLong() & (int16_t)-1; } - - static int16_t uniform(int16_t min, int16_t max) - { return getUniform(min, max); } -}; - -template<> struct Random -{ - static uint16_t get() - { return getLong() & (uint16_t)-1; } - - static uint16_t uniform(uint16_t min, uint16_t max) - { return getUniformPos(min, max); } -}; - -template<> struct Random -{ - static int32_t get() - { return (int32_t)getLong(); } - - static int32_t uniform(int32_t min, int32_t max) - { return getUniform(min, max); } -}; - -template<> struct Random -{ - static uint32_t get() - { return (uint32_t)getLong(); } - - static uint32_t uniform(uint32_t min, uint32_t max) - { return getUniformPos(min, max); } -}; +#include +#include -template<> struct Random -{ - static int64_t get() - { return (int64_t)getLong() << 32 || (uint64_t)getLong(); } - - static int64_t uniform(int64_t min, int64_t max) - { return getUniform(min, max); } -}; - -template<> struct Random -{ - static uint64_t get() - { return (uint64_t)getLong() << 32 || (uint64_t)getLong(); } +#include "base/range.hh" +#include "sim/host.hh" - static uint64_t uniform(uint64_t min, uint64_t max) - { return getUniformPos(min, max); } -}; +class Checkpoint; -template<> struct Random +class Random { - static float get() - { return getDouble(); } + protected: + static const int N = 624; + static const int M = 397; + static const uint32_t MATRIX_A = (uint32_t)0x9908b0df; + static const uint32_t UPPER_MASK = (uint32_t)0x80000000; + static const uint32_t LOWER_MASK = (uint32_t)0x7fffffff; + + uint32_t mt[N]; + int mti; + + uint32_t genrand(); + uint32_t genrand(uint32_t max); + uint64_t genrand(uint64_t max); + + void + _random(int8_t &value) + { + value = genrand() & (int8_t)-1; + } + + void + _random(int16_t &value) + { + value = genrand() & (int16_t)-1; + } + + void + _random(int32_t &value) + { + value = (int32_t)genrand(); + } + + void + _random(int64_t &value) + { + value = (int64_t)genrand() << 32 | (int64_t)genrand(); + } + + void + _random(uint8_t &value) + { + value = genrand() & (uint8_t)-1; + } + + void + _random(uint16_t &value) + { + value = genrand() & (uint16_t)-1; + } + + void + _random(uint32_t &value) + { + value = genrand(); + } + + void + _random(uint64_t &value) + { + value = (uint64_t)genrand() << 32 | (uint64_t)genrand(); + } + + // [0,1] + void + _random(float &value) + { + // ieee floats have 23 bits of mantissa + value = (genrand() >> 9) / 8388608.0; + } + + // [0,1] + void + _random(double &value) + { + double number = genrand() * 2097152.0 + (genrand() >> 11); + value = number / 9007199254740992.0; + } + + + // Range based versions of the random number generator + int8_t + _random(int8_t min, int8_t max) + { + uint32_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + int16_t + _random(int16_t min, int16_t max) + { + uint32_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + int32_t + _random(int32_t min, int32_t max) + { + uint32_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + int64_t + _random(int64_t min, int64_t max) + { + uint64_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + uint8_t + _random(uint8_t min, uint8_t max) + { + uint32_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + uint16_t + _random(uint16_t min, uint16_t max) + { + uint32_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + uint32_t + _random(uint32_t min, uint32_t max) + { + uint32_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + uint64_t + _random(uint64_t min, uint64_t max) + { + uint64_t diff = max - min; + return static_cast(min + genrand(diff)); + } + + public: + Random(); + Random(uint32_t s); + Random(uint32_t init_key[], int key_length); + ~Random(); + + void init(uint32_t s); + void init(uint32_t init_key[], int key_length); + + template + T + random() + { + T value; + _random(value); + return value; + } + + template + T + random(T min, T max) + { + return _random(min, max); + } + + template + T + random(const Range &range) + { + return _random(range.start, range.end); + } + + // [0,1] + double + gen_real1() + { + return genrand() / 4294967296.0; + } + + // [0,1) + double + gen_real2() + { + return genrand() / 4294967295.0; + } + + // (0,1) + double + gen_real3() + { + return ((double)genrand() + 0.5) / 4294967296.0; + } + + public: + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); }; -template<> struct Random -{ - static double get() - { return getDouble(); } -}; +extern Random random_mt; #endif // __BASE_RANDOM_HH__