Skip to content

Commit

Permalink
Replace rand() with rand_uint_32b() for reproducibility (#674)
Browse files Browse the repository at this point in the history
  • Loading branch information
Koren-Brand authored Dec 5, 2024
1 parent 6597d85 commit 41c01ce
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 111 deletions.
14 changes: 13 additions & 1 deletion icicle/include/icicle/utils/rand_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,16 @@
#include <random>

inline std::mt19937 rand_generator = std::mt19937{std::random_device{}()};
static void seed_rand_generator(unsigned seed) { rand_generator.seed(seed); }
static void seed_rand_generator(unsigned seed) { rand_generator.seed(seed); }

/**
* @brief Generate random unsigned integer in range (inclusive)
* @param min Lower limit.
* @param max Upper limit.
* @return Random (uniform distribution) unsigned integer s.t. min <= integer <= max.
*/
static uint32_t rand_uint_32b(uint32_t min = 0, uint32_t max = UINT32_MAX)
{
std::uniform_int_distribution<uint32_t> dist(min, max);
return dist(rand_generator);
}
11 changes: 6 additions & 5 deletions icicle/tests/test_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ class IcicleTestBase : public ::testing::Test
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
static void SetUpTestSuite()
{
unsigned seed = time(NULL);
srand(seed);
ICICLE_LOG_INFO << "Seed for tests is: " << seed;
seed_rand_generator(seed);
#ifdef BACKEND_BUILD_DIR
setenv("ICICLE_BACKEND_INSTALL_DIR", BACKEND_BUILD_DIR, 0 /*=replace*/);
#endif
Expand All @@ -53,7 +49,12 @@ class IcicleTestBase : public ::testing::Test
static void TearDownTestSuite() {}

// SetUp/TearDown are called before and after each test
void SetUp() override {}
void SetUp() override
{
unsigned seed = time(NULL);
ICICLE_LOG_INFO << "Seed for test is: " << seed;
seed_rand_generator(seed);
}
void TearDown() override {}

bool is_main_device_available() const { return s_main_device != UNKOWN_DEVICE && s_main_device != "CPU"; }
Expand Down
9 changes: 5 additions & 4 deletions icicle/tests/test_curve_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "icicle/backend/ntt_config.h"

#include "test_base.h"
#include "icicle/utils/rand_gen.h"

using namespace curve_config;
using namespace icicle;
Expand All @@ -36,8 +37,8 @@ class CurveApiTest : public IcicleTestBase
{
const int logn = 12;
const int batch = 3;
const int N = (1 << logn) - rand() % (5 * logn); // make it not always power of two
const int precompute_factor = (rand() & 7) + 1; // between 1 and 8
const int N = (1 << logn) - rand_uint_32b(0, 5 * logn); // make it not always power of two
const int precompute_factor = rand_uint_32b(0, 7) + 1; // between 1 and 8
const int total_nof_elemets = batch * N;

auto scalars = std::make_unique<scalar_t[]>(total_nof_elemets);
Expand Down Expand Up @@ -90,8 +91,8 @@ class CurveApiTest : public IcicleTestBase
// As such the default amount of tasks and 1 thread shouldn't be enough and the program should readjust the task
// number per thread.
const int batch = 3;
const int N = (1 << logn) - rand() % (5 * logn); // make it not always power of two
const int precompute_factor = 1; // Precompute is 1 to increase number of BMs
const int N = (1 << logn) - rand_uint_32b(0, 5 * logn); // make it not always power of two
const int precompute_factor = 1; // Precompute is 1 to increase number of BMs
const int total_nof_elemets = batch * N;

auto scalars = std::make_unique<scalar_t[]>(total_nof_elemets);
Expand Down
5 changes: 3 additions & 2 deletions icicle/tests/test_device_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "icicle/runtime.h"
#include "icicle/memory_tracker.h"
#include "test_base.h"
#include "icicle/utils/rand_gen.h"

using namespace icicle;

Expand Down Expand Up @@ -183,7 +184,7 @@ TEST_F(DeviceApiTest, memoryTracker)
START_TIMER(lookup);
for (auto& it : allocated_addresses) {
// identify addresses identified correctly (to active device)
const void* addr = (void*)((size_t)it + rand() % ALLOC_SIZE);
const void* addr = (void*)((size_t)it + rand_uint_32b(0, RAND_MAX) % ALLOC_SIZE);
ICICLE_CHECK(icicle_is_active_device_memory(addr));
}
END_TIMER_AVERAGE(lookup, "memory-tracker: lookup (and compare) average", true, NOF_ALLOCS);
Expand All @@ -195,7 +196,7 @@ TEST_F(DeviceApiTest, memoryTracker)

// test that we still identify correctly after switching device
icicle_set_device({"CPU", 0});
const void* addr = (void*)((size_t)*allocated_addresses.begin() + rand() % ALLOC_SIZE);
const void* addr = (void*)((size_t)*allocated_addresses.begin() + rand_uint_32b(0, RAND_MAX) % ALLOC_SIZE);
ASSERT_EQ(eIcicleError::INVALID_POINTER, icicle_is_active_device_memory(addr));
ASSERT_EQ(eIcicleError::INVALID_POINTER, icicle_is_active_device_memory(host_mem.get()));
auto it = tracker.identify(addr);
Expand Down
131 changes: 47 additions & 84 deletions icicle/tests/test_field_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,9 @@ TYPED_TEST(FieldApiTest, FieldSanityTest)

TYPED_TEST(FieldApiTest, vectorVectorOps)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t N = 1 << (rand() % 15 + 3);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const uint64_t N = 1 << rand_uint_32b(3, 17);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);

ICICLE_LOG_DEBUG << "N = " << N;
ICICLE_LOG_DEBUG << "batch_size = " << batch_size;
Expand Down Expand Up @@ -179,13 +176,10 @@ TYPED_TEST(FieldApiTest, vectorVectorOps)

TYPED_TEST(FieldApiTest, montgomeryConversion)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t N = 1 << (rand() % 15 + 3);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const bool is_to_montgomery = rand() % 2;
const uint64_t N = 1 << rand_uint_32b(3, 17);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);
const bool is_to_montgomery = rand_uint_32b(0, 1);
ICICLE_LOG_DEBUG << "N = " << N;
ICICLE_LOG_DEBUG << "batch_size = " << batch_size;
ICICLE_LOG_DEBUG << "columns_batch = " << columns_batch;
Expand Down Expand Up @@ -234,12 +228,9 @@ TYPED_TEST(FieldApiTest, montgomeryConversion)

TEST_F(FieldApiTestBase, VectorReduceOps)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t N = 1 << (rand() % 15 + 3);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const uint64_t N = 1 << rand_uint_32b(3, 17);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);
const int total_size = N * batch_size;

ICICLE_LOG_DEBUG << "N = " << N;
Expand Down Expand Up @@ -319,12 +310,9 @@ TEST_F(FieldApiTestBase, VectorReduceOps)

TEST_F(FieldApiTestBase, scalarVectorOps)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t N = 1 << (rand() % 15 + 3);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const uint64_t N = 1 << rand_uint_32b(3, 17);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);

ICICLE_LOG_DEBUG << "N = " << N;
ICICLE_LOG_DEBUG << "batch_size = " << batch_size;
Expand Down Expand Up @@ -431,20 +419,13 @@ TEST_F(FieldApiTestBase, scalarVectorOps)

TYPED_TEST(FieldApiTest, matrixAPIsAsync)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const int R =
1
<< (rand() % 8 + 2); // cpu implementation for out of place transpose also supports sizes which are not powers of 2
const int C =
1
<< (rand() % 8 + 2); // cpu implementation for out of place transpose also supports sizes which are not powers of 2
const int batch_size = 1 << (rand() % 4);
const bool columns_batch = rand() % 2;
const bool is_in_place = IcicleTestBase::is_main_device_available()
? 0
: rand() % 2; // TODO - fix inplace (Hadar: I'm not sure we should support it)
const int R = 1 << rand_uint_32b(
2, 9); // cpu implementation for out of place transpose also supports sizes which are not powers of 2
const int C = 1 << rand_uint_32b(
2, 9); // cpu implementation for out of place transpose also supports sizes which are not powers of 2
const int batch_size = 1 << rand_uint_32b(0, 3);
const bool columns_batch = rand_uint_32b(0, 1);
const bool is_in_place = IcicleTestBase::is_main_device_available() ? 0 : rand_uint_32b(0, 1);

ICICLE_LOG_DEBUG << "rows = " << R;
ICICLE_LOG_DEBUG << "cols = " << C;
Expand Down Expand Up @@ -537,13 +518,10 @@ TYPED_TEST(FieldApiTest, matrixAPIsAsync)

TYPED_TEST(FieldApiTest, bitReverse)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t N = 1 << (rand() % 15 + 3);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const bool is_in_place = rand() % 2;
const uint64_t N = 1 << rand_uint_32b(3, 17);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);
const bool is_in_place = rand_uint_32b(0, 1);
const int total_size = N * batch_size;

ICICLE_LOG_DEBUG << "N = " << N;
Expand Down Expand Up @@ -613,15 +591,12 @@ TYPED_TEST(FieldApiTest, bitReverse)

TYPED_TEST(FieldApiTest, Slice)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t size_in = 1 << (rand() % 15 + 5);
const uint64_t offset = rand() % 15;
const uint64_t stride = rand() % 4 + 1;
const uint64_t size_out = rand() % (((size_in - offset) / stride) - 1) + 1;
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const uint64_t size_in = 1 << rand_uint_32b(4, 17);
const uint64_t offset = rand_uint_32b(0, 14);
const uint64_t stride = rand_uint_32b(1, 4);
const uint64_t size_out = rand_uint_32b(0, (size_in - offset) / stride);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);

ICICLE_LOG_DEBUG << "size_in = " << size_in;
ICICLE_LOG_DEBUG << "size_out = " << size_out;
Expand Down Expand Up @@ -677,12 +652,9 @@ TYPED_TEST(FieldApiTest, Slice)

TEST_F(FieldApiTestBase, highestNonZeroIdx)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t N = 1 << (rand() % 15 + 3);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const uint64_t N = 1 << rand_uint_32b(3, 17);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);
const int total_size = N * batch_size;

auto in_a = std::make_unique<scalar_t[]>(total_size);
Expand Down Expand Up @@ -718,13 +690,10 @@ TEST_F(FieldApiTestBase, highestNonZeroIdx)

TEST_F(FieldApiTestBase, polynomialEval)
{
int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const uint64_t coeffs_size = 1 << (rand() % 10 + 4);
const uint64_t domain_size = 1 << (rand() % 8 + 2);
const int batch_size = 1 << (rand() % 5);
const bool columns_batch = rand() % 2;
const uint64_t coeffs_size = 1 << rand_uint_32b(4, 13);
const uint64_t domain_size = 1 << rand_uint_32b(2, 9);
const int batch_size = 1 << rand_uint_32b(0, 4);
const bool columns_batch = rand_uint_32b(0, 1);

ICICLE_LOG_DEBUG << "coeffs_size = " << coeffs_size;
ICICLE_LOG_DEBUG << "domain_size = " << domain_size;
Expand Down Expand Up @@ -766,13 +735,11 @@ TEST_F(FieldApiTestBase, polynomialEval)

TEST_F(FieldApiTestBase, polynomialDivision)
{
int seed = time(0);
srand(seed);
const uint64_t numerator_size = 1 << (rand() % 3 + 5);
const uint64_t denominator_size = 1 << (rand() % 2 + 3);
const uint64_t numerator_size = 1 << rand_uint_32b(5, 7);
const uint64_t denominator_size = 1 << rand_uint_32b(3, 4);
const uint64_t q_size = numerator_size - denominator_size + 1;
const uint64_t r_size = numerator_size;
const int batch_size = 10 + rand() % 10;
const int batch_size = rand_uint_32b(10, 19);

// basically we compute q(x),r(x) for a(x)=q(x)b(x)+r(x) by dividing a(x)/b(x)

Expand Down Expand Up @@ -844,26 +811,22 @@ TEST_F(FieldApiTestBase, polynomialDivision)
TYPED_TEST(FieldApiTest, ntt)
{
// Randomize configuration

int seed = time(0);
srand(seed);
ICICLE_LOG_DEBUG << "seed = " << seed;
const bool inplace = rand() % 2;
const int logn = rand() % 15 + 3;
const bool inplace = rand_uint_32b(0, 1);
const int logn = rand_uint_32b(3, 17);
const uint64_t N = 1 << logn;
const int log_ntt_domain_size = logn + 1;
const int log_batch_size = rand() % 3;
const int log_batch_size = rand_uint_32b(0, 2);
const int batch_size = 1 << log_batch_size;
const int _ordering = rand() % 4;
const int _ordering = rand_uint_32b(0, 3);
const Ordering ordering = static_cast<Ordering>(_ordering);
bool columns_batch;
if (logn == 7 || logn < 4) {
columns_batch = false; // currently not supported (icicle_v3/backend/cuda/src/ntt/ntt.cuh line 578)
} else {
columns_batch = rand() % 2;
columns_batch = rand_uint_32b(0, 1);
}
const NTTDir dir = static_cast<NTTDir>(rand() % 2); // 0: forward, 1: inverse
const int log_coset_stride = rand() % 3;
const NTTDir dir = static_cast<NTTDir>(rand_uint_32b(0, 1)); // 0: forward, 1: inverse
const int log_coset_stride = rand_uint_32b(0, 2);
scalar_t coset_gen;
if (log_coset_stride) {
coset_gen = scalar_t::omega(logn + log_coset_stride);
Expand Down
Loading

0 comments on commit 41c01ce

Please sign in to comment.