-
Notifications
You must be signed in to change notification settings - Fork 395
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2793 from verilog-to-routing/temp_rand_remove_static
Random number generation classes
- Loading branch information
Showing
45 changed files
with
705 additions
and
502 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,67 @@ | ||
#include <cstddef> | ||
|
||
#include "vtr_random.h" | ||
#include "specrand.h" | ||
#include "vtr_util.h" | ||
#include "vtr_error.h" | ||
#include "specrand.h" | ||
|
||
#define CHECK_RAND | ||
|
||
namespace vtr { | ||
/* Portable random number generator defined below. Taken from ANSI C by * | ||
* K & R. Not a great generator, but fast, and good enough for my needs. */ | ||
|
||
constexpr size_t IA = 1103515245u; | ||
constexpr size_t IC = 12345u; | ||
constexpr size_t IM = 2147483648u; | ||
|
||
static RandState random_state = 0; | ||
|
||
/** | ||
* @brief The pseudo-random number generator is initialized using the argument passed as seed. | ||
*/ | ||
void srandom(int seed) { | ||
random_state = (unsigned int)seed; | ||
#ifdef SPEC_CPU | ||
/* SPEC CPU requires a different random number generator */ | ||
spec_init_genrand((unsigned long)seed); | ||
#endif | ||
RandomNumberGenerator::RandomNumberGenerator(int seed) { | ||
random_state_ = (unsigned int)seed; | ||
} | ||
|
||
/* returns the random_state value */ | ||
RandState get_random_state() { | ||
return random_state; | ||
RandomNumberGenerator::RandomNumberGenerator() | ||
: RandomNumberGenerator(0) {} | ||
|
||
void RandomNumberGenerator::srandom(int seed) { | ||
random_state_ = (unsigned int)seed; | ||
} | ||
|
||
int irand(int imax, RandState& state) { | ||
#ifdef SPEC_CPU | ||
/* SPEC CPU requires a different random number generator */ | ||
return (int)(spec_genrand_int31() % (imax + 1)); | ||
#else | ||
/* Creates a random integer between 0 and imax, inclusive. i.e. [0..imax] */ | ||
int RandomNumberGenerator::irand(int imax) { | ||
// Creates a random integer between 0 and imax, inclusive. i.e. [0..imax] | ||
int ival; | ||
|
||
/* state = (state * IA + IC) % IM; */ | ||
state = state * IA + IC; /* Use overflow to wrap */ | ||
ival = state & (IM - 1); /* Modulus */ | ||
// state = (state * IA + IC) % IM; | ||
random_state_ = random_state_ * IA + IC; // Use overflow to wrap | ||
ival = random_state_ & (IM - 1); // Modulus | ||
ival = (int)((float)ival * (float)(imax + 0.999) / (float)IM); | ||
|
||
# ifdef CHECK_RAND | ||
if ((ival < 0) || (ival > imax)) { | ||
if (ival == imax + 1) { | ||
/* Due to random floating point rounding, sometimes above calculation gives number greater than ival by 1 */ | ||
ival = imax; | ||
} else { | ||
throw VtrError(string_fmt("Bad value in my_irand, imax = %d ival = %d", imax, ival), __FILE__, __LINE__); | ||
if constexpr (CHECK_RAND_CONSTEXPR) { | ||
if ((ival < 0) || (ival > imax)) { | ||
if (ival == imax + 1) { | ||
// Due to random floating point rounding, sometimes above calculation gives number greater than ival by 1 | ||
ival = imax; | ||
} else { | ||
throw VtrError(string_fmt("Bad value in my_irand, imax = %d ival = %d", imax, ival), __FILE__, __LINE__); | ||
} | ||
} | ||
} | ||
# endif | ||
|
||
return ival; | ||
#endif | ||
} | ||
|
||
int irand(int imax) { | ||
return irand(imax, random_state); | ||
} | ||
float RandomNumberGenerator::frand() { | ||
random_state_ = random_state_ * IA + IC; /* Use overflow to wrap */ | ||
int ival = random_state_ & (IM - 1); /* Modulus */ | ||
float fval = (float)ival / (float)IM; | ||
|
||
float frand() { | ||
/* Creates a random float between 0 and 1. i.e. [0..1). */ | ||
#ifdef SPEC_CPU | ||
/* SPEC CPU requires a different random number generator */ | ||
return (float)spec_genrand_real2(); | ||
#else | ||
float fval; | ||
int ival; | ||
if constexpr (CHECK_RAND_CONSTEXPR) { | ||
if (fval < 0 || fval > 1.) { | ||
throw VtrError(string_fmt("Bad value in my_frand, fval = %g", fval), __FILE__, __LINE__); | ||
} | ||
} | ||
|
||
random_state = random_state * IA + IC; /* Use overflow to wrap */ | ||
ival = random_state & (IM - 1); /* Modulus */ | ||
fval = (float)ival / (float)IM; | ||
return fval; | ||
} | ||
|
||
# ifdef CHECK_RAND | ||
if ((fval < 0) || (fval > 1.)) { | ||
throw VtrError(string_fmt("Bad value in my_frand, fval = %g", fval), __FILE__, __LINE__); | ||
RngContainer::RngContainer(int seed) { | ||
if constexpr (SPEC_CPU_CONSTEXPR) { | ||
rng_ = std::make_unique<SpecRandomNumberGenerator>(seed); | ||
} else { | ||
rng_ = std::make_unique<vtr::RandomNumberGenerator>(seed); | ||
} | ||
# endif | ||
|
||
return (fval); | ||
#endif | ||
} | ||
|
||
RngContainer::RngContainer() | ||
: RngContainer(0) {} | ||
} // namespace vtr |
Oops, something went wrong.