Skip to content

Commit

Permalink
Adding random seed reset to improve stability of tests
Browse files Browse the repository at this point in the history
  • Loading branch information
searchivairus committed Feb 1, 2018
1 parent ce1061f commit dd4978b
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 16 deletions.
2 changes: 1 addition & 1 deletion similarity_search/apps/tune_vptree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void RunExper(unsigned AddRestartQty,

LOG(LIB_INFO) << "We are going to tune parameters for " << MethodName;

static thread_local auto& engine(GET_RANDOM_GENERATOR);
static thread_local auto& engine(getRandomGenerator());
static std::normal_distribution<> normGen(0.0f, log(FullFactor));

AnyParamManager pmgr(IndexParams);
Expand Down
35 changes: 24 additions & 11 deletions similarity_search/include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <random>
#include <climits>
#include <stdexcept>
#include <memory>

#include "idtype.h"

Expand Down Expand Up @@ -65,7 +66,6 @@ typedef SSIZE_T ssize_t;

#define FIELD_DELIMITER ':'

#define GET_RANDOM_GENERATOR getRandomGenerator<std::mt19937>()

namespace similarity {

Expand All @@ -75,6 +75,8 @@ using std::stringstream;

using namespace std;

typedef std::mt19937 RandomGeneratorType;


const char* GetFileName(const char* fullpath);

Expand All @@ -84,18 +86,29 @@ bool DoesFileExist(const char *filename);

inline bool DoesFileExist(const string &filename) { return DoesFileExist(filename.c_str()); }

extern int randomSeed;

/*
* Random number generation is thread safe when respective
* objects are not shared among threads. So, we will keep one
* random number generator per thread.
* 1. Random number generation is thread safe when respective
* objects are not shared among threads. So, we will keep one
* random number generator per thread.
* 2. There is a default seed to initialize all random generators.
* 3. However, sometimes we may want to reset the random number generator
* within a working thread (i.e., this would be only a thread-specific change).
* In particular, this is needed to improve reproducibility of integration tests.
*/
template <class RandGenType>
inline RandGenType & getRandomGenerator() {
static thread_local RandGenType gen(randomSeed);
extern int defaultRandomSeed;
extern thread_local std::unique_ptr<RandomGeneratorType> randomGen;

inline void resetRandomGenerator(int newRandomSeed) {
randomGen.reset(new RandomGeneratorType(newRandomSeed));
}

inline RandomGeneratorType& getRandomGenerator() {
if (!randomGen) {
resetRandomGenerator(defaultRandomSeed);
}

return gen;
return *randomGen;
}

// random 32-bit integer number
Expand All @@ -108,7 +121,7 @@ inline int32_t RandomInt() {
// thread_local is static by default, but let's keep it static for clarity
static thread_local std::uniform_int_distribution<int32_t> distr(0, std::numeric_limits<int32_t>::max());

return distr(GET_RANDOM_GENERATOR);
return distr(getRandomGenerator());
}

template <class T>
Expand All @@ -122,7 +135,7 @@ inline T RandomReal() {
// thread_local is static by default, but let's keep it static for clarity
static thread_local std::uniform_real_distribution<T> distr(0, 1);

return distr(GET_RANDOM_GENERATOR);
return distr(getRandomGenerator());
}

void RStrip(char* str);
Expand Down
6 changes: 4 additions & 2 deletions similarity_search/src/init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@
#include "logging.h"

#include <iostream>
#include <memory>

namespace similarity {

int randomSeed = 0;
int defaultRandomSeed = 0;
thread_local std::unique_ptr<RandomGeneratorType> randomGen;

void initLibrary(int seed, LogChoice choice, const char* pLogFile) {
randomSeed = seed;
defaultRandomSeed = seed;

std::ios_base::sync_with_stdio(false);
InitializeLogger(choice, pLogFile);
Expand Down
2 changes: 1 addition & 1 deletion similarity_search/src/randproj_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ template <class dist_t> void initRandProj(size_t nSrcDim, size_t nDstDim,
bool bDoOrth,
vector<vector<dist_t>>& projMatr) {
// Static is thread-safe in C++-11
static thread_local auto& randGen(GET_RANDOM_GENERATOR);
static thread_local auto& randGen(getRandomGenerator());
static std::normal_distribution<> normGen(0.0f, 1.0f);

// 1. Create normally distributed vectors
Expand Down
2 changes: 1 addition & 1 deletion similarity_search/src/searchoracle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void PolynomialPruner<dist_t>::SetIndexTimeParams(AnyParamManager& pmgr) {
unsigned exp_left = 0, exp_right = 0;


static thread_local auto& randGen(GET_RANDOM_GENERATOR);
static thread_local auto& randGen(getRandomGenerator());
static std::normal_distribution<> normGen(0.0f, log(fullFactor));


Expand Down
4 changes: 4 additions & 0 deletions similarity_search/test/test_integr_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ size_t RunTestExper(const vector<MethodTestCase>& vTestCases,
}
}

// For better reproducibility, let's reset
// random number generators.
defaultRandomSeed = 0; // Will affect any new threads
resetRandomGenerator(defaultRandomSeed); // Affects only the current thread

for (int TestSetId = 0; TestSetId < config.GetTestSetToRunQty(); ++TestSetId) {
config.SelectTestSet(TestSetId);
Expand Down

0 comments on commit dd4978b

Please sign in to comment.