From 182ec439c21dc547d853b5634b8c710335cf030b Mon Sep 17 00:00:00 2001 From: Ruslan Arutyunyan Date: Wed, 31 Jul 2024 03:03:45 -0600 Subject: [PATCH 01/13] [Executors] Publish a history of P2500 parallel algorithms (#7) Co-authored-by: Alexey Kukanov From 7f4cc076c7bf444ce359b7bf8ffa9b866b73a732 Mon Sep 17 00:00:00 2001 From: Ruslan Arutyunyan Date: Fri, 26 Jul 2024 00:45:14 -0600 Subject: [PATCH 02/13] Add permutation table, fix logarithmic_index, add operator== --- rng/philox/philox.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index 51cdbe2..47b017a 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -274,6 +274,14 @@ struct philox_engine state_i = n - 1; } + void reset_counter() + { + for (std::size_t j = 0; j < n; ++j) { + x[j] = 0; + } + state_i = n - 1; + } + static constexpr result_type max_impl() { return w == std::numeric_limits::digits From d7136dcefaf7191aa27aec6b76916f497b8bca29 Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Fri, 26 Jul 2024 04:31:46 -0700 Subject: [PATCH 03/13] fix discard --- rng/philox/philox.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index 47b017a..1236350 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -282,6 +282,22 @@ struct philox_engine state_i = n - 1; } + void reset_counter() + { + for (std::size_t j = 0; j < n; ++j) { + x[j] = 0; + } + state_i = n - 1; + } + + void reset_counter() + { + for (std::size_t j = 0; j < n; ++j) { + x[j] = 0; + } + state_i = n - 1; + } + static constexpr result_type max_impl() { return w == std::numeric_limits::digits From bccc3b45aaef4e9a5c49b0f0ed5a59c8ed0788a7 Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Fri, 26 Jul 2024 04:32:06 -0700 Subject: [PATCH 04/13] add tests --- rng/philox/test.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 rng/philox/test.cpp diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp new file mode 100644 index 0000000..07042a5 --- /dev/null +++ b/rng/philox/test.cpp @@ -0,0 +1,98 @@ +#include +#include +#include + +#include "philox.hpp" + +// Test the conformance of the implementation with the ISO C++ standard +template +void conformance_test() { + { + Engine engine; + for(int i = 0; i < 9999; i++) { + engine(); + } + typename Engine::result_type reference; + if(std::is_same_v) { + reference = 1955073260; + } + else { + reference = 3409172418970261260; + } + if(engine() == reference) { + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; + } else { + std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } + } +} + +template +void seed_test() { + for(int i = 1; i < 5; i++) { // make sure that the state is reset properly for all idx positions + Engine engine; + typename Engine::result_type res; + for(int j = 0; j < i - 1; j++) { + engine(); + } + res = engine(); + engine.seed(); + for(int j = 0; j < i - 1; j++) { + engine(); + } + if(res != engine()) { + std::cout << __PRETTY_FUNCTION__ << " failed while generating " << i << " elements" << std::endl; + } + } + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; +} + +template +void discard_test() { + { + constexpr size_t n = 10; // arbitrary length we want to check + typename Engine::result_type reference[n]; + Engine engine; + for(int i = 0; i < n; i++) { + reference[i] = engine(); + } + for(int i = 0; i < n; i++) { + engine.seed(); + engine.discard(i); + for(size_t j = i; j < n; j++) { + if(reference[j] != engine()) { + std::cout << __PRETTY_FUNCTION__ << " failed with error in element " << j << " discard " << i << std::endl; + break; + } + } + } + std::cout << __PRETTY_FUNCTION__ << " passed step 1 discard from the intial state" << std::endl; + + for(int i = 1; i < n; i++) { + engine.seed(); + for(size_t j = 0; j < i - 1; j++) { + engine(); + } + engine.discard(1); + if(reference[i] != engine()) { + std::cout << __PRETTY_FUNCTION__ << " failed on step " << i << std::endl; + break; + } + } + std::cout << __PRETTY_FUNCTION__ << " passed step 2 discard after generation" << std::endl; + } +} + + +int main() { + conformance_test(); + conformance_test(); + + seed_test(); + seed_test(); + + discard_test(); + discard_test(); + + return 0; +} \ No newline at end of file From 3a2d85b120e23618d6cc2eb6675f1677053ec780 Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Mon, 29 Jul 2024 03:37:25 -0700 Subject: [PATCH 05/13] Add set_counter tests --- rng/philox/test.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index 07042a5..5319156 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -83,6 +83,74 @@ void discard_test() { } } +template +void set_counter_conformance_test() { + Engine engine; + std::array counter; + for(int i = 0; i < Engine::word_count - 1; i++) { + counter[i] = 0; + } + + counter[Engine::word_count - 1] = 2499; // to get 10'000 element + engine.set_counter(counter); + + for(int i = 0; i < Engine::word_count - 1; i++) { + engine(); + } + + typename Engine::result_type reference; + if(std::is_same_v) { + reference = 1955073260; + } + else { + reference = 3409172418970261260; + } + if(engine() == reference) { + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; + } else { + std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } +} + +template +void skip_test() { + using T = typename Engine::result_type; + Engine engine1; + std::array counter = {0, 0, 0, 5}; + engine1.set_counter(counter); + Engine engine2; + engine2.discard(5 * Engine::word_count); + + if(engine1() == engine2()) { + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; + } else { + std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } +} + +template +void counter_overflow_test() { + using T = typename Engine::result_type; + Engine engine1; + std::array counter; + for(int i = 0; i < Engine::word_count; i++) { + counter[i] = std::numeric_limits::max(); + } + + engine1.set_counter(counter); + for(int i = 0; i < Engine::word_count; i++) { + engine1(); + } // all counters overflowed == start from 0 0 0 0 + + Engine engine2; + + if(engine1() == engine2()) { + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; + } else { + std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } +} + int main() { conformance_test(); @@ -94,5 +162,14 @@ int main() { discard_test(); discard_test(); + set_counter_conformance_test(); + set_counter_conformance_test(); + + skip_test(); + skip_test(); + + counter_overflow_test(); + counter_overflow_test(); + return 0; } \ No newline at end of file From 433dfee6d675cd80c02d2fbc8a015cb6b1466694 Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Mon, 29 Jul 2024 04:13:00 -0700 Subject: [PATCH 06/13] Harder skip test --- rng/philox/test.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index 5319156..4149555 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -115,17 +115,23 @@ void set_counter_conformance_test() { template void skip_test() { using T = typename Engine::result_type; - Engine engine1; - std::array counter = {0, 0, 0, 5}; - engine1.set_counter(counter); - Engine engine2; - engine2.discard(5 * Engine::word_count); + for(T i = 1; i <= Engine::word_count + 1; i++) { + Engine engine1; + std::array counter = {0, 0, 0, i / Engine::word_count}; + engine1.set_counter(counter); + for(T j = 0; j < i % Engine::word_count; j++) { + engine1(); + } - if(engine1() == engine2()) { - std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; - } else { - std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + Engine engine2; + engine2.discard(i); + + if(engine1() != engine2()) { + std::cout << __PRETTY_FUNCTION__ << " failed for " << i << " skip" << std::endl; + return; + } } + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; } template From 1e72e28a2d83a9b441ab4955372b0e5d21b1f4af Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Thu, 1 Aug 2024 05:26:40 -0700 Subject: [PATCH 07/13] discard fix --- rng/philox/philox.hpp | 24 ------------------------ rng/philox/test.cpp | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index 1236350..51cdbe2 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -274,30 +274,6 @@ struct philox_engine state_i = n - 1; } - void reset_counter() - { - for (std::size_t j = 0; j < n; ++j) { - x[j] = 0; - } - state_i = n - 1; - } - - void reset_counter() - { - for (std::size_t j = 0; j < n; ++j) { - x[j] = 0; - } - state_i = n - 1; - } - - void reset_counter() - { - for (std::size_t j = 0; j < n; ++j) { - x[j] = 0; - } - state_i = n - 1; - } - static constexpr result_type max_impl() { return w == std::numeric_limits::digits diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index 4149555..cbcf52a 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -69,14 +69,17 @@ void discard_test() { std::cout << __PRETTY_FUNCTION__ << " passed step 1 discard from the intial state" << std::endl; for(int i = 1; i < n; i++) { - engine.seed(); - for(size_t j = 0; j < i - 1; j++) { - engine(); - } - engine.discard(1); - if(reference[i] != engine()) { - std::cout << __PRETTY_FUNCTION__ << " failed on step " << i << std::endl; - break; + for(int j = 1; j < i; j++) { + engine.seed(); + for(size_t k = 0; k < i - j; k++) { + engine(); + } + engine.discard(j); + if(reference[i] != engine()) { + std::cout << __PRETTY_FUNCTION__ << " failed on step " << i << " " << j << std::endl; + exit(-1); + break; + } } } std::cout << __PRETTY_FUNCTION__ << " passed step 2 discard after generation" << std::endl; From 0f9f544375b6f6d05ed14f368fb39e06fe342ae7 Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Fri, 2 Aug 2024 03:43:24 -0700 Subject: [PATCH 08/13] add discard overflow check --- rng/philox/test.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index cbcf52a..c1a41aa 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -160,6 +160,40 @@ void counter_overflow_test() { } } +template +void discard_overflow_test() { + using T = typename Engine::result_type; + Engine engine1; + std::array counter; + + for(int i = 0; i < Engine::word_count; i++) { + counter[i] = 0; + } + + if(std::is_same_v) { + counter[1] = 1; + } + else if(std::is_same_v) { + counter[2] = 1; + } + + engine1.set_counter(counter); + + Engine engine2; + + for(int i = 0; i < Engine::word_count; i++) { + engine2(); + } + for(int i = 0; i < Engine::word_count; i++) { + engine2.discard(std::numeric_limits::max()); + } + + if(engine1() == engine2()) { + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; + } else { + std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } +} int main() { conformance_test(); @@ -180,5 +214,8 @@ int main() { counter_overflow_test(); counter_overflow_test(); + discard_overflow_test(); + discard_overflow_test(); + return 0; -} \ No newline at end of file +} From d5350a348a1e5289545ad9ac96813e602422c55a Mon Sep 17 00:00:00 2001 From: "Elizarova, Alina" Date: Fri, 2 Aug 2024 05:40:46 -0700 Subject: [PATCH 09/13] add operators >> << --- rng/philox/philox.hpp | 102 +++++++++++++++++++++++++++++++++++++++--- rng/philox/test.cpp | 78 ++++++++++++++++++++++++++------ 2 files changed, 161 insertions(+), 19 deletions(-) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index 51cdbe2..2b1703b 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -38,8 +38,46 @@ namespace detail { { static constexpr std::size_t value = Is * 2; }; + + template + class save_stream_flags + { + typedef ::std::basic_ios<_CharT, _Traits> stream_type; + + public: + save_stream_flags(const save_stream_flags&) = delete; + save_stream_flags& + operator=(const save_stream_flags&) = delete; + + explicit save_stream_flags(stream_type& stream) + : stream_(stream), fmtflags_(stream.flags()), fill_(stream.fill()) + { + } + ~save_stream_flags() + { + stream_.flags(fmtflags_); + stream_.fill(fill_); + } + + private: + typename stream_type::fmtflags fmtflags_; + stream_type& stream_; + _CharT fill_; + }; } // namespace detail +template +struct philox_engine; + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const philox_engine& x); + +template +std::basic_istream& +operator>>(std::basic_istream& is, philox_engine& x); + + template struct philox_engine { @@ -171,13 +209,13 @@ struct philox_engine } // inserters and extractors - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const philox_engine& x); + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const philox_engine& x); - template - friend std::basic_istream& - operator>>(std::basic_istream& is, philox_engine& x); + template + friend std::basic_istream& + operator>>(std::basic_istream& is, philox_engine& x); private: // utilities @@ -289,6 +327,58 @@ struct philox_engine std::uint32_t state_i; }; +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const philox_engine& engine) { + + detail::save_stream_flags flags(os); + + os.setf(std::ios_base::dec | std::ios_base::left); + CharT sp = os.widen(' '); + os.fill(sp); + + for (std::size_t i = 0; i < n / 2; ++i) { + os << engine.k[i] << sp; + } + for (std::size_t i = 0; i < n; ++i) { + os << engine.x[i] << sp; + } + for (std::size_t i = 0; i < n; ++i) { + os << engine.y[i] << sp; + } + os << engine.state_i; + return os; +} + +template +std::basic_istream& +operator>>(std::basic_istream& is, philox_engine& engine) { + detail::save_stream_flags flags(is); + + is.setf(std::ios_base::dec | std::ios_base::skipws); + + // need a check for the different types? + UIntType tmp[5 * n / 2 + 1]; + + for (std::size_t i = 0; i < 5 * n / 2 + 1; ++i) { + is >> tmp[i]; + } + if(!is.fail()) { + std::size_t j = 0; + for (std::size_t i = 0; i < n / 2; ++i) { + engine.k[i] = tmp[j++]; + } + for (std::size_t i = 0; i < n; ++i) { + engine.x[i] = tmp[j++]; + } + for (std::size_t i = 0; i < n; ++i) { + engine.y[i] = tmp[j++]; + } + engine.state_i = tmp[j]; // do we change state_i or set it to n - 1 ? + } + return is; +} + using philox4x32 = philox_engine; using philox4x64 = philox_engine; diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index c1a41aa..0ab0854 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -1,30 +1,80 @@ #include +#include #include #include +#include #include "philox.hpp" // Test the conformance of the implementation with the ISO C++ standard template void conformance_test() { + Engine engine; + for(int i = 0; i < 9999; i++) { + engine(); + } + typename Engine::result_type reference; + if(std::is_same_v) { + reference = 1955073260; + } + else { + reference = 3409172418970261260; + } + if(engine() == reference) { + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; + } else { + std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } +} + +// Test public API +template +void api_test() { { Engine engine; - for(int i = 0; i < 9999; i++) { - engine(); - } - typename Engine::result_type reference; - if(std::is_same_v) { - reference = 1955073260; + engine.seed(); + } + { + Engine engine(1); + engine.seed(1); + } + { + std::seed_seq s; + Engine engine(s); + engine.seed(s); + } + { + Engine engine; + Engine engine2; + if(!(engine == engine2) || (engine != engine2)) { + std::cout << __PRETTY_FUNCTION__ << " failed !=, == for the same engines" << std::endl; + return; } - else { - reference = 3409172418970261260; + engine2.seed(42); + if((engine == engine2) || !(engine != engine2)) { + std::cout << __PRETTY_FUNCTION__ << " failed !=, == for the different engines" << std::endl; + return; } - if(engine() == reference) { - std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; - } else { - std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + } + { + std::ostringstream os; + Engine engine; + os << engine << std::endl; + Engine engine2; + engine2(); + std::istringstream in(os.str()); + in >> engine2; + if(engine != engine2) { + std::cout << __PRETTY_FUNCTION__ << " failed for >> << operators" << std::endl; + return; } } + { + Engine engine; + engine.min(); + engine.max(); + } + std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; } template @@ -77,7 +127,6 @@ void discard_test() { engine.discard(j); if(reference[i] != engine()) { std::cout << __PRETTY_FUNCTION__ << " failed on step " << i << " " << j << std::endl; - exit(-1); break; } } @@ -199,6 +248,9 @@ int main() { conformance_test(); conformance_test(); + api_test(); + api_test(); + seed_test(); seed_test(); From 7fff47cd1aadb3740cdf2f8dca18b2357a39d9fc Mon Sep 17 00:00:00 2001 From: Elizarova Alina Date: Thu, 20 Mar 2025 08:29:20 -0700 Subject: [PATCH 10/13] extend overflow test and fix max --- rng/philox/philox.hpp | 9 +------- rng/philox/test.cpp | 53 +++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index 2b1703b..fb62afb 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -111,7 +111,7 @@ struct philox_engine static constexpr std::array multipliers = extract_elements(even_indices_sequence{}); static constexpr std::array round_consts = extract_elements(odd_indices_sequence{}); static constexpr result_type min() { return 0; } - static constexpr result_type max() { return max_impl(); } + static constexpr result_type max() { return result_mask; } static constexpr result_type default_seed = 20111115u; // constructors and seeding functions philox_engine() : philox_engine(default_seed) {} @@ -312,13 +312,6 @@ struct philox_engine state_i = n - 1; } - static constexpr result_type max_impl() - { - return w == std::numeric_limits::digits - ? std::numeric_limits::digits - 1 - : (result_type(1) << w) - 1; - } - public: // state std::array x; std::array k; diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index 0ab0854..dd3c17f 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -212,35 +212,40 @@ void counter_overflow_test() { template void discard_overflow_test() { using T = typename Engine::result_type; - Engine engine1; - std::array counter; + for (int overflow_position = 0; overflow_position < Engine::word_count - 1; overflow_position++) { + Engine engine1; + std::array counter = {0}; - for(int i = 0; i < Engine::word_count; i++) { - counter[i] = 0; - } - - if(std::is_same_v) { - counter[1] = 1; - } - else if(std::is_same_v) { - counter[2] = 1; - } + int raw_counter_position = (Engine::word_count - overflow_position - 2) % Engine::word_count; + std::cout << "Testing discard overflow for position " << raw_counter_position << std::endl; + counter[raw_counter_position] = 1; - engine1.set_counter(counter); + engine1.set_counter(counter); - Engine engine2; + Engine engine2; - for(int i = 0; i < Engine::word_count; i++) { - engine2(); - } - for(int i = 0; i < Engine::word_count; i++) { - engine2.discard(std::numeric_limits::max()); - } + std::array counter2 = {0}; + for (int i = Engine::word_count - overflow_position - 1; i < Engine::word_count - 1; i++) { + counter2[i] = std::numeric_limits::max(); + } - if(engine1() == engine2()) { - std::cout << __PRETTY_FUNCTION__ << " passed" << std::endl; - } else { - std::cout << __PRETTY_FUNCTION__ << " failed" << std::endl; + engine2.set_counter(counter2); + + for (int i = 0; i < Engine::word_count; i++) { + engine2(); + } + + for (int i = 0; i < Engine::word_count; i++) { + engine2.discard(engine2.max()); + } + + if (engine1() == engine2()) { + std::cout << __PRETTY_FUNCTION__ << " passed for overflow_position " << overflow_position << std::endl; + } + else { + std::cout << __PRETTY_FUNCTION__ << " failed for overflow_position " << overflow_position << std::endl; + break; + } } } From c6b84ec218c6daf4420a14052863814f59b55936 Mon Sep 17 00:00:00 2001 From: Elizarova Alina Date: Thu, 20 Mar 2025 08:33:18 -0700 Subject: [PATCH 11/13] generic skip_ahead test --- rng/philox/test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rng/philox/test.cpp b/rng/philox/test.cpp index dd3c17f..9685fcf 100644 --- a/rng/philox/test.cpp +++ b/rng/philox/test.cpp @@ -169,7 +169,8 @@ void skip_test() { using T = typename Engine::result_type; for(T i = 1; i <= Engine::word_count + 1; i++) { Engine engine1; - std::array counter = {0, 0, 0, i / Engine::word_count}; + std::array counter = {0}; + counter[Engine::word_count - 1] = i / Engine::word_count; engine1.set_counter(counter); for(T j = 0; j < i % Engine::word_count; j++) { engine1(); From c93f4451b78c6f1d272f823d045206b4a0db9bbf Mon Sep 17 00:00:00 2001 From: Elizarova Alina Date: Thu, 20 Mar 2025 09:31:27 -0700 Subject: [PATCH 12/13] extend tests and do some fixes --- rng/philox/philox.hpp | 8 ++++---- rng/philox/test.cpp | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index fb62afb..c58badd 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -156,7 +156,7 @@ struct philox_engine void set_counter(const array& counter) { for (std::size_t j = 0; j < n; ++j) { - x[n - j - 1] = counter[j] & result_mask; + x[n - j - 1] = counter[j] & counter_mask; } } @@ -232,8 +232,8 @@ struct philox_engine using counter_type = std::tuple_element_t; using promotion_type = std::tuple_element_t; - static constexpr counter_type counter_mask = ~counter_type(0) >> (sizeof(counter_type) * CHAR_BIT - w); - static constexpr result_type result_mask = ~result_type(0) >> (sizeof(result_type) * CHAR_BIT - w); + static constexpr counter_type counter_mask = static_cast(~counter_type(0)) >> (std::numeric_limits::digits - w); + static constexpr result_type result_mask = static_cast(~result_type(0)) >> (std::numeric_limits::digits - w); private: // functions @@ -334,7 +334,7 @@ operator<<(std::basic_ostream& os, const philox_engine; +using philox2x32_w30 = std::philox_engine; +using philox2x64_w15 = std::philox_engine; +using philox2x64_w49 = std::philox_engine; + // Test the conformance of the implementation with the ISO C++ standard template void conformance_test() { @@ -254,26 +259,50 @@ int main() { conformance_test(); conformance_test(); + set_counter_conformance_test(); + set_counter_conformance_test(); + api_test(); api_test(); + api_test(); + api_test(); + api_test(); + api_test(); seed_test(); seed_test(); + seed_test(); + seed_test(); + seed_test(); + seed_test(); discard_test(); discard_test(); - - set_counter_conformance_test(); - set_counter_conformance_test(); + discard_test(); + discard_test(); + discard_test(); + discard_test(); skip_test(); skip_test(); + skip_test(); + skip_test(); + skip_test(); + skip_test(); counter_overflow_test(); counter_overflow_test(); + counter_overflow_test(); + counter_overflow_test(); + counter_overflow_test(); + counter_overflow_test(); discard_overflow_test(); discard_overflow_test(); + discard_overflow_test(); + discard_overflow_test(); + discard_overflow_test(); + discard_overflow_test(); return 0; } From 65a34c6f41395f84c234a72c6a48ab77aba6eeeb Mon Sep 17 00:00:00 2001 From: Elizarova Alina Date: Thu, 20 Mar 2025 10:03:19 -0700 Subject: [PATCH 13/13] return result_mask to set_counter --- rng/philox/philox.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rng/philox/philox.hpp b/rng/philox/philox.hpp index c58badd..01cfcae 100644 --- a/rng/philox/philox.hpp +++ b/rng/philox/philox.hpp @@ -156,7 +156,7 @@ struct philox_engine void set_counter(const array& counter) { for (std::size_t j = 0; j < n; ++j) { - x[n - j - 1] = counter[j] & counter_mask; + x[n - j - 1] = counter[j] & result_mask; } }