Spaces:
Runtime error
Runtime error
template <typename Vector> | |
void TestShuffleSimple() { | |
Vector data(5); | |
data[0] = 0; | |
data[1] = 1; | |
data[2] = 2; | |
data[3] = 3; | |
data[4] = 4; | |
Vector shuffled(data.begin(), data.end()); | |
thrust::default_random_engine g(2); | |
thrust::shuffle(shuffled.begin(), shuffled.end(), g); | |
thrust::sort(shuffled.begin(), shuffled.end()); | |
// Check all of our data is present | |
// This only tests for strange conditions like duplicated elements | |
ASSERT_EQUAL(shuffled, data); | |
} | |
DECLARE_VECTOR_UNITTEST(TestShuffleSimple); | |
template <typename Vector> | |
void TestShuffleCopySimple() { | |
Vector data(5); | |
data[0] = 0; | |
data[1] = 1; | |
data[2] = 2; | |
data[3] = 3; | |
data[4] = 4; | |
Vector shuffled(5); | |
thrust::default_random_engine g(2); | |
thrust::shuffle_copy(data.begin(), data.end(), shuffled.begin(), g); | |
g.seed(2); | |
thrust::shuffle(data.begin(), data.end(), g); | |
ASSERT_EQUAL(shuffled, data); | |
} | |
DECLARE_VECTOR_UNITTEST(TestShuffleCopySimple); | |
template <typename T> | |
void TestHostDeviceIdentical(size_t m) { | |
thrust::host_vector<T> host_result(m); | |
thrust::host_vector<T> device_result(m); | |
thrust::sequence(host_result.begin(), host_result.end(), 0llu); | |
thrust::sequence(device_result.begin(), device_result.end(), 0llu); | |
thrust::default_random_engine host_g(183); | |
thrust::default_random_engine device_g(183); | |
thrust::shuffle(host_result.begin(), host_result.end(), host_g); | |
thrust::shuffle(device_result.begin(), device_result.end(), device_g); | |
ASSERT_EQUAL(device_result, host_result); | |
} | |
DECLARE_VARIABLE_UNITTEST(TestHostDeviceIdentical); | |
// Individual input keys should be permuted to output locations with uniform | |
// probability. Perform chi-squared test with confidence 99.9%. | |
template <typename Vector> | |
void TestShuffleKeyPosition() { | |
typedef typename Vector::value_type T; | |
size_t m = 20; | |
size_t num_samples = 100; | |
thrust::host_vector<size_t> index_sum(m, 0); | |
thrust::host_vector<T> sequence(m); | |
thrust::sequence(sequence.begin(), sequence.end(), T(0)); | |
for (size_t i = 0; i < num_samples; i++) { | |
Vector shuffled(sequence.begin(), sequence.end()); | |
thrust::default_random_engine g(i); | |
thrust::shuffle(shuffled.begin(), shuffled.end(), g); | |
thrust::host_vector<T> tmp(shuffled.begin(), shuffled.end()); | |
for (auto j = 0ull; j < m; j++) { | |
index_sum[tmp[j]] += j; | |
} | |
} | |
double expected_average_position = static_cast<double>(m - 1) / 2; | |
double chi_squared = 0.0; | |
for (auto j = 0ull; j < m; j++) { | |
double average_position = static_cast<double>(index_sum[j]) / num_samples; | |
chi_squared += std::pow(expected_average_position - average_position, 2) / | |
expected_average_position; | |
} | |
// Tabulated chi-squared critical value for m-1=19 degrees of freedom | |
// and 99.9% confidence | |
double confidence_threshold = 43.82; | |
ASSERT_LESS(chi_squared, confidence_threshold); | |
} | |
DECLARE_INTEGRAL_VECTOR_UNITTEST(TestShuffleKeyPosition); | |
struct vector_compare { | |
template <typename VectorT> | |
bool operator()(const VectorT& a, const VectorT& b) const { | |
for (auto i = 0ull; i < a.size(); i++) { | |
if (a[i] < b[i]) return true; | |
if (a[i] > b[i]) return false; | |
} | |
return false; | |
} | |
}; | |
// Brute force check permutations are uniformly distributed on small input | |
// Uses a chi-squared test indicating 99% confidence the output is uniformly | |
// random | |
template <typename Vector> | |
void TestShuffleUniformPermutation() { | |
typedef typename Vector::value_type T; | |
size_t m = 5; | |
size_t num_samples = 1000; | |
size_t total_permutations = 1 * 2 * 3 * 4 * 5; | |
std::map<thrust::host_vector<T>, size_t, vector_compare> permutation_counts; | |
Vector sequence(m); | |
thrust::sequence(sequence.begin(), sequence.end(), T(0)); | |
thrust::default_random_engine g(17); | |
for (auto i = 0ull; i < num_samples; i++) { | |
thrust::shuffle(sequence.begin(), sequence.end(), g); | |
thrust::host_vector<T> tmp(sequence.begin(), sequence.end()); | |
permutation_counts[tmp]++; | |
} | |
ASSERT_EQUAL(permutation_counts.size(), total_permutations); | |
double chi_squared = 0.0; | |
double expected_count = static_cast<double>(num_samples) / total_permutations; | |
for (auto kv : permutation_counts) { | |
chi_squared += std::pow(expected_count - kv.second, 2) / expected_count; | |
} | |
// Tabulated chi-squared critical value for 119 degrees of freedom (5! - 1) | |
// and 99% confidence | |
double confidence_threshold = 157.8; | |
ASSERT_LESS(chi_squared, confidence_threshold); | |
} | |
DECLARE_VECTOR_UNITTEST(TestShuffleUniformPermutation); | |