gpu-compute: "<random>" -> "base/random.hh" in testers/gpu... (#140)

In "src/cpu/testers/gpu_ruby_test" a random number generator was used.
This was using the CPP "<random>" library. This patch changes it to the
gem5 random class (that declared in "base/random.hh").

In addition to this, undeterministic behavior has been removed. Via
"protocol_tester.cc" the RNG is either seeded with a seed specified by
the user, or goes with the gem5 default seed. This ensures reproducable
runs. Prior to this patch the RNG was seeded with `time(NULL)`. This
made finding faults difficult.

This, at least partially, addresses Issue #138

Change-Id: Ia8e9f7b87e91323f828e0b7f6c3906c0c5793b2c
This commit is contained in:
Jason Lowe-Power
2023-07-28 16:54:24 -07:00
committed by GitHub
5 changed files with 27 additions and 11 deletions

View File

@@ -73,7 +73,7 @@ class ProtocolTester(ClockedObject):
random_seed = Param.Int(
0,
"Random seed number. Default value (0) means \
using runtime-specific value.",
using base/random.hh without seed.",
)
log_file = Param.String("Log file's name")
system = Param.System(Parent.any, "System we belong to")

View File

@@ -33,7 +33,6 @@
#include <algorithm>
#include <climits>
#include <random>
#include "base/intmath.hh"
#include "base/logging.hh"
@@ -101,7 +100,8 @@ AddressManager::getAddress(Location loc)
AddressManager::Location
AddressManager::getAtomicLoc()
{
Location ret_atomic_loc = random() % numAtomicLocs;
Location ret_atomic_loc = \
random_mt.random<unsigned long>() % numAtomicLocs;
atomicStructs[ret_atomic_loc]->startLocSelection();
return ret_atomic_loc;
}
@@ -206,7 +206,9 @@ AddressManager::AtomicStruct::getLoadLoc()
// we can pick any location btw
// locArray [firstMark : arraySize-1]
int range_size = arraySize - firstMark;
Location ret_loc = locArray[firstMark + random() % range_size];
Location ret_loc = locArray[
firstMark + random_mt.random<unsigned int>() % range_size
];
// update loadStoreMap
LdStMap::iterator it = loadStoreMap.find(ret_loc);
@@ -238,7 +240,9 @@ AddressManager::AtomicStruct::getStoreLoc()
} else {
// we can pick any location btw [firstMark : secondMark-1]
int range_size = secondMark - firstMark;
Location ret_loc = locArray[firstMark + random() % range_size];
Location ret_loc = locArray[
firstMark + random_mt.random<unsigned int>() % range_size
];
// update loadStoreMap
LdStMap::iterator it = loadStoreMap.find(ret_loc);

View File

@@ -34,6 +34,7 @@
#include <fstream>
#include <unordered_set>
#include "base/random.hh"
#include "cpu/testers/gpu_ruby_test/protocol_tester.hh"
#include "cpu/testers/gpu_ruby_test/tester_thread.hh"
@@ -100,7 +101,7 @@ Episode::initActions()
int num_loads = numLoads;
int num_stores = numStores;
while ((num_loads + num_stores) > 0) {
switch (random() % 2) {
switch (random_mt.random<unsigned int>() % 2) {
case 0: // Load
if (num_loads > 0) {
actions.push_back(new Action(Action::Type::LOAD,

View File

@@ -34,8 +34,8 @@
#include <algorithm>
#include <ctime>
#include <fstream>
#include <random>
#include "base/random.hh"
#include "cpu/testers/gpu_ruby_test/cpu_thread.hh"
#include "cpu/testers/gpu_ruby_test/dma_thread.hh"
#include "cpu/testers/gpu_ruby_test/gpu_wavefront.hh"
@@ -141,11 +141,20 @@ ProtocolTester::ProtocolTester(const Params &p)
sentExitSignal = false;
// set random seed number
// set random seed number, if specified.
// Note: random_m5 will use a fixed key if random_seed is not set.
// This ensures a reproducable.
if (p.random_seed != 0) {
srand(p.random_seed);
random_mt.init(p.random_seed);
} else {
srand(time(NULL));
warn(
"If `random_seed == 0` (or `random_seed` is unset) "
"ProtocolTester does not seed the RNG. This will NOT result in "
"the RNG generating different results each run. In this case the "
"RNG is seeded by a default value. This differs from behavior in "
"previous versions of gem5. Setting `random_seed` to a non-zero "
"value is strongly recommended."
);
}
actionCount = 0;

View File

@@ -33,6 +33,7 @@
#include <fstream>
#include "base/random.hh"
#include "debug/ProtocolTest.hh"
namespace gem5
@@ -144,7 +145,8 @@ TesterThread::attachTesterThreadToPorts(ProtocolTester *_tester,
void
TesterThread::issueNewEpisode()
{
int num_reg_loads = random() % tester->getEpisodeLength();
int num_reg_loads = \
random_mt.random<unsigned int>() % tester->getEpisodeLength();
int num_reg_stores = tester->getEpisodeLength() - num_reg_loads;
// create a new episode