From f60135cec62c91a9d7923397fe8796d2b3eaa5cb Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 12 Sep 2018 16:27:42 -0400 Subject: Feature/memory arena (#631) * First pass at MemoryArena. * First pass at RandomGenerator. * Extract TestContext into external source file. * Fix warning on printf. * Use enum classes for Test enums. OutputMode -> TestOutputMode. * First pass at FreeList unit test. * Auto registering tests. Improvements to RandomGenerator. * Remove the need for unitTest headers - cos can use registering. * Added unitTest for MemoryArena. * Do unit tests. * Fix typo. --- source/core/slang-random-generator.h | 97 ++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 source/core/slang-random-generator.h (limited to 'source/core/slang-random-generator.h') diff --git a/source/core/slang-random-generator.h b/source/core/slang-random-generator.h new file mode 100644 index 000000000..7b3e42288 --- /dev/null +++ b/source/core/slang-random-generator.h @@ -0,0 +1,97 @@ +#ifndef SLANG_RANDOM_GENERATOR_H +#define SLANG_RANDOM_GENERATOR_H + +#include "../../slang.h" + +#include + +#include +#include + +#include "smart-pointer.h" + +namespace Slang { + +class RandomGenerator: public RefObject +{ + public: + + /// Make a copy of the generator in the same state + virtual RandomGenerator* clone() = 0; + + /// Reset with a seed + virtual void reset(int32_t seed) = 0; + /// Next int32_t random number + virtual int32_t nextInt32() = 0; + /// Next int64_t random number + virtual int64_t nextInt64(); + + /// Get a 0-1 range floating point + virtual float nextUnitFloat32(); + + /// Get the next bool + virtual bool nextBool(); + + /// Next Int32 which can only be positive + int32_t nextPositiveInt32() { return nextInt32() & 0x7fffffff; } + /// Next Int64 which can only be positive + int64_t nextPositiveInt64() { return nextInt64() & SLANG_INT64(0x7fffffffffffffff); } + + /// Returns value up to BUT NOT INCLUDING maxValue. + int32_t nextInt32UpTo(int32_t maxValue) { assert(maxValue > 0); return (maxValue <= 1) ? 0 : (nextPositiveInt32() % maxValue); } + + /// Returns value from min up to BUT NOT INCLUDING max + int32_t nextInt32InRange(int32_t min, int32_t max); + + /// Returns value up to BUT NOT INCLUDING maxValue + int64_t nextInt64UpTo(int64_t maxValue) { assert(maxValue > 0); return (maxValue <= 1) ? 0 : (nextPositiveInt64() % maxValue); } + + /// Returns value from min up to BUT NOT INCLUDING max + int64_t nextInt64InRange(int64_t min, int64_t max); + + /// Create a RandomGenerator with specified seed using default generator type + static RandomGenerator* create(int32_t seed); +}; + +/* Mersenne Twister random number generator +https://en.wikipedia.org/wiki/Mersenne_Twister +*/ +class Mt19937RandomGenerator: public RandomGenerator +{ + public: + typedef Mt19937RandomGenerator ThisType; + + enum + { + kNumEntries = 624 + }; + + Mt19937RandomGenerator* clone() SLANG_OVERRIDE { return new ThisType(*this); } + void reset(int32_t seed) SLANG_OVERRIDE; + int32_t nextInt32() SLANG_OVERRIDE; + + /// Ctor + Mt19937RandomGenerator(); + Mt19937RandomGenerator(const ThisType& rhs); + explicit Mt19937RandomGenerator(int32_t seed); + + /// Assignment + void operator=(const ThisType& rhs) + { + m_index = rhs.m_index; + ::memcpy(m_mt, rhs.m_mt, sizeof(m_mt)); + } + + protected: + void _generate(); + + uint32_t m_mt[kNumEntries]; ///< The random state vector + int m_index; ///< If set to >= kMaxEntries it means reset + +}; + +typedef Mt19937RandomGenerator DefaultRandomGenerator; + +} // namespace Slang + +#endif // SLANG_RANDOM_GENERATOR_H \ No newline at end of file -- cgit v1.2.3