#include #include #include #include template struct ValidateEngine { __host__ __device__ ValidateEngine(const typename Engine::result_type value_10000) : m_value_10000(value_10000) {} __host__ __device__ bool operator()(void) const { Engine e; e.discard(9999); // get the 10Kth result return e() == m_value_10000; } const typename Engine::result_type m_value_10000; }; // end ValidateEngine template struct ValidateEngineMin { __host__ __device__ bool operator()(void) const { Engine e; bool result = true; for(int i = 0; i < 10000; ++i) { result &= (e() >= Engine::min); } return result; } }; // end ValidateEngineMin template struct ValidateEngineMin { __host__ __device__ bool operator()(void) const { return true; } }; template struct ValidateEngineMax { __host__ __device__ bool operator()(void) const { Engine e; bool result = true; for(int i = 0; i < 10000; ++i) { result &= (e() <= Engine::max); } return result; } }; // end ValidateEngineMax template struct ValidateEngineEqual { __host__ __device__ bool operator()(void) const { bool result = true; // test from default constructor Engine e0, e1; result &= (e0 == e1); // advance engines e0.discard(10000); e1.discard(10000); result &= (e0 == e1); // test from identical seeds Engine e2(13), e3(13); result &= (e2 == e3); // test different seeds aren't equal Engine e4(7), e5(13); result &= !(e4 == e5); // test reseeding engine to the same seed causes equality e4.seed(13); result &= (e4 == e5); return result; } }; template struct ValidateEngineUnequal { __host__ __device__ bool operator()(void) const { bool result = true; // test from default constructor Engine e0, e1; result &= !(e0 != e1); // advance engines e0.discard(1000); e1.discard(1000); result &= !(e0 != e1); // test from identical seeds Engine e2(13), e3(13); result &= !(e2 != e3); // test different seeds aren't equal Engine e4(7), e5(13); result &= (e4 != e5); // test reseeding engine to the same seed causes equality e4.seed(13); result &= !(e4 != e5); // test different discards causes inequality Engine e6(13), e7(13); e6.discard(500); e7.discard(1000); result &= (e6 != e7); return result; } }; template struct ValidateDistributionMin { typedef Engine random_engine; __host__ __device__ ValidateDistributionMin(const Distribution &dd) : d(dd) {} __host__ __device__ bool operator()(void) { Engine e; bool result = true; for(int i = 0; i < 10000; ++i) { result &= (d(e) >= d.min()); } return result; } Distribution d; }; template struct ValidateDistributionMax { typedef Engine random_engine; __host__ __device__ ValidateDistributionMax(const Distribution &dd) : d(dd) {} __host__ __device__ bool operator()(void) { Engine e; bool result = true; for(int i = 0; i < 10000; ++i) { result &= (d(e) <= d.max()); } return result; } Distribution d; }; template struct ValidateDistributionEqual { __host__ __device__ bool operator()(void) const { return d0 == d1; } Distribution d0, d1; }; template struct ValidateDistributionUnqual { __host__ __device__ bool operator()(void) const { return d0 != d1; } Distribution d0, d1; }; template void TestEngineValidation(void) { // test host thrust::host_vector h(1); thrust::generate(h.begin(), h.end(), ValidateEngine(value_10000)); ASSERT_EQUAL(true, h[0]); // test device thrust::device_vector d(1); thrust::generate(d.begin(), d.end(), ValidateEngine(value_10000)); ASSERT_EQUAL(true, d[0]); } template void TestEngineMax(void) { // test host thrust::host_vector h(1); thrust::generate(h.begin(), h.end(), ValidateEngineMax()); ASSERT_EQUAL(true, h[0]); // test device thrust::device_vector d(1); thrust::generate(d.begin(), d.end(), ValidateEngineMax()); ASSERT_EQUAL(true, d[0]); } template void TestEngineMin(void) { // test host thrust::host_vector h(1); thrust::generate(h.begin(), h.end(), ValidateEngineMin()); ASSERT_EQUAL(true, h[0]); // test device thrust::device_vector d(1); thrust::generate(d.begin(), d.end(), ValidateEngineMin()); ASSERT_EQUAL(true, d[0]); } template void TestEngineSaveRestore(void) { // create a default engine Engine e0; // run it for a while e0.discard(10000); // save it std::stringstream ss; ss << e0; // run it a while longer e0.discard(10000); // restore old state Engine e1; ss >> e1; // run e1 a while longer e1.discard(10000); // both should return the same result ASSERT_EQUAL(e0(), e1()); } template void TestEngineEqual(void) { ValidateEngineEqual f; // test host thrust::host_vector h(1); thrust::generate(h.begin(), h.end(), f); ASSERT_EQUAL(true, h[0]); // test device thrust::device_vector d(1); thrust::generate(d.begin(), d.end(), f); ASSERT_EQUAL(true, d[0]); } template void TestEngineUnequal(void) { ValidateEngineUnequal f; // test host thrust::host_vector h(1); thrust::generate(h.begin(), h.end(), f); ASSERT_EQUAL(true, h[0]); // test device thrust::device_vector d(1); thrust::generate(d.begin(), d.end(), f); ASSERT_EQUAL(true, d[0]); } void TestRanlux24BaseValidation(void) { typedef thrust::random::ranlux24_base Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestRanlux24BaseValidation); void TestRanlux24BaseMin(void) { typedef thrust::random::ranlux24_base Engine; TestEngineMin(); } DECLARE_UNITTEST(TestRanlux24BaseMin); void TestRanlux24BaseMax(void) { typedef thrust::random::ranlux24_base Engine; TestEngineMax(); } DECLARE_UNITTEST(TestRanlux24BaseMax); void TestRanlux24BaseSaveRestore(void) { typedef thrust::random::ranlux24_base Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestRanlux24BaseSaveRestore); void TestRanlux24BaseEqual(void) { typedef thrust::random::ranlux24_base Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestRanlux24BaseEqual); void TestRanlux24BaseUnequal(void) { typedef thrust::random::ranlux24_base Engine; TestEngineUnequal(); } DECLARE_UNITTEST(TestRanlux24BaseUnequal); void TestRanlux48BaseValidation(void) { typedef thrust::random::ranlux48_base Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestRanlux48BaseValidation); void TestRanlux48BaseMin(void) { typedef thrust::random::ranlux48_base Engine; TestEngineMin(); } DECLARE_UNITTEST(TestRanlux48BaseMin); void TestRanlux48BaseMax(void) { typedef thrust::random::ranlux48_base Engine; TestEngineMax(); } DECLARE_UNITTEST(TestRanlux48BaseMax); void TestRanlux48BaseSaveRestore(void) { typedef thrust::random::ranlux48_base Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestRanlux48BaseSaveRestore); void TestRanlux48BaseEqual(void) { typedef thrust::random::ranlux48_base Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestRanlux48BaseEqual); #if defined(__INTEL_COMPILER) && 1800 >= __INTEL_COMPILER void TestRanlux48BaseUnequal(void) { // ICPC has a known failure with this test. // See nvbug 200414000. KNOWN_FAILURE; } #else void TestRanlux48BaseUnequal(void) { typedef thrust::random::ranlux48_base Engine; TestEngineUnequal(); } #endif DECLARE_UNITTEST(TestRanlux48BaseUnequal); void TestMinstdRandValidation(void) { typedef thrust::random::minstd_rand Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestMinstdRandValidation); void TestMinstdRandMin(void) { typedef thrust::random::minstd_rand Engine; TestEngineMin(); } DECLARE_UNITTEST(TestMinstdRandMin); void TestMinstdRandMax(void) { typedef thrust::random::minstd_rand Engine; TestEngineMax(); } DECLARE_UNITTEST(TestMinstdRandMax); void TestMinstdRandSaveRestore(void) { typedef thrust::random::minstd_rand Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestMinstdRandSaveRestore); void TestMinstdRandEqual(void) { typedef thrust::random::minstd_rand Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestMinstdRandEqual); void TestMinstdRandUnequal(void) { typedef thrust::random::minstd_rand Engine; TestEngineUnequal(); } DECLARE_UNITTEST(TestMinstdRandUnequal); void TestMinstdRand0Validation(void) { typedef thrust::random::minstd_rand0 Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestMinstdRand0Validation); void TestMinstdRand0Min(void) { typedef thrust::random::minstd_rand0 Engine; TestEngineMin(); } DECLARE_UNITTEST(TestMinstdRand0Min); void TestMinstdRand0Max(void) { typedef thrust::random::minstd_rand0 Engine; TestEngineMax(); } DECLARE_UNITTEST(TestMinstdRand0Max); void TestMinstdRand0SaveRestore(void) { typedef thrust::random::minstd_rand0 Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestMinstdRand0SaveRestore); void TestMinstdRand0Equal(void) { typedef thrust::random::minstd_rand0 Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestMinstdRand0Equal); void TestMinstdRand0Unequal(void) { typedef thrust::random::minstd_rand0 Engine; TestEngineUnequal(); } DECLARE_UNITTEST(TestMinstdRand0Unequal); void TestTaus88Validation(void) { typedef thrust::random::taus88 Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestTaus88Validation); void TestTaus88Min(void) { typedef thrust::random::taus88 Engine; TestEngineMin(); } DECLARE_UNITTEST(TestTaus88Min); void TestTaus88Max(void) { typedef thrust::random::taus88 Engine; TestEngineMax(); } DECLARE_UNITTEST(TestTaus88Max); void TestTaus88SaveRestore(void) { typedef thrust::random::taus88 Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestTaus88SaveRestore); void TestTaus88Equal(void) { typedef thrust::random::taus88 Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestTaus88Equal); void TestTaus88Unequal(void) { typedef thrust::random::taus88 Engine; TestEngineUnequal(); } DECLARE_UNITTEST(TestTaus88Unequal); void TestRanlux24Validation(void) { typedef thrust::random::ranlux24 Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestRanlux24Validation); void TestRanlux24Min(void) { typedef thrust::random::ranlux24 Engine; TestEngineMin(); } DECLARE_UNITTEST(TestRanlux24Min); void TestRanlux24Max(void) { typedef thrust::random::ranlux24 Engine; TestEngineMax(); } DECLARE_UNITTEST(TestRanlux24Max); void TestRanlux24SaveRestore(void) { typedef thrust::random::ranlux24 Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestRanlux24SaveRestore); void TestRanlux24Equal(void) { typedef thrust::random::ranlux24 Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestRanlux24Equal); void TestRanlux24Unequal(void) { typedef thrust::random::ranlux24 Engine; TestEngineUnequal(); } DECLARE_UNITTEST(TestRanlux24Unequal); void TestRanlux48Validation(void) { typedef thrust::random::ranlux48 Engine; TestEngineValidation(); } DECLARE_UNITTEST(TestRanlux48Validation); void TestRanlux48Min(void) { typedef thrust::random::ranlux48 Engine; TestEngineMin(); } DECLARE_UNITTEST(TestRanlux48Min); void TestRanlux48Max(void) { typedef thrust::random::ranlux48 Engine; TestEngineMax(); } DECLARE_UNITTEST(TestRanlux48Max); void TestRanlux48SaveRestore(void) { typedef thrust::random::ranlux48 Engine; TestEngineSaveRestore(); } DECLARE_UNITTEST(TestRanlux48SaveRestore); void TestRanlux48Equal(void) { typedef thrust::random::ranlux48 Engine; TestEngineEqual(); } DECLARE_UNITTEST(TestRanlux48Equal); void TestRanlux48Unequal(void) { typedef thrust::random::ranlux48 Engine; TestEngineUnequal(); } DECLARE_UNITTEST(TestRanlux48Unequal); template void ValidateDistributionCharacteristic(void) { typedef typename Validator::random_engine Engine; // test default-constructed Distribution // test host thrust::host_vector h(1); thrust::generate(h.begin(), h.end(), Validator(Distribution())); ASSERT_EQUAL(true, h[0]); // test device thrust::device_vector d(1); thrust::generate(d.begin(), d.end(), Validator(Distribution())); ASSERT_EQUAL(true, d[0]); // test distribution & engine with comparable ranges // only do this if they have the same result_type if(thrust::detail::is_same::value) { // test Distribution with same range as engine // test host THRUST_DISABLE_MSVC_WARNING_BEGIN(4305) thrust::generate(h.begin(), h.end(), Validator( Distribution(Engine::min, Engine::max) )); THRUST_DISABLE_MSVC_WARNING_END(4305) ASSERT_EQUAL(true, h[0]); // test device THRUST_DISABLE_MSVC_WARNING_BEGIN(4305) thrust::generate(d.begin(), d.end(), Validator( Distribution(Engine::min, Engine::max) )); THRUST_DISABLE_MSVC_WARNING_END(4305) ASSERT_EQUAL(true, d[0]); // test Distribution with smaller range than engine // test host THRUST_DISABLE_MSVC_WARNING_BEGIN(4305) // Truncation warning. typename Distribution::result_type engine_range = Engine::max - Engine::min; THRUST_DISABLE_MSVC_WARNING_END(4305) thrust::generate(h.begin(), h.end(), Validator(Distribution(engine_range/3, (2 * engine_range)/3))); ASSERT_EQUAL(true, h[0]); // test device thrust::generate(d.begin(), d.end(), Validator(Distribution(engine_range/3, (2 * engine_range)/3))); ASSERT_EQUAL(true, d[0]); } // test Distribution with a very small range // test host thrust::generate(h.begin(), h.end(), Validator(Distribution(1,6))); ASSERT_EQUAL(true, h[0]); // test device thrust::generate(d.begin(), d.end(), Validator(Distribution(1,6))); ASSERT_EQUAL(true, d[0]); } template void TestDistributionSaveRestore(void) { // create a default distribution Distribution d0(7, 13); // save it std::stringstream ss; ss << d0; // restore old state Distribution d1; ss >> d1; ASSERT_EQUAL(d0, d1); } void TestUniformIntDistributionMin(void) { typedef thrust::random::uniform_int_distribution int_dist; typedef thrust::random::uniform_int_distribution uint_dist; ValidateDistributionCharacteristic >(); ValidateDistributionCharacteristic >(); } DECLARE_UNITTEST(TestUniformIntDistributionMin); void TestUniformIntDistributionMax(void) { typedef thrust::random::uniform_int_distribution int_dist; typedef thrust::random::uniform_int_distribution uint_dist; ValidateDistributionCharacteristic >(); ValidateDistributionCharacteristic >(); } DECLARE_UNITTEST(TestUniformIntDistributionMax); void TestUniformIntDistributionSaveRestore(void) { typedef thrust::random::uniform_int_distribution int_dist; typedef thrust::random::uniform_int_distribution uint_dist; TestDistributionSaveRestore(); TestDistributionSaveRestore(); } DECLARE_UNITTEST(TestUniformIntDistributionSaveRestore); void TestUniformRealDistributionMin(void) { typedef thrust::random::uniform_real_distribution float_dist; typedef thrust::random::uniform_real_distribution double_dist; ValidateDistributionCharacteristic >(); ValidateDistributionCharacteristic >(); } DECLARE_UNITTEST(TestUniformRealDistributionMin); void TestUniformRealDistributionMax(void) { typedef thrust::random::uniform_real_distribution float_dist; typedef thrust::random::uniform_real_distribution double_dist; ValidateDistributionCharacteristic >(); ValidateDistributionCharacteristic >(); } DECLARE_UNITTEST(TestUniformRealDistributionMax); void TestUniformRealDistributionSaveRestore(void) { typedef thrust::random::uniform_real_distribution float_dist; typedef thrust::random::uniform_real_distribution double_dist; TestDistributionSaveRestore(); TestDistributionSaveRestore(); } DECLARE_UNITTEST(TestUniformRealDistributionSaveRestore); void TestNormalDistributionMin(void) { typedef thrust::random::normal_distribution float_dist; typedef thrust::random::normal_distribution double_dist; ValidateDistributionCharacteristic >(); ValidateDistributionCharacteristic >(); } DECLARE_UNITTEST(TestNormalDistributionMin); void TestNormalDistributionMax(void) { typedef thrust::random::normal_distribution float_dist; typedef thrust::random::normal_distribution double_dist; ValidateDistributionCharacteristic >(); ValidateDistributionCharacteristic >(); } DECLARE_UNITTEST(TestNormalDistributionMax); void TestNormalDistributionSaveRestore(void) { typedef thrust::random::normal_distribution float_dist; typedef thrust::random::normal_distribution double_dist; TestDistributionSaveRestore(); TestDistributionSaveRestore(); } DECLARE_UNITTEST(TestNormalDistributionSaveRestore);