diff options
Diffstat (limited to 'third_party/abseil_cpp/absl/random/internal')
60 files changed, 0 insertions, 13333 deletions
diff --git a/third_party/abseil_cpp/absl/random/internal/BUILD.bazel b/third_party/abseil_cpp/absl/random/internal/BUILD.bazel deleted file mode 100644 index 8485e28b010b..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/BUILD.bazel +++ /dev/null @@ -1,730 +0,0 @@ -# -# Copyright 2019 The Abseil Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") - -# Internal-only implementation classes for Abseil Random -load( - "//absl:copts/configure_copts.bzl", - "ABSL_DEFAULT_COPTS", - "ABSL_DEFAULT_LINKOPTS", - "ABSL_RANDOM_RANDEN_COPTS", - "ABSL_TEST_COPTS", - "absl_random_randen_copts_init", -) - -package(default_visibility = [ - "//absl/random:__pkg__", -]) - -licenses(["notice"]) - -cc_library( - name = "traits", - hdrs = ["traits.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = ["//absl/base:config"], -) - -cc_library( - name = "distribution_caller", - hdrs = ["distribution_caller.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - "//absl/base:config", - "//absl/base:fast_type_id", - "//absl/utility", - ], -) - -cc_library( - name = "fast_uniform_bits", - hdrs = [ - "fast_uniform_bits.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - "//absl/base:config", - "//absl/meta:type_traits", - ], -) - -cc_library( - name = "seed_material", - srcs = [ - "seed_material.cc", - ], - hdrs = [ - "seed_material.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS + select({ - "//absl:windows": ["-DEFAULTLIB:bcrypt.lib"], - "//conditions:default": [], - }), - deps = [ - ":fast_uniform_bits", - "//absl/base:core_headers", - "//absl/base:raw_logging_internal", - "//absl/strings", - "//absl/types:optional", - "//absl/types:span", - ], -) - -cc_library( - name = "pool_urbg", - srcs = [ - "pool_urbg.cc", - ], - hdrs = [ - "pool_urbg.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = select({ - "//absl:windows": [], - "//absl:wasm": [], - "//conditions:default": ["-pthread"], - }) + ABSL_DEFAULT_LINKOPTS, - deps = [ - ":randen", - ":seed_material", - ":traits", - "//absl/base", - "//absl/base:config", - "//absl/base:core_headers", - "//absl/base:endian", - "//absl/base:raw_logging_internal", - "//absl/random:seed_gen_exception", - "//absl/types:span", - ], -) - -cc_library( - name = "explicit_seed_seq", - testonly = 1, - hdrs = [ - "explicit_seed_seq.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = ["//absl/base:config"], -) - -cc_library( - name = "sequence_urbg", - testonly = 1, - hdrs = [ - "sequence_urbg.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = ["//absl/base:config"], -) - -cc_library( - name = "salted_seed_seq", - hdrs = [ - "salted_seed_seq.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":seed_material", - "//absl/container:inlined_vector", - "//absl/meta:type_traits", - "//absl/types:optional", - "//absl/types:span", - ], -) - -cc_library( - name = "iostream_state_saver", - hdrs = ["iostream_state_saver.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - "//absl/meta:type_traits", - "//absl/numeric:int128", - ], -) - -cc_library( - name = "generate_real", - hdrs = [ - "generate_real.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":fastmath", - ":traits", - "//absl/base:bits", - "//absl/meta:type_traits", - ], -) - -cc_library( - name = "fastmath", - hdrs = [ - "fastmath.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = ["//absl/base:bits"], -) - -cc_library( - name = "wide_multiply", - hdrs = ["wide_multiply.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":traits", - "//absl/base:bits", - "//absl/base:config", - "//absl/numeric:int128", - ], -) - -cc_library( - name = "nonsecure_base", - hdrs = ["nonsecure_base.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":pool_urbg", - ":salted_seed_seq", - ":seed_material", - "//absl/base:core_headers", - "//absl/meta:type_traits", - "//absl/types:optional", - "//absl/types:span", - ], -) - -cc_library( - name = "pcg_engine", - hdrs = ["pcg_engine.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":fastmath", - ":iostream_state_saver", - "//absl/base:config", - "//absl/meta:type_traits", - "//absl/numeric:int128", - ], -) - -cc_library( - name = "randen_engine", - hdrs = ["randen_engine.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":iostream_state_saver", - ":randen", - "//absl/meta:type_traits", - ], -) - -cc_library( - name = "platform", - srcs = [ - "randen_round_keys.cc", - ], - hdrs = [ - "randen_traits.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - textual_hdrs = [ - "platform.h", - ], - deps = ["//absl/base:config"], -) - -cc_library( - name = "randen", - srcs = [ - "randen.cc", - ], - hdrs = [ - "randen.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":platform", - ":randen_hwaes", - ":randen_slow", - "//absl/base:raw_logging_internal", - ], -) - -cc_library( - name = "randen_slow", - srcs = ["randen_slow.cc"], - hdrs = ["randen_slow.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":platform", - "//absl/base:config", - "//absl/base:core_headers", - ], -) - -absl_random_randen_copts_init() - -cc_library( - name = "randen_hwaes", - srcs = [ - "randen_detect.cc", - ], - hdrs = [ - "randen_detect.h", - "randen_hwaes.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":platform", - ":randen_hwaes_impl", - "//absl/base:config", - ], -) - -# build with --save_temps to see assembly language output. -cc_library( - name = "randen_hwaes_impl", - srcs = [ - "randen_hwaes.cc", - "randen_hwaes.h", - ], - copts = ABSL_DEFAULT_COPTS + ABSL_RANDOM_RANDEN_COPTS + select({ - "//absl:windows": [], - "//conditions:default": ["-Wno-pass-failed"], - }), - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":platform", - "//absl/base:config", - "//absl/base:core_headers", - ], -) - -cc_binary( - name = "gaussian_distribution_gentables", - srcs = [ - "gaussian_distribution_gentables.cc", - ], - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - "//absl/base:core_headers", - "//absl/random:distributions", - ], -) - -cc_library( - name = "distribution_test_util", - testonly = 1, - srcs = [ - "chi_square.cc", - "distribution_test_util.cc", - ], - hdrs = [ - "chi_square.h", - "distribution_test_util.h", - ], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - "//absl/base:config", - "//absl/base:core_headers", - "//absl/base:raw_logging_internal", - "//absl/strings", - "//absl/strings:str_format", - "//absl/types:span", - ], -) - -# Common tags for tests, etc. -ABSL_RANDOM_NONPORTABLE_TAGS = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - "no_test_darwin_x86_64", - "no_test_ios_x86_64", - "no_test_loonix", - "no_test_msvc_x64", - "no_test_wasm", -] - -cc_test( - name = "traits_test", - size = "small", - srcs = ["traits_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":traits", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "generate_real_test", - size = "small", - srcs = [ - "generate_real_test.cc", - ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":generate_real", - "//absl/base:bits", - "//absl/flags:flag", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "distribution_test_util_test", - size = "small", - srcs = ["distribution_test_util_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":distribution_test_util", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fastmath_test", - size = "small", - srcs = ["fastmath_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":fastmath", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "explicit_seed_seq_test", - size = "small", - srcs = ["explicit_seed_seq_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":explicit_seed_seq", - "//absl/random:seed_sequences", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "salted_seed_seq_test", - size = "small", - srcs = ["salted_seed_seq_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":salted_seed_seq", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "chi_square_test", - size = "small", - srcs = [ - "chi_square_test.cc", - ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":distribution_test_util", - "//absl/base:core_headers", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "fast_uniform_bits_test", - size = "small", - srcs = [ - "fast_uniform_bits_test.cc", - ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":fast_uniform_bits", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "mock_helpers", - hdrs = ["mock_helpers.h"], - deps = [ - "//absl/base:fast_type_id", - "//absl/types:optional", - ], -) - -cc_library( - name = "mock_overload_set", - testonly = 1, - hdrs = ["mock_overload_set.h"], - deps = [ - ":mock_helpers", - "//absl/random:mocking_bit_gen", - "@com_google_googletest//:gtest", - ], -) - -cc_test( - name = "nonsecure_base_test", - size = "small", - srcs = [ - "nonsecure_base_test.cc", - ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":nonsecure_base", - "//absl/random", - "//absl/random:distributions", - "//absl/random:seed_sequences", - "//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "seed_material_test", - size = "small", - srcs = ["seed_material_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":seed_material", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "pool_urbg_test", - size = "small", - srcs = [ - "pool_urbg_test.cc", - ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":pool_urbg", - "//absl/meta:type_traits", - "//absl/types:span", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "pcg_engine_test", - size = "medium", # Trying to measure accuracy. - srcs = ["pcg_engine_test.cc"], - copts = ABSL_TEST_COPTS, - flaky = 1, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":explicit_seed_seq", - ":pcg_engine", - "//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "randen_engine_test", - size = "medium", - srcs = [ - "randen_engine_test.cc", - ], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":explicit_seed_seq", - ":randen_engine", - "//absl/base:raw_logging_internal", - "//absl/strings", - "//absl/time", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "randen_test", - size = "small", - srcs = ["randen_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":randen", - "//absl/meta:type_traits", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "randen_slow_test", - size = "small", - srcs = ["randen_slow_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":platform", - ":randen_slow", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "randen_hwaes_test", - size = "small", - srcs = ["randen_hwaes_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - tags = ABSL_RANDOM_NONPORTABLE_TAGS, - deps = [ - ":platform", - ":randen_hwaes", - ":randen_hwaes_impl", # build_cleaner: keep - "//absl/base:raw_logging_internal", - "//absl/strings:str_format", - "@com_google_googletest//:gtest", - ], -) - -cc_test( - name = "wide_multiply_test", - size = "small", - srcs = ["wide_multiply_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":wide_multiply", - "//absl/base:bits", - "//absl/numeric:int128", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "nanobenchmark", - srcs = ["nanobenchmark.cc"], - linkopts = ABSL_DEFAULT_LINKOPTS, - textual_hdrs = ["nanobenchmark.h"], - deps = [ - ":platform", - ":randen_engine", - "//absl/base:config", - "//absl/base:core_headers", - "//absl/base:raw_logging_internal", - ], -) - -cc_library( - name = "uniform_helper", - hdrs = ["uniform_helper.h"], - copts = ABSL_DEFAULT_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":traits", - "//absl/base:config", - "//absl/meta:type_traits", - ], -) - -cc_test( - name = "nanobenchmark_test", - size = "small", - srcs = ["nanobenchmark_test.cc"], - flaky = 1, - linkopts = ABSL_DEFAULT_LINKOPTS, - tags = [ - "benchmark", - "no_test_ios_x86_64", - "no_test_loonix", # Crashing. - ], - deps = [ - ":nanobenchmark", - "//absl/base:raw_logging_internal", - "//absl/strings", - ], -) - -cc_test( - name = "randen_benchmarks", - size = "medium", - timeout = "long", - srcs = ["randen_benchmarks.cc"], - copts = ABSL_TEST_COPTS + ABSL_RANDOM_RANDEN_COPTS, - flaky = 1, - linkopts = ABSL_DEFAULT_LINKOPTS, - tags = ABSL_RANDOM_NONPORTABLE_TAGS + ["benchmark"], - deps = [ - ":nanobenchmark", - ":platform", - ":randen", - ":randen_engine", - ":randen_hwaes", - ":randen_hwaes_impl", - ":randen_slow", - "//absl/base:raw_logging_internal", - "//absl/strings", - ], -) - -cc_test( - name = "iostream_state_saver_test", - size = "small", - srcs = ["iostream_state_saver_test.cc"], - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":iostream_state_saver", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "uniform_helper_test", - size = "small", - srcs = ["uniform_helper_test.cc"], - copts = ABSL_TEST_COPTS, - linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [ - ":uniform_helper", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/third_party/abseil_cpp/absl/random/internal/chi_square.cc b/third_party/abseil_cpp/absl/random/internal/chi_square.cc deleted file mode 100644 index 640d48cea6f4..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/chi_square.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/chi_square.h" - -#include <cmath> - -#include "absl/random/internal/distribution_test_util.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -#if defined(__EMSCRIPTEN__) -// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found. -inline double fma(double x, double y, double z) { - return (x * y) + z; -} -#endif - -// Use Horner's method to evaluate a polynomial. -template <typename T, unsigned N> -inline T EvaluatePolynomial(T x, const T (&poly)[N]) { -#if !defined(__EMSCRIPTEN__) - using std::fma; -#endif - T p = poly[N - 1]; - for (unsigned i = 2; i <= N; i++) { - p = fma(p, x, poly[N - i]); - } - return p; -} - -static constexpr int kLargeDOF = 150; - -// Returns the probability of a normal z-value. -// -// Adapted from the POZ function in: -// Ibbetson D, Algorithm 209 -// Collected Algorithms of the CACM 1963 p. 616 -// -double POZ(double z) { - static constexpr double kP1[] = { - 0.797884560593, -0.531923007300, 0.319152932694, - -0.151968751364, 0.059054035642, -0.019198292004, - 0.005198775019, -0.001075204047, 0.000124818987, - }; - static constexpr double kP2[] = { - 0.999936657524, 0.000535310849, -0.002141268741, 0.005353579108, - -0.009279453341, 0.011630447319, -0.010557625006, 0.006549791214, - -0.002034254874, -0.000794620820, 0.001390604284, -0.000676904986, - -0.000019538132, 0.000152529290, -0.000045255659, - }; - - const double kZMax = 6.0; // Maximum meaningful z-value. - if (z == 0.0) { - return 0.5; - } - double x; - double y = 0.5 * std::fabs(z); - if (y >= (kZMax * 0.5)) { - x = 1.0; - } else if (y < 1.0) { - double w = y * y; - x = EvaluatePolynomial(w, kP1) * y * 2.0; - } else { - y -= 2.0; - x = EvaluatePolynomial(y, kP2); - } - return z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5); -} - -// Approximates the survival function of the normal distribution. -// -// Algorithm 26.2.18, from: -// [Abramowitz and Stegun, Handbook of Mathematical Functions,p.932] -// http://people.math.sfu.ca/~cbm/aands/abramowitz_and_stegun.pdf -// -double normal_survival(double z) { - // Maybe replace with the alternate formulation. - // 0.5 * erfc((x - mean)/(sqrt(2) * sigma)) - static constexpr double kR[] = { - 1.0, 0.196854, 0.115194, 0.000344, 0.019527, - }; - double r = EvaluatePolynomial(z, kR); - r *= r; - return 0.5 / (r * r); -} - -} // namespace - -// Calculates the critical chi-square value given degrees-of-freedom and a -// p-value, usually using bisection. Also known by the name CRITCHI. -double ChiSquareValue(int dof, double p) { - static constexpr double kChiEpsilon = - 0.000001; // Accuracy of the approximation. - static constexpr double kChiMax = - 99999.0; // Maximum chi-squared value. - - const double p_value = 1.0 - p; - if (dof < 1 || p_value > 1.0) { - return 0.0; - } - - if (dof > kLargeDOF) { - // For large degrees of freedom, use the normal approximation by - // Wilson, E. B. and Hilferty, M. M. (1931) - // chi^2 - mean - // Z = -------------- - // stddev - const double z = InverseNormalSurvival(p_value); - const double mean = 1 - 2.0 / (9 * dof); - const double variance = 2.0 / (9 * dof); - // Cannot use this method if the variance is 0. - if (variance != 0) { - return std::pow(z * std::sqrt(variance) + mean, 3.0) * dof; - } - } - - if (p_value <= 0.0) return kChiMax; - - // Otherwise search for the p value by bisection - double min_chisq = 0.0; - double max_chisq = kChiMax; - double current = dof / std::sqrt(p_value); - while ((max_chisq - min_chisq) > kChiEpsilon) { - if (ChiSquarePValue(current, dof) < p_value) { - max_chisq = current; - } else { - min_chisq = current; - } - current = (max_chisq + min_chisq) * 0.5; - } - return current; -} - -// Calculates the p-value (probability) of a given chi-square value -// and degrees of freedom. -// -// Adapted from the POCHISQ function from: -// Hill, I. D. and Pike, M. C. Algorithm 299 -// Collected Algorithms of the CACM 1963 p. 243 -// -double ChiSquarePValue(double chi_square, int dof) { - static constexpr double kLogSqrtPi = - 0.5723649429247000870717135; // Log[Sqrt[Pi]] - static constexpr double kInverseSqrtPi = - 0.5641895835477562869480795; // 1/(Sqrt[Pi]) - - // For large degrees of freedom, use the normal approximation by - // Wilson, E. B. and Hilferty, M. M. (1931) - // Via Wikipedia: - // By the Central Limit Theorem, because the chi-square distribution is the - // sum of k independent random variables with finite mean and variance, it - // converges to a normal distribution for large k. - if (dof > kLargeDOF) { - // Re-scale everything. - const double chi_square_scaled = std::pow(chi_square / dof, 1.0 / 3); - const double mean = 1 - 2.0 / (9 * dof); - const double variance = 2.0 / (9 * dof); - // If variance is 0, this method cannot be used. - if (variance != 0) { - const double z = (chi_square_scaled - mean) / std::sqrt(variance); - if (z > 0) { - return normal_survival(z); - } else if (z < 0) { - return 1.0 - normal_survival(-z); - } else { - return 0.5; - } - } - } - - // The chi square function is >= 0 for any degrees of freedom. - // In other words, probability that the chi square function >= 0 is 1. - if (chi_square <= 0.0) return 1.0; - - // If the degrees of freedom is zero, the chi square function is always 0 by - // definition. In other words, the probability that the chi square function - // is > 0 is zero (chi square values <= 0 have been filtered above). - if (dof < 1) return 0; - - auto capped_exp = [](double x) { return x < -20 ? 0.0 : std::exp(x); }; - static constexpr double kBigX = 20; - - double a = 0.5 * chi_square; - const bool even = !(dof & 1); // True if dof is an even number. - const double y = capped_exp(-a); - double s = even ? y : (2.0 * POZ(-std::sqrt(chi_square))); - - if (dof <= 2) { - return s; - } - - chi_square = 0.5 * (dof - 1.0); - double z = (even ? 1.0 : 0.5); - if (a > kBigX) { - double e = (even ? 0.0 : kLogSqrtPi); - double c = std::log(a); - while (z <= chi_square) { - e = std::log(z) + e; - s += capped_exp(c * z - a - e); - z += 1.0; - } - return s; - } - - double e = (even ? 1.0 : (kInverseSqrtPi / std::sqrt(a))); - double c = 0.0; - while (z <= chi_square) { - e = e * (a / z); - c = c + e; - z += 1.0; - } - return c * y + s; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/chi_square.h b/third_party/abseil_cpp/absl/random/internal/chi_square.h deleted file mode 100644 index 07f4fbe52298..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/chi_square.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_ -#define ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_ - -// The chi-square statistic. -// -// Useful for evaluating if `D` independent random variables are behaving as -// expected, or if two distributions are similar. (`D` is the degrees of -// freedom). -// -// Each bucket should have an expected count of 10 or more for the chi square to -// be meaningful. - -#include <cassert> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -constexpr const char kChiSquared[] = "chi-squared"; - -// Returns the measured chi square value, using a single expected value. This -// assumes that the values in [begin, end) are uniformly distributed. -template <typename Iterator> -double ChiSquareWithExpected(Iterator begin, Iterator end, double expected) { - // Compute the sum and the number of buckets. - assert(expected >= 10); // require at least 10 samples per bucket. - double chi_square = 0; - for (auto it = begin; it != end; it++) { - double d = static_cast<double>(*it) - expected; - chi_square += d * d; - } - chi_square = chi_square / expected; - return chi_square; -} - -// Returns the measured chi square value, taking the actual value of each bucket -// from the first set of iterators, and the expected value of each bucket from -// the second set of iterators. -template <typename Iterator, typename Expected> -double ChiSquare(Iterator it, Iterator end, Expected eit, Expected eend) { - double chi_square = 0; - for (; it != end && eit != eend; ++it, ++eit) { - if (*it > 0) { - assert(*eit > 0); - } - double e = static_cast<double>(*eit); - double d = static_cast<double>(*it - *eit); - if (d != 0) { - assert(e > 0); - chi_square += (d * d) / e; - } - } - assert(it == end && eit == eend); - return chi_square; -} - -// ====================================================================== -// The following methods can be used for an arbitrary significance level. -// - -// Calculates critical chi-square values to produce the given p-value using a -// bisection search for a value within epsilon, relying on the monotonicity of -// ChiSquarePValue(). -double ChiSquareValue(int dof, double p); - -// Calculates the p-value (probability) of a given chi-square value. -double ChiSquarePValue(double chi_square, int dof); - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/chi_square_test.cc b/third_party/abseil_cpp/absl/random/internal/chi_square_test.cc deleted file mode 100644 index 5025defac12c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/chi_square_test.cc +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/chi_square.h" - -#include <algorithm> -#include <cstddef> -#include <cstdint> -#include <iterator> -#include <numeric> -#include <vector> - -#include "gtest/gtest.h" -#include "absl/base/macros.h" - -using absl::random_internal::ChiSquare; -using absl::random_internal::ChiSquarePValue; -using absl::random_internal::ChiSquareValue; -using absl::random_internal::ChiSquareWithExpected; - -namespace { - -TEST(ChiSquare, Value) { - struct { - int line; - double chi_square; - int df; - double confidence; - } const specs[] = { - // Testing lookup at 1% confidence - {__LINE__, 0, 0, 0.01}, - {__LINE__, 0.00016, 1, 0.01}, - {__LINE__, 1.64650, 8, 0.01}, - {__LINE__, 5.81221, 16, 0.01}, - {__LINE__, 156.4319, 200, 0.01}, - {__LINE__, 1121.3784, 1234, 0.01}, - {__LINE__, 53557.1629, 54321, 0.01}, - {__LINE__, 651662.6647, 654321, 0.01}, - - // Testing lookup at 99% confidence - {__LINE__, 0, 0, 0.99}, - {__LINE__, 6.635, 1, 0.99}, - {__LINE__, 20.090, 8, 0.99}, - {__LINE__, 32.000, 16, 0.99}, - {__LINE__, 249.4456, 200, 0.99}, - {__LINE__, 1131.1573, 1023, 0.99}, - {__LINE__, 1352.5038, 1234, 0.99}, - {__LINE__, 55090.7356, 54321, 0.99}, - {__LINE__, 656985.1514, 654321, 0.99}, - - // Testing lookup at 99.9% confidence - {__LINE__, 16.2659, 3, 0.999}, - {__LINE__, 22.4580, 6, 0.999}, - {__LINE__, 267.5409, 200, 0.999}, - {__LINE__, 1168.5033, 1023, 0.999}, - {__LINE__, 55345.1741, 54321, 0.999}, - {__LINE__, 657861.7284, 654321, 0.999}, - {__LINE__, 51.1772, 24, 0.999}, - {__LINE__, 59.7003, 30, 0.999}, - {__LINE__, 37.6984, 15, 0.999}, - {__LINE__, 29.5898, 10, 0.999}, - {__LINE__, 27.8776, 9, 0.999}, - - // Testing lookup at random confidences - {__LINE__, 0.000157088, 1, 0.01}, - {__LINE__, 5.31852, 2, 0.93}, - {__LINE__, 1.92256, 4, 0.25}, - {__LINE__, 10.7709, 13, 0.37}, - {__LINE__, 26.2514, 17, 0.93}, - {__LINE__, 36.4799, 29, 0.84}, - {__LINE__, 25.818, 31, 0.27}, - {__LINE__, 63.3346, 64, 0.50}, - {__LINE__, 196.211, 128, 0.9999}, - {__LINE__, 215.21, 243, 0.10}, - {__LINE__, 285.393, 256, 0.90}, - {__LINE__, 984.504, 1024, 0.1923}, - {__LINE__, 2043.85, 2048, 0.4783}, - {__LINE__, 48004.6, 48273, 0.194}, - }; - for (const auto& spec : specs) { - SCOPED_TRACE(spec.line); - // Verify all values are have at most a 1% relative error. - const double val = ChiSquareValue(spec.df, spec.confidence); - const double err = std::max(5e-6, spec.chi_square / 5e3); // 1 part in 5000 - EXPECT_NEAR(spec.chi_square, val, err) << spec.line; - } - - // Relaxed test for extreme values, from - // http://www.ciphersbyritter.com/JAVASCRP/NORMCHIK.HTM#ChiSquare - EXPECT_NEAR(49.2680, ChiSquareValue(100, 1e-6), 5); // 0.000'005 mark - EXPECT_NEAR(123.499, ChiSquareValue(200, 1e-6), 5); // 0.000'005 mark - - EXPECT_NEAR(149.449, ChiSquareValue(100, 0.999), 0.01); - EXPECT_NEAR(161.318, ChiSquareValue(100, 0.9999), 0.01); - EXPECT_NEAR(172.098, ChiSquareValue(100, 0.99999), 0.01); - - EXPECT_NEAR(381.426, ChiSquareValue(300, 0.999), 0.05); - EXPECT_NEAR(399.756, ChiSquareValue(300, 0.9999), 0.1); - EXPECT_NEAR(416.126, ChiSquareValue(300, 0.99999), 0.2); -} - -TEST(ChiSquareTest, PValue) { - struct { - int line; - double pval; - double chi_square; - int df; - } static const specs[] = { - {__LINE__, 1, 0, 0}, - {__LINE__, 0, 0.001, 0}, - {__LINE__, 1.000, 0, 453}, - {__LINE__, 0.134471, 7972.52, 7834}, - {__LINE__, 0.203922, 28.32, 23}, - {__LINE__, 0.737171, 48274, 48472}, - {__LINE__, 0.444146, 583.1234, 579}, - {__LINE__, 0.294814, 138.2, 130}, - {__LINE__, 0.0816532, 12.63, 7}, - {__LINE__, 0, 682.32, 67}, - {__LINE__, 0.49405, 999, 999}, - {__LINE__, 1.000, 0, 9999}, - {__LINE__, 0.997477, 0.00001, 1}, - {__LINE__, 0, 5823.21, 5040}, - }; - for (const auto& spec : specs) { - SCOPED_TRACE(spec.line); - const double pval = ChiSquarePValue(spec.chi_square, spec.df); - EXPECT_NEAR(spec.pval, pval, 1e-3); - } -} - -TEST(ChiSquareTest, CalcChiSquare) { - struct { - int line; - std::vector<int> expected; - std::vector<int> actual; - } const specs[] = { - {__LINE__, - {56, 234, 76, 1, 546, 1, 87, 345, 1, 234}, - {2, 132, 4, 43, 234, 8, 345, 8, 236, 56}}, - {__LINE__, - {123, 36, 234, 367, 345, 2, 456, 567, 234, 567}, - {123, 56, 2345, 8, 345, 8, 2345, 23, 48, 267}}, - {__LINE__, - {123, 234, 345, 456, 567, 678, 789, 890, 98, 76}, - {123, 234, 345, 456, 567, 678, 789, 890, 98, 76}}, - {__LINE__, {3, 675, 23, 86, 2, 8, 2}, {456, 675, 23, 86, 23, 65, 2}}, - {__LINE__, {1}, {23}}, - }; - for (const auto& spec : specs) { - SCOPED_TRACE(spec.line); - double chi_square = 0; - for (int i = 0; i < spec.expected.size(); ++i) { - const double diff = spec.actual[i] - spec.expected[i]; - chi_square += (diff * diff) / spec.expected[i]; - } - EXPECT_NEAR(chi_square, - ChiSquare(std::begin(spec.actual), std::end(spec.actual), - std::begin(spec.expected), std::end(spec.expected)), - 1e-5); - } -} - -TEST(ChiSquareTest, CalcChiSquareInt64) { - const int64_t data[3] = {910293487, 910292491, 910216780}; - // $ python -c "import scipy.stats - // > print scipy.stats.chisquare([910293487, 910292491, 910216780])[0]" - // 4.25410123524 - double sum = std::accumulate(std::begin(data), std::end(data), double{0}); - size_t n = std::distance(std::begin(data), std::end(data)); - double a = ChiSquareWithExpected(std::begin(data), std::end(data), sum / n); - EXPECT_NEAR(4.254101, a, 1e-6); - - // ... Or with known values. - double b = - ChiSquareWithExpected(std::begin(data), std::end(data), 910267586.0); - EXPECT_NEAR(4.254101, b, 1e-6); -} - -TEST(ChiSquareTest, TableData) { - // Test data from - // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3674.htm - // 0.90 0.95 0.975 0.99 0.999 - const double data[100][5] = { - /* 1*/ {2.706, 3.841, 5.024, 6.635, 10.828}, - /* 2*/ {4.605, 5.991, 7.378, 9.210, 13.816}, - /* 3*/ {6.251, 7.815, 9.348, 11.345, 16.266}, - /* 4*/ {7.779, 9.488, 11.143, 13.277, 18.467}, - /* 5*/ {9.236, 11.070, 12.833, 15.086, 20.515}, - /* 6*/ {10.645, 12.592, 14.449, 16.812, 22.458}, - /* 7*/ {12.017, 14.067, 16.013, 18.475, 24.322}, - /* 8*/ {13.362, 15.507, 17.535, 20.090, 26.125}, - /* 9*/ {14.684, 16.919, 19.023, 21.666, 27.877}, - /*10*/ {15.987, 18.307, 20.483, 23.209, 29.588}, - /*11*/ {17.275, 19.675, 21.920, 24.725, 31.264}, - /*12*/ {18.549, 21.026, 23.337, 26.217, 32.910}, - /*13*/ {19.812, 22.362, 24.736, 27.688, 34.528}, - /*14*/ {21.064, 23.685, 26.119, 29.141, 36.123}, - /*15*/ {22.307, 24.996, 27.488, 30.578, 37.697}, - /*16*/ {23.542, 26.296, 28.845, 32.000, 39.252}, - /*17*/ {24.769, 27.587, 30.191, 33.409, 40.790}, - /*18*/ {25.989, 28.869, 31.526, 34.805, 42.312}, - /*19*/ {27.204, 30.144, 32.852, 36.191, 43.820}, - /*20*/ {28.412, 31.410, 34.170, 37.566, 45.315}, - /*21*/ {29.615, 32.671, 35.479, 38.932, 46.797}, - /*22*/ {30.813, 33.924, 36.781, 40.289, 48.268}, - /*23*/ {32.007, 35.172, 38.076, 41.638, 49.728}, - /*24*/ {33.196, 36.415, 39.364, 42.980, 51.179}, - /*25*/ {34.382, 37.652, 40.646, 44.314, 52.620}, - /*26*/ {35.563, 38.885, 41.923, 45.642, 54.052}, - /*27*/ {36.741, 40.113, 43.195, 46.963, 55.476}, - /*28*/ {37.916, 41.337, 44.461, 48.278, 56.892}, - /*29*/ {39.087, 42.557, 45.722, 49.588, 58.301}, - /*30*/ {40.256, 43.773, 46.979, 50.892, 59.703}, - /*31*/ {41.422, 44.985, 48.232, 52.191, 61.098}, - /*32*/ {42.585, 46.194, 49.480, 53.486, 62.487}, - /*33*/ {43.745, 47.400, 50.725, 54.776, 63.870}, - /*34*/ {44.903, 48.602, 51.966, 56.061, 65.247}, - /*35*/ {46.059, 49.802, 53.203, 57.342, 66.619}, - /*36*/ {47.212, 50.998, 54.437, 58.619, 67.985}, - /*37*/ {48.363, 52.192, 55.668, 59.893, 69.347}, - /*38*/ {49.513, 53.384, 56.896, 61.162, 70.703}, - /*39*/ {50.660, 54.572, 58.120, 62.428, 72.055}, - /*40*/ {51.805, 55.758, 59.342, 63.691, 73.402}, - /*41*/ {52.949, 56.942, 60.561, 64.950, 74.745}, - /*42*/ {54.090, 58.124, 61.777, 66.206, 76.084}, - /*43*/ {55.230, 59.304, 62.990, 67.459, 77.419}, - /*44*/ {56.369, 60.481, 64.201, 68.710, 78.750}, - /*45*/ {57.505, 61.656, 65.410, 69.957, 80.077}, - /*46*/ {58.641, 62.830, 66.617, 71.201, 81.400}, - /*47*/ {59.774, 64.001, 67.821, 72.443, 82.720}, - /*48*/ {60.907, 65.171, 69.023, 73.683, 84.037}, - /*49*/ {62.038, 66.339, 70.222, 74.919, 85.351}, - /*50*/ {63.167, 67.505, 71.420, 76.154, 86.661}, - /*51*/ {64.295, 68.669, 72.616, 77.386, 87.968}, - /*52*/ {65.422, 69.832, 73.810, 78.616, 89.272}, - /*53*/ {66.548, 70.993, 75.002, 79.843, 90.573}, - /*54*/ {67.673, 72.153, 76.192, 81.069, 91.872}, - /*55*/ {68.796, 73.311, 77.380, 82.292, 93.168}, - /*56*/ {69.919, 74.468, 78.567, 83.513, 94.461}, - /*57*/ {71.040, 75.624, 79.752, 84.733, 95.751}, - /*58*/ {72.160, 76.778, 80.936, 85.950, 97.039}, - /*59*/ {73.279, 77.931, 82.117, 87.166, 98.324}, - /*60*/ {74.397, 79.082, 83.298, 88.379, 99.607}, - /*61*/ {75.514, 80.232, 84.476, 89.591, 100.888}, - /*62*/ {76.630, 81.381, 85.654, 90.802, 102.166}, - /*63*/ {77.745, 82.529, 86.830, 92.010, 103.442}, - /*64*/ {78.860, 83.675, 88.004, 93.217, 104.716}, - /*65*/ {79.973, 84.821, 89.177, 94.422, 105.988}, - /*66*/ {81.085, 85.965, 90.349, 95.626, 107.258}, - /*67*/ {82.197, 87.108, 91.519, 96.828, 108.526}, - /*68*/ {83.308, 88.250, 92.689, 98.028, 109.791}, - /*69*/ {84.418, 89.391, 93.856, 99.228, 111.055}, - /*70*/ {85.527, 90.531, 95.023, 100.425, 112.317}, - /*71*/ {86.635, 91.670, 96.189, 101.621, 113.577}, - /*72*/ {87.743, 92.808, 97.353, 102.816, 114.835}, - /*73*/ {88.850, 93.945, 98.516, 104.010, 116.092}, - /*74*/ {89.956, 95.081, 99.678, 105.202, 117.346}, - /*75*/ {91.061, 96.217, 100.839, 106.393, 118.599}, - /*76*/ {92.166, 97.351, 101.999, 107.583, 119.850}, - /*77*/ {93.270, 98.484, 103.158, 108.771, 121.100}, - /*78*/ {94.374, 99.617, 104.316, 109.958, 122.348}, - /*79*/ {95.476, 100.749, 105.473, 111.144, 123.594}, - /*80*/ {96.578, 101.879, 106.629, 112.329, 124.839}, - /*81*/ {97.680, 103.010, 107.783, 113.512, 126.083}, - /*82*/ {98.780, 104.139, 108.937, 114.695, 127.324}, - /*83*/ {99.880, 105.267, 110.090, 115.876, 128.565}, - /*84*/ {100.980, 106.395, 111.242, 117.057, 129.804}, - /*85*/ {102.079, 107.522, 112.393, 118.236, 131.041}, - /*86*/ {103.177, 108.648, 113.544, 119.414, 132.277}, - /*87*/ {104.275, 109.773, 114.693, 120.591, 133.512}, - /*88*/ {105.372, 110.898, 115.841, 121.767, 134.746}, - /*89*/ {106.469, 112.022, 116.989, 122.942, 135.978}, - /*90*/ {107.565, 113.145, 118.136, 124.116, 137.208}, - /*91*/ {108.661, 114.268, 119.282, 125.289, 138.438}, - /*92*/ {109.756, 115.390, 120.427, 126.462, 139.666}, - /*93*/ {110.850, 116.511, 121.571, 127.633, 140.893}, - /*94*/ {111.944, 117.632, 122.715, 128.803, 142.119}, - /*95*/ {113.038, 118.752, 123.858, 129.973, 143.344}, - /*96*/ {114.131, 119.871, 125.000, 131.141, 144.567}, - /*97*/ {115.223, 120.990, 126.141, 132.309, 145.789}, - /*98*/ {116.315, 122.108, 127.282, 133.476, 147.010}, - /*99*/ {117.407, 123.225, 128.422, 134.642, 148.230}, - /*100*/ {118.498, 124.342, 129.561, 135.807, 149.449} - /**/}; - - // 0.90 0.95 0.975 0.99 0.999 - for (int i = 0; i < ABSL_ARRAYSIZE(data); i++) { - const double E = 0.0001; - EXPECT_NEAR(ChiSquarePValue(data[i][0], i + 1), 0.10, E) - << i << " " << data[i][0]; - EXPECT_NEAR(ChiSquarePValue(data[i][1], i + 1), 0.05, E) - << i << " " << data[i][1]; - EXPECT_NEAR(ChiSquarePValue(data[i][2], i + 1), 0.025, E) - << i << " " << data[i][2]; - EXPECT_NEAR(ChiSquarePValue(data[i][3], i + 1), 0.01, E) - << i << " " << data[i][3]; - EXPECT_NEAR(ChiSquarePValue(data[i][4], i + 1), 0.001, E) - << i << " " << data[i][4]; - - const double F = 0.1; - EXPECT_NEAR(ChiSquareValue(i + 1, 0.90), data[i][0], F) << i; - EXPECT_NEAR(ChiSquareValue(i + 1, 0.95), data[i][1], F) << i; - EXPECT_NEAR(ChiSquareValue(i + 1, 0.975), data[i][2], F) << i; - EXPECT_NEAR(ChiSquareValue(i + 1, 0.99), data[i][3], F) << i; - EXPECT_NEAR(ChiSquareValue(i + 1, 0.999), data[i][4], F) << i; - } -} - -TEST(ChiSquareTest, ChiSquareTwoIterator) { - // Test data from http://www.stat.yale.edu/Courses/1997-98/101/chigf.htm - // Null-hypothesis: This data is normally distributed. - const int counts[10] = {6, 6, 18, 33, 38, 38, 28, 21, 9, 3}; - const double expected[10] = {4.6, 8.8, 18.4, 30.0, 38.2, - 38.2, 30.0, 18.4, 8.8, 4.6}; - double chi_square = ChiSquare(std::begin(counts), std::end(counts), - std::begin(expected), std::end(expected)); - EXPECT_NEAR(chi_square, 2.69, 0.001); - - // Degrees of freedom: 10 bins. two estimated parameters. = 10 - 2 - 1. - const int dof = 7; - // The critical value of 7, 95% => 14.067 (see above test) - double p_value_05 = ChiSquarePValue(14.067, dof); - EXPECT_NEAR(p_value_05, 0.05, 0.001); // 95%-ile p-value - - double p_actual = ChiSquarePValue(chi_square, dof); - EXPECT_GT(p_actual, 0.05); // Accept the null hypothesis. -} - -TEST(ChiSquareTest, DiceRolls) { - // Assume we are testing 102 fair dice rolls. - // Null-hypothesis: This data is fairly distributed. - // - // The dof value of 4, @95% = 9.488 (see above test) - // The dof value of 5, @95% = 11.070 - const int rolls[6] = {22, 11, 17, 14, 20, 18}; - double sum = std::accumulate(std::begin(rolls), std::end(rolls), double{0}); - size_t n = std::distance(std::begin(rolls), std::end(rolls)); - - double a = ChiSquareWithExpected(std::begin(rolls), std::end(rolls), sum / n); - EXPECT_NEAR(a, 4.70588, 1e-5); - EXPECT_LT(a, ChiSquareValue(4, 0.95)); - - double p_a = ChiSquarePValue(a, 4); - EXPECT_NEAR(p_a, 0.318828, 1e-5); // Accept the null hypothesis. - - double b = ChiSquareWithExpected(std::begin(rolls), std::end(rolls), 17.0); - EXPECT_NEAR(b, 4.70588, 1e-5); - EXPECT_LT(b, ChiSquareValue(5, 0.95)); - - double p_b = ChiSquarePValue(b, 5); - EXPECT_NEAR(p_b, 0.4528180, 1e-5); // Accept the null hypothesis. -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/distribution_caller.h b/third_party/abseil_cpp/absl/random/internal/distribution_caller.h deleted file mode 100644 index fc81b787ebe2..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/distribution_caller.h +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_ -#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_ - -#include <utility> - -#include "absl/base/config.h" -#include "absl/base/internal/fast_type_id.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// DistributionCaller provides an opportunity to overload the general -// mechanism for calling a distribution, allowing for mock-RNG classes -// to intercept such calls. -template <typename URBG> -struct DistributionCaller { - // SFINAE to detect whether the URBG type includes a member matching - // bool InvokeMock(base_internal::FastTypeIdType, void*, void*). - // - // These live inside BitGenRef so that they have friend access - // to MockingBitGen. (see similar methods in DistributionCaller). - template <template <class...> class Trait, class AlwaysVoid, class... Args> - struct detector : std::false_type {}; - template <template <class...> class Trait, class... Args> - struct detector<Trait, absl::void_t<Trait<Args...>>, Args...> - : std::true_type {}; - - template <class T> - using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( - std::declval<::absl::base_internal::FastTypeIdType>(), - std::declval<void*>(), std::declval<void*>())); - - using HasInvokeMock = typename detector<invoke_mock_t, void, URBG>::type; - - // Default implementation of distribution caller. - template <typename DistrT, typename... Args> - static typename DistrT::result_type Impl(std::false_type, URBG* urbg, - Args&&... args) { - DistrT dist(std::forward<Args>(args)...); - return dist(*urbg); - } - - // Mock implementation of distribution caller. - // The underlying KeyT must match the KeyT constructed by MockOverloadSet. - template <typename DistrT, typename... Args> - static typename DistrT::result_type Impl(std::true_type, URBG* urbg, - Args&&... args) { - using ResultT = typename DistrT::result_type; - using ArgTupleT = std::tuple<absl::decay_t<Args>...>; - using KeyT = ResultT(DistrT, ArgTupleT); - - ArgTupleT arg_tuple(std::forward<Args>(args)...); - ResultT result; - if (!urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple, - &result)) { - auto dist = absl::make_from_tuple<DistrT>(arg_tuple); - result = dist(*urbg); - } - return result; - } - - // Default implementation of distribution caller. - template <typename DistrT, typename... Args> - static typename DistrT::result_type Call(URBG* urbg, Args&&... args) { - return Impl<DistrT, Args...>(HasInvokeMock{}, urbg, - std::forward<Args>(args)...); - } -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/distribution_test_util.cc b/third_party/abseil_cpp/absl/random/internal/distribution_test_util.cc deleted file mode 100644 index e9005658c0a7..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/distribution_test_util.cc +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/distribution_test_util.h" - -#include <cassert> -#include <cmath> -#include <string> -#include <vector> - -#include "absl/base/internal/raw_logging.h" -#include "absl/base/macros.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -#if defined(__EMSCRIPTEN__) -// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found. -inline double fma(double x, double y, double z) { return (x * y) + z; } -#endif - -} // namespace - -DistributionMoments ComputeDistributionMoments( - absl::Span<const double> data_points) { - DistributionMoments result; - - // Compute m1 - for (double x : data_points) { - result.n++; - result.mean += x; - } - result.mean /= static_cast<double>(result.n); - - // Compute m2, m3, m4 - for (double x : data_points) { - double v = x - result.mean; - result.variance += v * v; - result.skewness += v * v * v; - result.kurtosis += v * v * v * v; - } - result.variance /= static_cast<double>(result.n - 1); - - result.skewness /= static_cast<double>(result.n); - result.skewness /= std::pow(result.variance, 1.5); - - result.kurtosis /= static_cast<double>(result.n); - result.kurtosis /= std::pow(result.variance, 2.0); - return result; - - // When validating the min/max count, the following confidence intervals may - // be of use: - // 3.291 * stddev = 99.9% CI - // 2.576 * stddev = 99% CI - // 1.96 * stddev = 95% CI - // 1.65 * stddev = 90% CI -} - -std::ostream& operator<<(std::ostream& os, const DistributionMoments& moments) { - return os << absl::StrFormat("mean=%f, stddev=%f, skewness=%f, kurtosis=%f", - moments.mean, std::sqrt(moments.variance), - moments.skewness, moments.kurtosis); -} - -double InverseNormalSurvival(double x) { - // inv_sf(u) = -sqrt(2) * erfinv(2u-1) - static constexpr double kSqrt2 = 1.4142135623730950488; - return -kSqrt2 * absl::random_internal::erfinv(2 * x - 1.0); -} - -bool Near(absl::string_view msg, double actual, double expected, double bound) { - assert(bound > 0.0); - double delta = fabs(expected - actual); - if (delta < bound) { - return true; - } - - std::string formatted = absl::StrCat( - msg, " actual=", actual, " expected=", expected, " err=", delta / bound); - ABSL_RAW_LOG(INFO, "%s", formatted.c_str()); - return false; -} - -// TODO(absl-team): Replace with an "ABSL_HAVE_SPECIAL_MATH" and try -// to use std::beta(). As of this writing P0226R1 is not implemented -// in libc++: http://libcxx.llvm.org/cxx1z_status.html -double beta(double p, double q) { - // Beta(x, y) = Gamma(x) * Gamma(y) / Gamma(x+y) - double lbeta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q); - return std::exp(lbeta); -} - -// Approximation to inverse of the Error Function in double precision. -// (http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf) -double erfinv(double x) { -#if !defined(__EMSCRIPTEN__) - using std::fma; -#endif - - double w = 0.0; - double p = 0.0; - w = -std::log((1.0 - x) * (1.0 + x)); - if (w < 6.250000) { - w = w - 3.125000; - p = -3.6444120640178196996e-21; - p = fma(p, w, -1.685059138182016589e-19); - p = fma(p, w, 1.2858480715256400167e-18); - p = fma(p, w, 1.115787767802518096e-17); - p = fma(p, w, -1.333171662854620906e-16); - p = fma(p, w, 2.0972767875968561637e-17); - p = fma(p, w, 6.6376381343583238325e-15); - p = fma(p, w, -4.0545662729752068639e-14); - p = fma(p, w, -8.1519341976054721522e-14); - p = fma(p, w, 2.6335093153082322977e-12); - p = fma(p, w, -1.2975133253453532498e-11); - p = fma(p, w, -5.4154120542946279317e-11); - p = fma(p, w, 1.051212273321532285e-09); - p = fma(p, w, -4.1126339803469836976e-09); - p = fma(p, w, -2.9070369957882005086e-08); - p = fma(p, w, 4.2347877827932403518e-07); - p = fma(p, w, -1.3654692000834678645e-06); - p = fma(p, w, -1.3882523362786468719e-05); - p = fma(p, w, 0.0001867342080340571352); - p = fma(p, w, -0.00074070253416626697512); - p = fma(p, w, -0.0060336708714301490533); - p = fma(p, w, 0.24015818242558961693); - p = fma(p, w, 1.6536545626831027356); - } else if (w < 16.000000) { - w = std::sqrt(w) - 3.250000; - p = 2.2137376921775787049e-09; - p = fma(p, w, 9.0756561938885390979e-08); - p = fma(p, w, -2.7517406297064545428e-07); - p = fma(p, w, 1.8239629214389227755e-08); - p = fma(p, w, 1.5027403968909827627e-06); - p = fma(p, w, -4.013867526981545969e-06); - p = fma(p, w, 2.9234449089955446044e-06); - p = fma(p, w, 1.2475304481671778723e-05); - p = fma(p, w, -4.7318229009055733981e-05); - p = fma(p, w, 6.8284851459573175448e-05); - p = fma(p, w, 2.4031110387097893999e-05); - p = fma(p, w, -0.0003550375203628474796); - p = fma(p, w, 0.00095328937973738049703); - p = fma(p, w, -0.0016882755560235047313); - p = fma(p, w, 0.0024914420961078508066); - p = fma(p, w, -0.0037512085075692412107); - p = fma(p, w, 0.005370914553590063617); - p = fma(p, w, 1.0052589676941592334); - p = fma(p, w, 3.0838856104922207635); - } else { - w = std::sqrt(w) - 5.000000; - p = -2.7109920616438573243e-11; - p = fma(p, w, -2.5556418169965252055e-10); - p = fma(p, w, 1.5076572693500548083e-09); - p = fma(p, w, -3.7894654401267369937e-09); - p = fma(p, w, 7.6157012080783393804e-09); - p = fma(p, w, -1.4960026627149240478e-08); - p = fma(p, w, 2.9147953450901080826e-08); - p = fma(p, w, -6.7711997758452339498e-08); - p = fma(p, w, 2.2900482228026654717e-07); - p = fma(p, w, -9.9298272942317002539e-07); - p = fma(p, w, 4.5260625972231537039e-06); - p = fma(p, w, -1.9681778105531670567e-05); - p = fma(p, w, 7.5995277030017761139e-05); - p = fma(p, w, -0.00021503011930044477347); - p = fma(p, w, -0.00013871931833623122026); - p = fma(p, w, 1.0103004648645343977); - p = fma(p, w, 4.8499064014085844221); - } - return p * x; -} - -namespace { - -// Direct implementation of AS63, BETAIN() -// https://www.jstor.org/stable/2346797?seq=3#page_scan_tab_contents. -// -// BETAIN(x, p, q, beta) -// x: the value of the upper limit x. -// p: the value of the parameter p. -// q: the value of the parameter q. -// beta: the value of ln B(p, q) -// -double BetaIncompleteImpl(const double x, const double p, const double q, - const double beta) { - if (p < (p + q) * x) { - // Incomplete beta function is symmetrical, so return the complement. - return 1. - BetaIncompleteImpl(1.0 - x, q, p, beta); - } - - double psq = p + q; - const double kErr = 1e-14; - const double xc = 1. - x; - const double pre = - std::exp(p * std::log(x) + (q - 1.) * std::log(xc) - beta) / p; - - double term = 1.; - double ai = 1.; - double result = 1.; - int ns = static_cast<int>(q + xc * psq); - - // Use the soper reduction forumla. - double rx = (ns == 0) ? x : x / xc; - double temp = q - ai; - for (;;) { - term = term * temp * rx / (p + ai); - result = result + term; - temp = std::fabs(term); - if (temp < kErr && temp < kErr * result) { - return result * pre; - } - ai = ai + 1.; - --ns; - if (ns >= 0) { - temp = q - ai; - if (ns == 0) { - rx = x; - } - } else { - temp = psq; - psq = psq + 1.; - } - } - - // NOTE: See also TOMS Alogrithm 708. - // http://www.netlib.org/toms/index.html - // - // NOTE: The NWSC library also includes BRATIO / ISUBX (p87) - // https://archive.org/details/DTIC_ADA261511/page/n75 -} - -// Direct implementation of AS109, XINBTA(p, q, beta, alpha) -// https://www.jstor.org/stable/2346798?read-now=1&seq=4#page_scan_tab_contents -// https://www.jstor.org/stable/2346887?seq=1#page_scan_tab_contents -// -// XINBTA(p, q, beta, alhpa) -// p: the value of the parameter p. -// q: the value of the parameter q. -// beta: the value of ln B(p, q) -// alpha: the value of the lower tail area. -// -double BetaIncompleteInvImpl(const double p, const double q, const double beta, - const double alpha) { - if (alpha < 0.5) { - // Inverse Incomplete beta function is symmetrical, return the complement. - return 1. - BetaIncompleteInvImpl(q, p, beta, 1. - alpha); - } - const double kErr = 1e-14; - double value = kErr; - - // Compute the initial estimate. - { - double r = std::sqrt(-std::log(alpha * alpha)); - double y = - r - fma(r, 0.27061, 2.30753) / fma(r, fma(r, 0.04481, 0.99229), 1.0); - if (p > 1. && q > 1.) { - r = (y * y - 3.) / 6.; - double s = 1. / (p + p - 1.); - double t = 1. / (q + q - 1.); - double h = 2. / s + t; - double w = - y * std::sqrt(h + r) / h - (t - s) * (r + 5. / 6. - t / (3. * h)); - value = p / (p + q * std::exp(w + w)); - } else { - r = q + q; - double t = 1.0 / (9. * q); - double u = 1.0 - t + y * std::sqrt(t); - t = r * (u * u * u); - if (t <= 0) { - value = 1.0 - std::exp((std::log((1.0 - alpha) * q) + beta) / q); - } else { - t = (4.0 * p + r - 2.0) / t; - if (t <= 1) { - value = std::exp((std::log(alpha * p) + beta) / p); - } else { - value = 1.0 - 2.0 / (t + 1.0); - } - } - } - } - - // Solve for x using a modified newton-raphson method using the function - // BetaIncomplete. - { - value = std::max(value, kErr); - value = std::min(value, 1.0 - kErr); - - const double r = 1.0 - p; - const double t = 1.0 - q; - double y; - double yprev = 0; - double sq = 1; - double prev = 1; - for (;;) { - if (value < 0 || value > 1.0) { - // Error case; value went infinite. - return std::numeric_limits<double>::infinity(); - } else if (value == 0 || value == 1) { - y = value; - } else { - y = BetaIncompleteImpl(value, p, q, beta); - if (!std::isfinite(y)) { - return y; - } - } - y = (y - alpha) * - std::exp(beta + r * std::log(value) + t * std::log(1.0 - value)); - if (y * yprev <= 0) { - prev = std::max(sq, std::numeric_limits<double>::min()); - } - double g = 1.0; - for (;;) { - const double adj = g * y; - const double adj_sq = adj * adj; - if (adj_sq >= prev) { - g = g / 3.0; - continue; - } - const double tx = value - adj; - if (tx < 0 || tx > 1) { - g = g / 3.0; - continue; - } - if (prev < kErr) { - return value; - } - if (y * y < kErr) { - return value; - } - if (tx == value) { - return value; - } - if (tx == 0 || tx == 1) { - g = g / 3.0; - continue; - } - value = tx; - yprev = y; - break; - } - } - } - - // NOTES: See also: Asymptotic inversion of the incomplete beta function. - // https://core.ac.uk/download/pdf/82140723.pdf - // - // NOTE: See the Boost library documentation as well: - // https://www.boost.org/doc/libs/1_52_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/sf_beta/ibeta_function.html -} - -} // namespace - -double BetaIncomplete(const double x, const double p, const double q) { - // Error cases. - if (p < 0 || q < 0 || x < 0 || x > 1.0) { - return std::numeric_limits<double>::infinity(); - } - if (x == 0 || x == 1) { - return x; - } - // ln(Beta(p, q)) - double beta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q); - return BetaIncompleteImpl(x, p, q, beta); -} - -double BetaIncompleteInv(const double p, const double q, const double alpha) { - // Error cases. - if (p < 0 || q < 0 || alpha < 0 || alpha > 1.0) { - return std::numeric_limits<double>::infinity(); - } - if (alpha == 0 || alpha == 1) { - return alpha; - } - // ln(Beta(p, q)) - double beta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q); - return BetaIncompleteInvImpl(p, q, beta, alpha); -} - -// Given `num_trials` trials each with probability `p` of success, the -// probability of no failures is `p^k`. To ensure the probability of a failure -// is no more than `p_fail`, it must be that `p^k == 1 - p_fail`. This function -// computes `p` from that equation. -double RequiredSuccessProbability(const double p_fail, const int num_trials) { - double p = std::exp(std::log(1.0 - p_fail) / static_cast<double>(num_trials)); - ABSL_ASSERT(p > 0); - return p; -} - -double ZScore(double expected_mean, const DistributionMoments& moments) { - return (moments.mean - expected_mean) / - (std::sqrt(moments.variance) / - std::sqrt(static_cast<double>(moments.n))); -} - -double MaxErrorTolerance(double acceptance_probability) { - double one_sided_pvalue = 0.5 * (1.0 - acceptance_probability); - const double max_err = InverseNormalSurvival(one_sided_pvalue); - ABSL_ASSERT(max_err > 0); - return max_err; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/distribution_test_util.h b/third_party/abseil_cpp/absl/random/internal/distribution_test_util.h deleted file mode 100644 index 6d94cf6c97bf..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/distribution_test_util.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_ -#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_ - -#include <cstddef> -#include <iostream> -#include <vector> - -#include "absl/strings/string_view.h" -#include "absl/types/span.h" - -// NOTE: The functions in this file are test only, and are should not be used in -// non-test code. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// http://webspace.ship.edu/pgmarr/Geo441/Lectures/Lec%205%20-%20Normality%20Testing.pdf - -// Compute the 1st to 4th standard moments: -// mean, variance, skewness, and kurtosis. -// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm -struct DistributionMoments { - size_t n = 0; - double mean = 0.0; - double variance = 0.0; - double skewness = 0.0; - double kurtosis = 0.0; -}; -DistributionMoments ComputeDistributionMoments( - absl::Span<const double> data_points); - -std::ostream& operator<<(std::ostream& os, const DistributionMoments& moments); - -// Computes the Z-score for a set of data with the given distribution moments -// compared against `expected_mean`. -double ZScore(double expected_mean, const DistributionMoments& moments); - -// Returns the probability of success required for a single trial to ensure that -// after `num_trials` trials, the probability of at least one failure is no more -// than `p_fail`. -double RequiredSuccessProbability(double p_fail, int num_trials); - -// Computes the maximum distance from the mean tolerable, for Z-Tests that are -// expected to pass with `acceptance_probability`. Will terminate if the -// resulting tolerance is zero (due to passing in 0.0 for -// `acceptance_probability` or rounding errors). -// -// For example, -// MaxErrorTolerance(0.001) = 0.0 -// MaxErrorTolerance(0.5) = ~0.47 -// MaxErrorTolerance(1.0) = inf -double MaxErrorTolerance(double acceptance_probability); - -// Approximation to inverse of the Error Function in double precision. -// (http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf) -double erfinv(double x); - -// Beta(p, q) = Gamma(p) * Gamma(q) / Gamma(p+q) -double beta(double p, double q); - -// The inverse of the normal survival function. -double InverseNormalSurvival(double x); - -// Returns whether actual is "near" expected, based on the bound. -bool Near(absl::string_view msg, double actual, double expected, double bound); - -// Implements the incomplete regularized beta function, AS63, BETAIN. -// https://www.jstor.org/stable/2346797 -// -// BetaIncomplete(x, p, q), where -// `x` is the value of the upper limit -// `p` is beta parameter p, `q` is beta parameter q. -// -// NOTE: This is a test-only function which is only accurate to within, at most, -// 1e-13 of the actual value. -// -double BetaIncomplete(double x, double p, double q); - -// Implements the inverse of the incomplete regularized beta function, AS109, -// XINBTA. -// https://www.jstor.org/stable/2346798 -// https://www.jstor.org/stable/2346887 -// -// BetaIncompleteInv(p, q, beta, alhpa) -// `p` is beta parameter p, `q` is beta parameter q. -// `alpha` is the value of the lower tail area. -// -// NOTE: This is a test-only function and, when successful, is only accurate to -// within ~1e-6 of the actual value; there are some cases where it diverges from -// the actual value by much more than that. The function uses Newton's method, -// and thus the runtime is highly variable. -double BetaIncompleteInv(double p, double q, double alpha); - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/distribution_test_util_test.cc b/third_party/abseil_cpp/absl/random/internal/distribution_test_util_test.cc deleted file mode 100644 index c49d44fb4796..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/distribution_test_util_test.cc +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/distribution_test_util.h" - -#include "gtest/gtest.h" - -namespace { - -TEST(TestUtil, InverseErf) { - const struct { - const double z; - const double value; - } kErfInvTable[] = { - {0.0000001, 8.86227e-8}, - {0.00001, 8.86227e-6}, - {0.5, 0.4769362762044}, - {0.6, 0.5951160814499}, - {0.99999, 3.1234132743}, - {0.9999999, 3.7665625816}, - {0.999999944, 3.8403850690566985}, // = log((1-x) * (1+x)) =~ 16.004 - {0.999999999, 4.3200053849134452}, - }; - - for (const auto& data : kErfInvTable) { - auto value = absl::random_internal::erfinv(data.z); - - // Log using the Wolfram-alpha function name & parameters. - EXPECT_NEAR(value, data.value, 1e-8) - << " InverseErf[" << data.z << "] (expected=" << data.value << ") -> " - << value; - } -} - -const struct { - const double p; - const double q; - const double x; - const double alpha; -} kBetaTable[] = { - {0.5, 0.5, 0.01, 0.06376856085851985}, - {0.5, 0.5, 0.1, 0.2048327646991335}, - {0.5, 0.5, 1, 1}, - {1, 0.5, 0, 0}, - {1, 0.5, 0.01, 0.005012562893380045}, - {1, 0.5, 0.1, 0.0513167019494862}, - {1, 0.5, 0.5, 0.2928932188134525}, - {1, 1, 0.5, 0.5}, - {2, 2, 0.1, 0.028}, - {2, 2, 0.2, 0.104}, - {2, 2, 0.3, 0.216}, - {2, 2, 0.4, 0.352}, - {2, 2, 0.5, 0.5}, - {2, 2, 0.6, 0.648}, - {2, 2, 0.7, 0.784}, - {2, 2, 0.8, 0.896}, - {2, 2, 0.9, 0.972}, - {5.5, 5, 0.5, 0.4361908850559777}, - {10, 0.5, 0.9, 0.1516409096346979}, - {10, 5, 0.5, 0.08978271484375}, - {10, 5, 1, 1}, - {10, 10, 0.5, 0.5}, - {20, 5, 0.8, 0.4598773297575791}, - {20, 10, 0.6, 0.2146816102371739}, - {20, 10, 0.8, 0.9507364826957875}, - {20, 20, 0.5, 0.5}, - {20, 20, 0.6, 0.8979413687105918}, - {30, 10, 0.7, 0.2241297491808366}, - {30, 10, 0.8, 0.7586405487192086}, - {40, 20, 0.7, 0.7001783247477069}, - {1, 0.5, 0.1, 0.0513167019494862}, - {1, 0.5, 0.2, 0.1055728090000841}, - {1, 0.5, 0.3, 0.1633399734659245}, - {1, 0.5, 0.4, 0.2254033307585166}, - {1, 2, 0.2, 0.36}, - {1, 3, 0.2, 0.488}, - {1, 4, 0.2, 0.5904}, - {1, 5, 0.2, 0.67232}, - {2, 2, 0.3, 0.216}, - {3, 2, 0.3, 0.0837}, - {4, 2, 0.3, 0.03078}, - {5, 2, 0.3, 0.010935}, - - // These values test small & large points along the range of the Beta - // function. - // - // When selecting test points, remember that if BetaIncomplete(x, p, q) - // returns the same value to within the limits of precision over a large - // domain of the input, x, then BetaIncompleteInv(alpha, p, q) may return an - // essentially arbitrary value where BetaIncomplete(x, p, q) =~ alpha. - - // BetaRegularized[x, 0.00001, 0.00001], - // For x in {~0.001 ... ~0.999}, => ~0.5 - {1e-5, 1e-5, 1e-5, 0.4999424388184638311}, - {1e-5, 1e-5, (1.0 - 1e-8), 0.5000920948389232964}, - - // BetaRegularized[x, 0.00001, 10000]. - // For x in {~epsilon ... 1.0}, => ~1 - {1e-5, 1e5, 1e-6, 0.9999817708130066936}, - {1e-5, 1e5, (1.0 - 1e-7), 1.0}, - - // BetaRegularized[x, 10000, 0.00001]. - // For x in {0 .. 1-epsilon}, => ~0 - {1e5, 1e-5, 1e-6, 0}, - {1e5, 1e-5, (1.0 - 1e-6), 1.8229186993306369e-5}, -}; - -TEST(BetaTest, BetaIncomplete) { - for (const auto& data : kBetaTable) { - auto value = absl::random_internal::BetaIncomplete(data.x, data.p, data.q); - - // Log using the Wolfram-alpha function name & parameters. - EXPECT_NEAR(value, data.alpha, 1e-12) - << " BetaRegularized[" << data.x << ", " << data.p << ", " << data.q - << "] (expected=" << data.alpha << ") -> " << value; - } -} - -TEST(BetaTest, BetaIncompleteInv) { - for (const auto& data : kBetaTable) { - auto value = - absl::random_internal::BetaIncompleteInv(data.p, data.q, data.alpha); - - // Log using the Wolfram-alpha function name & parameters. - EXPECT_NEAR(value, data.x, 1e-6) - << " InverseBetaRegularized[" << data.alpha << ", " << data.p << ", " - << data.q << "] (expected=" << data.x << ") -> " << value; - } -} - -TEST(MaxErrorTolerance, MaxErrorTolerance) { - std::vector<std::pair<double, double>> cases = { - {0.0000001, 8.86227e-8 * 1.41421356237}, - {0.00001, 8.86227e-6 * 1.41421356237}, - {0.5, 0.4769362762044 * 1.41421356237}, - {0.6, 0.5951160814499 * 1.41421356237}, - {0.99999, 3.1234132743 * 1.41421356237}, - {0.9999999, 3.7665625816 * 1.41421356237}, - {0.999999944, 3.8403850690566985 * 1.41421356237}, - {0.999999999, 4.3200053849134452 * 1.41421356237}}; - for (auto entry : cases) { - EXPECT_NEAR(absl::random_internal::MaxErrorTolerance(entry.first), - entry.second, 1e-8); - } -} - -TEST(ZScore, WithSameMean) { - absl::random_internal::DistributionMoments m; - m.n = 100; - m.mean = 5; - m.variance = 1; - EXPECT_NEAR(absl::random_internal::ZScore(5, m), 0, 1e-12); - - m.n = 1; - m.mean = 0; - m.variance = 1; - EXPECT_NEAR(absl::random_internal::ZScore(0, m), 0, 1e-12); - - m.n = 10000; - m.mean = -5; - m.variance = 100; - EXPECT_NEAR(absl::random_internal::ZScore(-5, m), 0, 1e-12); -} - -TEST(ZScore, DifferentMean) { - absl::random_internal::DistributionMoments m; - m.n = 100; - m.mean = 5; - m.variance = 1; - EXPECT_NEAR(absl::random_internal::ZScore(4, m), 10, 1e-12); - - m.n = 1; - m.mean = 0; - m.variance = 1; - EXPECT_NEAR(absl::random_internal::ZScore(-1, m), 1, 1e-12); - - m.n = 10000; - m.mean = -5; - m.variance = 100; - EXPECT_NEAR(absl::random_internal::ZScore(-4, m), -10, 1e-12); -} -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/explicit_seed_seq.h b/third_party/abseil_cpp/absl/random/internal/explicit_seed_seq.h deleted file mode 100644 index 6a743eaf46cc..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/explicit_seed_seq.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_ -#define ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_ - -#include <algorithm> -#include <cstddef> -#include <cstdint> -#include <initializer_list> -#include <iterator> -#include <vector> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// This class conforms to the C++ Standard "Seed Sequence" concept -// [rand.req.seedseq]. -// -// An "ExplicitSeedSeq" is meant to provide a conformant interface for -// forwarding pre-computed seed material to the constructor of a class -// conforming to the "Uniform Random Bit Generator" concept. This class makes no -// attempt to mutate the state provided by its constructor, and returns it -// directly via ExplicitSeedSeq::generate(). -// -// If this class is asked to generate more seed material than was provided to -// the constructor, then the remaining bytes will be filled with deterministic, -// nonrandom data. -class ExplicitSeedSeq { - public: - using result_type = uint32_t; - - ExplicitSeedSeq() : state_() {} - - // Copy and move both allowed. - ExplicitSeedSeq(const ExplicitSeedSeq& other) = default; - ExplicitSeedSeq& operator=(const ExplicitSeedSeq& other) = default; - ExplicitSeedSeq(ExplicitSeedSeq&& other) = default; - ExplicitSeedSeq& operator=(ExplicitSeedSeq&& other) = default; - - template <typename Iterator> - ExplicitSeedSeq(Iterator begin, Iterator end) { - for (auto it = begin; it != end; it++) { - state_.push_back(*it & 0xffffffff); - } - } - - template <typename T> - ExplicitSeedSeq(std::initializer_list<T> il) - : ExplicitSeedSeq(il.begin(), il.end()) {} - - size_t size() const { return state_.size(); } - - template <typename OutIterator> - void param(OutIterator out) const { - std::copy(std::begin(state_), std::end(state_), out); - } - - template <typename OutIterator> - void generate(OutIterator begin, OutIterator end) { - for (size_t index = 0; begin != end; begin++) { - *begin = state_.empty() ? 0 : state_[index++]; - if (index >= state_.size()) { - index = 0; - } - } - } - - protected: - std::vector<uint32_t> state_; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/explicit_seed_seq_test.cc b/third_party/abseil_cpp/absl/random/internal/explicit_seed_seq_test.cc deleted file mode 100644 index a55ad73948b9..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/explicit_seed_seq_test.cc +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/explicit_seed_seq.h" - -#include <iterator> -#include <random> -#include <utility> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/random/seed_sequences.h" - -namespace { - -template <typename Sseq> -bool ConformsToInterface() { - // Check that the SeedSequence can be default-constructed. - { Sseq default_constructed_seq; } - // Check that the SeedSequence can be constructed with two iterators. - { - uint32_t init_array[] = {1, 3, 5, 7, 9}; - Sseq iterator_constructed_seq(init_array, &init_array[5]); - } - // Check that the SeedSequence can be std::initializer_list-constructed. - { Sseq list_constructed_seq = {1, 3, 5, 7, 9, 11, 13}; } - // Check that param() and size() return state provided to constructor. - { - uint32_t init_array[] = {1, 2, 3, 4, 5}; - Sseq seq(init_array, &init_array[ABSL_ARRAYSIZE(init_array)]); - EXPECT_EQ(seq.size(), ABSL_ARRAYSIZE(init_array)); - - uint32_t state_array[ABSL_ARRAYSIZE(init_array)]; - seq.param(state_array); - - for (int i = 0; i < ABSL_ARRAYSIZE(state_array); i++) { - EXPECT_EQ(state_array[i], i + 1); - } - } - // Check for presence of generate() method. - { - Sseq seq; - uint32_t seeds[5]; - - seq.generate(seeds, &seeds[ABSL_ARRAYSIZE(seeds)]); - } - return true; -} -} // namespace - -TEST(SeedSequences, CheckInterfaces) { - // Control case - EXPECT_TRUE(ConformsToInterface<std::seed_seq>()); - - // Abseil classes - EXPECT_TRUE(ConformsToInterface<absl::random_internal::ExplicitSeedSeq>()); -} - -TEST(ExplicitSeedSeq, DefaultConstructorGeneratesZeros) { - const size_t kNumBlocks = 128; - - uint32_t outputs[kNumBlocks]; - absl::random_internal::ExplicitSeedSeq seq; - seq.generate(outputs, &outputs[kNumBlocks]); - - for (uint32_t& seed : outputs) { - EXPECT_EQ(seed, 0); - } -} - -TEST(ExplicitSeeqSeq, SeedMaterialIsForwardedIdentically) { - const size_t kNumBlocks = 128; - - uint32_t seed_material[kNumBlocks]; - std::random_device urandom{"/dev/urandom"}; - for (uint32_t& seed : seed_material) { - seed = urandom(); - } - absl::random_internal::ExplicitSeedSeq seq(seed_material, - &seed_material[kNumBlocks]); - - // Check that output is same as seed-material provided to constructor. - { - const size_t kNumGenerated = kNumBlocks / 2; - uint32_t outputs[kNumGenerated]; - seq.generate(outputs, &outputs[kNumGenerated]); - for (size_t i = 0; i < kNumGenerated; i++) { - EXPECT_EQ(outputs[i], seed_material[i]); - } - } - // Check that SeedSequence is stateless between invocations: Despite the last - // invocation of generate() only consuming half of the input-entropy, the same - // entropy will be recycled for the next invocation. - { - const size_t kNumGenerated = kNumBlocks; - uint32_t outputs[kNumGenerated]; - seq.generate(outputs, &outputs[kNumGenerated]); - for (size_t i = 0; i < kNumGenerated; i++) { - EXPECT_EQ(outputs[i], seed_material[i]); - } - } - // Check that when more seed-material is asked for than is provided, nonzero - // values are still written. - { - const size_t kNumGenerated = kNumBlocks * 2; - uint32_t outputs[kNumGenerated]; - seq.generate(outputs, &outputs[kNumGenerated]); - for (size_t i = 0; i < kNumGenerated; i++) { - EXPECT_EQ(outputs[i], seed_material[i % kNumBlocks]); - } - } -} - -TEST(ExplicitSeedSeq, CopyAndMoveConstructors) { - using testing::Each; - using testing::Eq; - using testing::Not; - using testing::Pointwise; - - uint32_t entropy[4]; - std::random_device urandom("/dev/urandom"); - for (uint32_t& entry : entropy) { - entry = urandom(); - } - absl::random_internal::ExplicitSeedSeq seq_from_entropy(std::begin(entropy), - std::end(entropy)); - // Copy constructor. - { - absl::random_internal::ExplicitSeedSeq seq_copy(seq_from_entropy); - EXPECT_EQ(seq_copy.size(), seq_from_entropy.size()); - - std::vector<uint32_t> seeds_1; - seeds_1.resize(1000, 0); - std::vector<uint32_t> seeds_2; - seeds_2.resize(1000, 1); - - seq_from_entropy.generate(seeds_1.begin(), seeds_1.end()); - seq_copy.generate(seeds_2.begin(), seeds_2.end()); - - EXPECT_THAT(seeds_1, Pointwise(Eq(), seeds_2)); - } - // Assignment operator. - { - for (uint32_t& entry : entropy) { - entry = urandom(); - } - absl::random_internal::ExplicitSeedSeq another_seq(std::begin(entropy), - std::end(entropy)); - - std::vector<uint32_t> seeds_1; - seeds_1.resize(1000, 0); - std::vector<uint32_t> seeds_2; - seeds_2.resize(1000, 0); - - seq_from_entropy.generate(seeds_1.begin(), seeds_1.end()); - another_seq.generate(seeds_2.begin(), seeds_2.end()); - - // Assert precondition: Sequences generated by seed-sequences are not equal. - EXPECT_THAT(seeds_1, Not(Pointwise(Eq(), seeds_2))); - - // Apply the assignment-operator. - another_seq = seq_from_entropy; - - // Re-generate seeds. - seq_from_entropy.generate(seeds_1.begin(), seeds_1.end()); - another_seq.generate(seeds_2.begin(), seeds_2.end()); - - // Seeds generated by seed-sequences should now be equal. - EXPECT_THAT(seeds_1, Pointwise(Eq(), seeds_2)); - } - // Move constructor. - { - // Get seeds from seed-sequence constructed from entropy. - std::vector<uint32_t> seeds_1; - seeds_1.resize(1000, 0); - seq_from_entropy.generate(seeds_1.begin(), seeds_1.end()); - - // Apply move-constructor move the sequence to another instance. - absl::random_internal::ExplicitSeedSeq moved_seq( - std::move(seq_from_entropy)); - std::vector<uint32_t> seeds_2; - seeds_2.resize(1000, 1); - moved_seq.generate(seeds_2.begin(), seeds_2.end()); - // Verify that seeds produced by moved-instance are the same as original. - EXPECT_THAT(seeds_1, Pointwise(Eq(), seeds_2)); - - // Verify that the moved-from instance now behaves like a - // default-constructed instance. - EXPECT_EQ(seq_from_entropy.size(), 0); - seq_from_entropy.generate(seeds_1.begin(), seeds_1.end()); - EXPECT_THAT(seeds_1, Each(Eq(0))); - } -} diff --git a/third_party/abseil_cpp/absl/random/internal/fast_uniform_bits.h b/third_party/abseil_cpp/absl/random/internal/fast_uniform_bits.h deleted file mode 100644 index 425aaf7d830c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/fast_uniform_bits.h +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_ -#define ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_ - -#include <cstddef> -#include <cstdint> -#include <limits> -#include <type_traits> - -#include "absl/base/config.h" -#include "absl/meta/type_traits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -// Returns true if the input value is zero or a power of two. Useful for -// determining if the range of output values in a URBG -template <typename UIntType> -constexpr bool IsPowerOfTwoOrZero(UIntType n) { - return (n == 0) || ((n & (n - 1)) == 0); -} - -// Computes the length of the range of values producible by the URBG, or returns -// zero if that would encompass the entire range of representable values in -// URBG::result_type. -template <typename URBG> -constexpr typename URBG::result_type RangeSize() { - using result_type = typename URBG::result_type; - static_assert((URBG::max)() != (URBG::min)(), "URBG range cannot be 0."); - return ((URBG::max)() == (std::numeric_limits<result_type>::max)() && - (URBG::min)() == std::numeric_limits<result_type>::lowest()) - ? result_type{0} - : ((URBG::max)() - (URBG::min)() + result_type{1}); -} - -// Computes the floor of the log. (i.e., std::floor(std::log2(N)); -template <typename UIntType> -constexpr UIntType IntegerLog2(UIntType n) { - return (n <= 1) ? 0 : 1 + IntegerLog2(n >> 1); -} - -// Returns the number of bits of randomness returned through -// `PowerOfTwoVariate(urbg)`. -template <typename URBG> -constexpr size_t NumBits() { - return RangeSize<URBG>() == 0 - ? std::numeric_limits<typename URBG::result_type>::digits - : IntegerLog2(RangeSize<URBG>()); -} - -// Given a shift value `n`, constructs a mask with exactly the low `n` bits set. -// If `n == 0`, all bits are set. -template <typename UIntType> -constexpr UIntType MaskFromShift(size_t n) { - return ((n % std::numeric_limits<UIntType>::digits) == 0) - ? ~UIntType{0} - : (UIntType{1} << n) - UIntType{1}; -} - -// Tags used to dispatch FastUniformBits::generate to the simple or more complex -// entropy extraction algorithm. -struct SimplifiedLoopTag {}; -struct RejectionLoopTag {}; - -// FastUniformBits implements a fast path to acquire uniform independent bits -// from a type which conforms to the [rand.req.urbg] concept. -// Parameterized by: -// `UIntType`: the result (output) type -// -// The std::independent_bits_engine [rand.adapt.ibits] adaptor can be -// instantiated from an existing generator through a copy or a move. It does -// not, however, facilitate the production of pseudorandom bits from an un-owned -// generator that will outlive the std::independent_bits_engine instance. -template <typename UIntType = uint64_t> -class FastUniformBits { - public: - using result_type = UIntType; - - static constexpr result_type(min)() { return 0; } - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - template <typename URBG> - result_type operator()(URBG& g); // NOLINT(runtime/references) - - private: - static_assert(std::is_unsigned<UIntType>::value, - "Class-template FastUniformBits<> must be parameterized using " - "an unsigned type."); - - // Generate() generates a random value, dispatched on whether - // the underlying URBG must use rejection sampling to generate a value, - // or whether a simplified loop will suffice. - template <typename URBG> - result_type Generate(URBG& g, // NOLINT(runtime/references) - SimplifiedLoopTag); - - template <typename URBG> - result_type Generate(URBG& g, // NOLINT(runtime/references) - RejectionLoopTag); -}; - -template <typename UIntType> -template <typename URBG> -typename FastUniformBits<UIntType>::result_type -FastUniformBits<UIntType>::operator()(URBG& g) { // NOLINT(runtime/references) - // kRangeMask is the mask used when sampling variates from the URBG when the - // width of the URBG range is not a power of 2. - // Y = (2 ^ kRange) - 1 - static_assert((URBG::max)() > (URBG::min)(), - "URBG::max and URBG::min may not be equal."); - - using tag = absl::conditional_t<IsPowerOfTwoOrZero(RangeSize<URBG>()), - SimplifiedLoopTag, RejectionLoopTag>; - return Generate(g, tag{}); -} - -template <typename UIntType> -template <typename URBG> -typename FastUniformBits<UIntType>::result_type -FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references) - SimplifiedLoopTag) { - // The simplified version of FastUniformBits works only on URBGs that have - // a range that is a power of 2. In this case we simply loop and shift without - // attempting to balance the bits across calls. - static_assert(IsPowerOfTwoOrZero(RangeSize<URBG>()), - "incorrect Generate tag for URBG instance"); - - static constexpr size_t kResultBits = - std::numeric_limits<result_type>::digits; - static constexpr size_t kUrbgBits = NumBits<URBG>(); - static constexpr size_t kIters = - (kResultBits / kUrbgBits) + (kResultBits % kUrbgBits != 0); - static constexpr size_t kShift = (kIters == 1) ? 0 : kUrbgBits; - static constexpr auto kMin = (URBG::min)(); - - result_type r = static_cast<result_type>(g() - kMin); - for (size_t n = 1; n < kIters; ++n) { - r = (r << kShift) + static_cast<result_type>(g() - kMin); - } - return r; -} - -template <typename UIntType> -template <typename URBG> -typename FastUniformBits<UIntType>::result_type -FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references) - RejectionLoopTag) { - static_assert(!IsPowerOfTwoOrZero(RangeSize<URBG>()), - "incorrect Generate tag for URBG instance"); - using urbg_result_type = typename URBG::result_type; - - // See [rand.adapt.ibits] for more details on the constants calculated below. - // - // It is preferable to use roughly the same number of bits from each generator - // call, however this is only possible when the number of bits provided by the - // URBG is a divisor of the number of bits in `result_type`. In all other - // cases, the number of bits used cannot always be the same, but it can be - // guaranteed to be off by at most 1. Thus we run two loops, one with a - // smaller bit-width size (`kSmallWidth`) and one with a larger width size - // (satisfying `kLargeWidth == kSmallWidth + 1`). The loops are run - // `kSmallIters` and `kLargeIters` times respectively such - // that - // - // `kResultBits == kSmallIters * kSmallBits - // + kLargeIters * kLargeBits` - // - // where `kResultBits` is the total number of bits in `result_type`. - // - static constexpr size_t kResultBits = - std::numeric_limits<result_type>::digits; // w - static constexpr urbg_result_type kUrbgRange = RangeSize<URBG>(); // R - static constexpr size_t kUrbgBits = NumBits<URBG>(); // m - - // compute the initial estimate of the bits used. - // [rand.adapt.ibits] 2 (c) - static constexpr size_t kA = // ceil(w/m) - (kResultBits / kUrbgBits) + ((kResultBits % kUrbgBits) != 0); // n' - - static constexpr size_t kABits = kResultBits / kA; // w0' - static constexpr urbg_result_type kARejection = - ((kUrbgRange >> kABits) << kABits); // y0' - - // refine the selection to reduce the rejection frequency. - static constexpr size_t kTotalIters = - ((kUrbgRange - kARejection) <= (kARejection / kA)) ? kA : (kA + 1); // n - - // [rand.adapt.ibits] 2 (b) - static constexpr size_t kSmallIters = - kTotalIters - (kResultBits % kTotalIters); // n0 - static constexpr size_t kSmallBits = kResultBits / kTotalIters; // w0 - static constexpr urbg_result_type kSmallRejection = - ((kUrbgRange >> kSmallBits) << kSmallBits); // y0 - - static constexpr size_t kLargeBits = kSmallBits + 1; // w0+1 - static constexpr urbg_result_type kLargeRejection = - ((kUrbgRange >> kLargeBits) << kLargeBits); // y1 - - // - // Because `kLargeBits == kSmallBits + 1`, it follows that - // - // `kResultBits == kSmallIters * kSmallBits + kLargeIters` - // - // and therefore - // - // `kLargeIters == kTotalWidth % kSmallWidth` - // - // Intuitively, each iteration with the large width accounts for one unit - // of the remainder when `kTotalWidth` is divided by `kSmallWidth`. As - // mentioned above, if the URBG width is a divisor of `kTotalWidth`, then - // there would be no need for any large iterations (i.e., one loop would - // suffice), and indeed, in this case, `kLargeIters` would be zero. - static_assert(kResultBits == kSmallIters * kSmallBits + - (kTotalIters - kSmallIters) * kLargeBits, - "Error in looping constant calculations."); - - // The small shift is essentially small bits, but due to the potential - // of generating a smaller result_type from a larger urbg type, the actual - // shift might be 0. - static constexpr size_t kSmallShift = kSmallBits % kResultBits; - static constexpr auto kSmallMask = - MaskFromShift<urbg_result_type>(kSmallShift); - static constexpr size_t kLargeShift = kLargeBits % kResultBits; - static constexpr auto kLargeMask = - MaskFromShift<urbg_result_type>(kLargeShift); - - static constexpr auto kMin = (URBG::min)(); - - result_type s = 0; - for (size_t n = 0; n < kSmallIters; ++n) { - urbg_result_type v; - do { - v = g() - kMin; - } while (v >= kSmallRejection); - - s = (s << kSmallShift) + static_cast<result_type>(v & kSmallMask); - } - - for (size_t n = kSmallIters; n < kTotalIters; ++n) { - urbg_result_type v; - do { - v = g() - kMin; - } while (v >= kLargeRejection); - - s = (s << kLargeShift) + static_cast<result_type>(v & kLargeMask); - } - return s; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/fast_uniform_bits_test.cc b/third_party/abseil_cpp/absl/random/internal/fast_uniform_bits_test.cc deleted file mode 100644 index cee702df852d..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/fast_uniform_bits_test.cc +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/fast_uniform_bits.h" - -#include <random> - -#include "gtest/gtest.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -template <typename IntType> -class FastUniformBitsTypedTest : public ::testing::Test {}; - -using IntTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t>; - -TYPED_TEST_SUITE(FastUniformBitsTypedTest, IntTypes); - -TYPED_TEST(FastUniformBitsTypedTest, BasicTest) { - using Limits = std::numeric_limits<TypeParam>; - using FastBits = FastUniformBits<TypeParam>; - - EXPECT_EQ(0, (FastBits::min)()); - EXPECT_EQ((Limits::max)(), (FastBits::max)()); - - constexpr int kIters = 10000; - std::random_device rd; - std::mt19937 gen(rd()); - FastBits fast; - for (int i = 0; i < kIters; i++) { - const auto v = fast(gen); - EXPECT_LE(v, (FastBits::max)()); - EXPECT_GE(v, (FastBits::min)()); - } -} - -template <typename UIntType, UIntType Lo, UIntType Hi, UIntType Val = Lo> -struct FakeUrbg { - using result_type = UIntType; - - FakeUrbg() = default; - explicit FakeUrbg(bool r) : reject(r) {} - - static constexpr result_type(max)() { return Hi; } - static constexpr result_type(min)() { return Lo; } - result_type operator()() { - // when reject is set, return Hi half the time. - return ((++calls % 2) == 1 && reject) ? Hi : Val; - } - - bool reject = false; - size_t calls = 0; -}; - -TEST(FastUniformBitsTest, IsPowerOfTwoOrZero) { - EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{0})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{1})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{2})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint8_t{3})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{4})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{16})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint8_t{17})); - EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint8_t>::max)())); - - EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{0})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{1})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{2})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint16_t{3})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{4})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{16})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint16_t{17})); - EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint16_t>::max)())); - - EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{0})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{1})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{2})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint32_t{3})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{32})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint32_t{17})); - EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint32_t>::max)())); - - EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{0})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{1})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{2})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint64_t{3})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{4})); - EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{64})); - EXPECT_FALSE(IsPowerOfTwoOrZero(uint64_t{17})); - EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits<uint64_t>::max)())); -} - -TEST(FastUniformBitsTest, IntegerLog2) { - EXPECT_EQ(0, IntegerLog2(uint16_t{0})); - EXPECT_EQ(0, IntegerLog2(uint16_t{1})); - EXPECT_EQ(1, IntegerLog2(uint16_t{2})); - EXPECT_EQ(1, IntegerLog2(uint16_t{3})); - EXPECT_EQ(2, IntegerLog2(uint16_t{4})); - EXPECT_EQ(2, IntegerLog2(uint16_t{5})); - EXPECT_EQ(2, IntegerLog2(uint16_t{7})); - EXPECT_EQ(3, IntegerLog2(uint16_t{8})); - EXPECT_EQ(63, IntegerLog2((std::numeric_limits<uint64_t>::max)())); -} - -TEST(FastUniformBitsTest, RangeSize) { - EXPECT_EQ(2, (RangeSize<FakeUrbg<uint8_t, 0, 1>>())); - EXPECT_EQ(3, (RangeSize<FakeUrbg<uint8_t, 0, 2>>())); - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint8_t, 0, 3>>())); - // EXPECT_EQ(0, (RangeSize<FakeUrbg<uint8_t, 2, 2>>())); - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint8_t, 2, 5>>())); - EXPECT_EQ(5, (RangeSize<FakeUrbg<uint8_t, 2, 6>>())); - EXPECT_EQ(9, (RangeSize<FakeUrbg<uint8_t, 2, 10>>())); - EXPECT_EQ( - 0, (RangeSize< - FakeUrbg<uint8_t, 0, (std::numeric_limits<uint8_t>::max)()>>())); - - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint16_t, 0, 3>>())); - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint16_t, 2, 5>>())); - EXPECT_EQ(5, (RangeSize<FakeUrbg<uint16_t, 2, 6>>())); - EXPECT_EQ(18, (RangeSize<FakeUrbg<uint16_t, 1000, 1017>>())); - EXPECT_EQ( - 0, (RangeSize< - FakeUrbg<uint16_t, 0, (std::numeric_limits<uint16_t>::max)()>>())); - - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint32_t, 0, 3>>())); - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint32_t, 2, 5>>())); - EXPECT_EQ(5, (RangeSize<FakeUrbg<uint32_t, 2, 6>>())); - EXPECT_EQ(18, (RangeSize<FakeUrbg<uint32_t, 1000, 1017>>())); - EXPECT_EQ(0, (RangeSize<FakeUrbg<uint32_t, 0, 0xffffffff>>())); - EXPECT_EQ(0xffffffff, (RangeSize<FakeUrbg<uint32_t, 1, 0xffffffff>>())); - EXPECT_EQ(0xfffffffe, (RangeSize<FakeUrbg<uint32_t, 1, 0xfffffffe>>())); - EXPECT_EQ(0xfffffffd, (RangeSize<FakeUrbg<uint32_t, 2, 0xfffffffe>>())); - EXPECT_EQ( - 0, (RangeSize< - FakeUrbg<uint32_t, 0, (std::numeric_limits<uint32_t>::max)()>>())); - - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint64_t, 0, 3>>())); - EXPECT_EQ(4, (RangeSize<FakeUrbg<uint64_t, 2, 5>>())); - EXPECT_EQ(5, (RangeSize<FakeUrbg<uint64_t, 2, 6>>())); - EXPECT_EQ(18, (RangeSize<FakeUrbg<uint64_t, 1000, 1017>>())); - EXPECT_EQ(0x100000000, (RangeSize<FakeUrbg<uint64_t, 0, 0xffffffff>>())); - EXPECT_EQ(0xffffffff, (RangeSize<FakeUrbg<uint64_t, 1, 0xffffffff>>())); - EXPECT_EQ(0xfffffffe, (RangeSize<FakeUrbg<uint64_t, 1, 0xfffffffe>>())); - EXPECT_EQ(0xfffffffd, (RangeSize<FakeUrbg<uint64_t, 2, 0xfffffffe>>())); - EXPECT_EQ(0, (RangeSize<FakeUrbg<uint64_t, 0, 0xffffffffffffffff>>())); - EXPECT_EQ(0xffffffffffffffff, - (RangeSize<FakeUrbg<uint64_t, 1, 0xffffffffffffffff>>())); - EXPECT_EQ(0xfffffffffffffffe, - (RangeSize<FakeUrbg<uint64_t, 1, 0xfffffffffffffffe>>())); - EXPECT_EQ(0xfffffffffffffffd, - (RangeSize<FakeUrbg<uint64_t, 2, 0xfffffffffffffffe>>())); - EXPECT_EQ( - 0, (RangeSize< - FakeUrbg<uint64_t, 0, (std::numeric_limits<uint64_t>::max)()>>())); -} - -// The constants need to be choosen so that an infinite rejection loop doesn't -// happen... -using Urng1_5bit = FakeUrbg<uint8_t, 0, 2, 0>; // ~1.5 bits (range 3) -using Urng4bits = FakeUrbg<uint8_t, 1, 0x10, 2>; -using Urng22bits = FakeUrbg<uint32_t, 0, 0x3fffff, 0x301020>; -using Urng31bits = FakeUrbg<uint32_t, 1, 0xfffffffe, 0x60070f03>; // ~31.9 bits -using Urng32bits = FakeUrbg<uint32_t, 0, 0xffffffff, 0x74010f01>; -using Urng33bits = - FakeUrbg<uint64_t, 1, 0x1ffffffff, 0x013301033>; // ~32.9 bits -using Urng63bits = FakeUrbg<uint64_t, 1, 0xfffffffffffffffe, - 0xfedcba9012345678>; // ~63.9 bits -using Urng64bits = - FakeUrbg<uint64_t, 0, 0xffffffffffffffff, 0x123456780fedcba9>; - -TEST(FastUniformBitsTest, OutputsUpTo32Bits) { - // Tests that how values are composed; the single-bit deltas should be spread - // across each invocation. - Urng1_5bit urng1_5; - Urng4bits urng4; - Urng22bits urng22; - Urng31bits urng31; - Urng32bits urng32; - Urng33bits urng33; - Urng63bits urng63; - Urng64bits urng64; - - // 8-bit types - { - FastUniformBits<uint8_t> fast8; - EXPECT_EQ(0x0, fast8(urng1_5)); - EXPECT_EQ(0x11, fast8(urng4)); - EXPECT_EQ(0x20, fast8(urng22)); - EXPECT_EQ(0x2, fast8(urng31)); - EXPECT_EQ(0x1, fast8(urng32)); - EXPECT_EQ(0x32, fast8(urng33)); - EXPECT_EQ(0x77, fast8(urng63)); - EXPECT_EQ(0xa9, fast8(urng64)); - } - - // 16-bit types - { - FastUniformBits<uint16_t> fast16; - EXPECT_EQ(0x0, fast16(urng1_5)); - EXPECT_EQ(0x1111, fast16(urng4)); - EXPECT_EQ(0x1020, fast16(urng22)); - EXPECT_EQ(0x0f02, fast16(urng31)); - EXPECT_EQ(0x0f01, fast16(urng32)); - EXPECT_EQ(0x1032, fast16(urng33)); - EXPECT_EQ(0x5677, fast16(urng63)); - EXPECT_EQ(0xcba9, fast16(urng64)); - } - - // 32-bit types - { - FastUniformBits<uint32_t> fast32; - EXPECT_EQ(0x0, fast32(urng1_5)); - EXPECT_EQ(0x11111111, fast32(urng4)); - EXPECT_EQ(0x08301020, fast32(urng22)); - EXPECT_EQ(0x0f020f02, fast32(urng31)); - EXPECT_EQ(0x74010f01, fast32(urng32)); - EXPECT_EQ(0x13301032, fast32(urng33)); - EXPECT_EQ(0x12345677, fast32(urng63)); - EXPECT_EQ(0x0fedcba9, fast32(urng64)); - } -} - -TEST(FastUniformBitsTest, Outputs64Bits) { - // Tests that how values are composed; the single-bit deltas should be spread - // across each invocation. - FastUniformBits<uint64_t> fast64; - - { - FakeUrbg<uint8_t, 0, 1, 0> urng0; - FakeUrbg<uint8_t, 0, 1, 1> urng1; - Urng4bits urng4; - Urng22bits urng22; - Urng31bits urng31; - Urng32bits urng32; - Urng33bits urng33; - Urng63bits urng63; - Urng64bits urng64; - - // somewhat degenerate cases only create a single bit. - EXPECT_EQ(0x0, fast64(urng0)); - EXPECT_EQ(64, urng0.calls); - EXPECT_EQ(0xffffffffffffffff, fast64(urng1)); - EXPECT_EQ(64, urng1.calls); - - // less degenerate cases. - EXPECT_EQ(0x1111111111111111, fast64(urng4)); - EXPECT_EQ(16, urng4.calls); - EXPECT_EQ(0x01020c0408301020, fast64(urng22)); - EXPECT_EQ(3, urng22.calls); - EXPECT_EQ(0x387811c3c0870f02, fast64(urng31)); - EXPECT_EQ(3, urng31.calls); - EXPECT_EQ(0x74010f0174010f01, fast64(urng32)); - EXPECT_EQ(2, urng32.calls); - EXPECT_EQ(0x808194040cb01032, fast64(urng33)); - EXPECT_EQ(3, urng33.calls); - EXPECT_EQ(0x1234567712345677, fast64(urng63)); - EXPECT_EQ(2, urng63.calls); - EXPECT_EQ(0x123456780fedcba9, fast64(urng64)); - EXPECT_EQ(1, urng64.calls); - } - - // The 1.5 bit case is somewhat interesting in that the algorithm refinement - // causes one extra small sample. Comments here reference the names used in - // [rand.adapt.ibits] that correspond to this case. - { - Urng1_5bit urng1_5; - - // w = 64 - // R = 3 - // m = 1 - // n' = 64 - // w0' = 1 - // y0' = 2 - // n = (1 <= 0) > 64 : 65 = 65 - // n0 = 65 - (64%65) = 1 - // n1 = 64 - // w0 = 0 - // y0 = 3 - // w1 = 1 - // y1 = 2 - EXPECT_EQ(0x0, fast64(urng1_5)); - EXPECT_EQ(65, urng1_5.calls); - } - - // Validate rejections for non-power-of-2 cases. - { - Urng1_5bit urng1_5(true); - Urng31bits urng31(true); - Urng33bits urng33(true); - Urng63bits urng63(true); - - // For 1.5 bits, there would be 1+2*64, except the first - // value was accepted and shifted off the end. - EXPECT_EQ(0, fast64(urng1_5)); - EXPECT_EQ(128, urng1_5.calls); - EXPECT_EQ(0x387811c3c0870f02, fast64(urng31)); - EXPECT_EQ(6, urng31.calls); - EXPECT_EQ(0x808194040cb01032, fast64(urng33)); - EXPECT_EQ(6, urng33.calls); - EXPECT_EQ(0x1234567712345677, fast64(urng63)); - EXPECT_EQ(4, urng63.calls); - } -} - -TEST(FastUniformBitsTest, URBG32bitRegression) { - // Validate with deterministic 32-bit std::minstd_rand - // to ensure that operator() performs as expected. - - EXPECT_EQ(2147483646, RangeSize<std::minstd_rand>()); - EXPECT_EQ(30, IntegerLog2(RangeSize<std::minstd_rand>())); - - std::minstd_rand gen(1); - FastUniformBits<uint64_t> fast64; - - EXPECT_EQ(0x05e47095f8791f45, fast64(gen)); - EXPECT_EQ(0x028be17e3c07c122, fast64(gen)); - EXPECT_EQ(0x55d2847c1626e8c2, fast64(gen)); -} - -} // namespace -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/fastmath.h b/third_party/abseil_cpp/absl/random/internal/fastmath.h deleted file mode 100644 index 6baeb5a7c917..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/fastmath.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_FASTMATH_H_ -#define ABSL_RANDOM_INTERNAL_FASTMATH_H_ - -// This file contains fast math functions (bitwise ops as well as some others) -// which are implementation details of various absl random number distributions. - -#include <cassert> -#include <cmath> -#include <cstdint> - -#include "absl/base/internal/bits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Returns the position of the first bit set. -inline int LeadingSetBit(uint64_t n) { - return 64 - base_internal::CountLeadingZeros64(n); -} - -// Compute log2(n) using integer operations. -// While std::log2 is more accurate than std::log(n) / std::log(2), for -// very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2, -// for instance--std::log2 rounds up rather than down, which introduces -// definite skew in the results. -inline int IntLog2Floor(uint64_t n) { - return (n <= 1) ? 0 : (63 - base_internal::CountLeadingZeros64(n)); -} -inline int IntLog2Ceil(uint64_t n) { - return (n <= 1) ? 0 : (64 - base_internal::CountLeadingZeros64(n - 1)); -} - -inline double StirlingLogFactorial(double n) { - assert(n >= 1); - // Using Stirling's approximation. - constexpr double kLog2PI = 1.83787706640934548356; - const double logn = std::log(n); - const double ninv = 1.0 / static_cast<double>(n); - return n * logn - n + 0.5 * (kLog2PI + logn) + (1.0 / 12.0) * ninv - - (1.0 / 360.0) * ninv * ninv * ninv; -} - -// Rotate value right. -// -// We only implement the uint32_t / uint64_t versions because -// 1) those are the only ones we use, and -// 2) those are the only ones where clang detects the rotate idiom correctly. -inline constexpr uint32_t rotr(uint32_t value, uint8_t bits) { - return (value >> (bits & 31)) | (value << ((-bits) & 31)); -} -inline constexpr uint64_t rotr(uint64_t value, uint8_t bits) { - return (value >> (bits & 63)) | (value << ((-bits) & 63)); -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_FASTMATH_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/fastmath_test.cc b/third_party/abseil_cpp/absl/random/internal/fastmath_test.cc deleted file mode 100644 index 65859c25de4c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/fastmath_test.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/fastmath.h" - -#include "gtest/gtest.h" - -#if defined(__native_client__) || defined(__EMSCRIPTEN__) -// NACL has a less accurate implementation of std::log2 than most of -// the other platforms. For some values which should have integral results, -// sometimes NACL returns slightly larger values. -// -// The MUSL libc used by emscripten also has a similar bug. -#define ABSL_RANDOM_INACCURATE_LOG2 -#endif - -namespace { - -TEST(DistributionImplTest, LeadingSetBit) { - using absl::random_internal::LeadingSetBit; - constexpr uint64_t kZero = 0; - EXPECT_EQ(0, LeadingSetBit(kZero)); - EXPECT_EQ(64, LeadingSetBit(~kZero)); - - for (int index = 0; index < 64; index++) { - uint64_t x = static_cast<uint64_t>(1) << index; - EXPECT_EQ(index + 1, LeadingSetBit(x)) << index; - EXPECT_EQ(index + 1, LeadingSetBit(x + x - 1)) << index; - } -} - -TEST(FastMathTest, IntLog2FloorTest) { - using absl::random_internal::IntLog2Floor; - constexpr uint64_t kZero = 0; - EXPECT_EQ(0, IntLog2Floor(0)); // boundary. return 0. - EXPECT_EQ(0, IntLog2Floor(1)); - EXPECT_EQ(1, IntLog2Floor(2)); - EXPECT_EQ(63, IntLog2Floor(~kZero)); - - // A boundary case: Converting 0xffffffffffffffff requires > 53 - // bits of precision, so the conversion to double rounds up, - // and the result of std::log2(x) > IntLog2Floor(x). - EXPECT_LT(IntLog2Floor(~kZero), static_cast<int>(std::log2(~kZero))); - - for (int i = 0; i < 64; i++) { - const uint64_t i_pow_2 = static_cast<uint64_t>(1) << i; - EXPECT_EQ(i, IntLog2Floor(i_pow_2)); - EXPECT_EQ(i, static_cast<int>(std::log2(i_pow_2))); - - uint64_t y = i_pow_2; - for (int j = i - 1; j > 0; --j) { - y = y | (i_pow_2 >> j); - EXPECT_EQ(i, IntLog2Floor(y)); - } - } -} - -TEST(FastMathTest, IntLog2CeilTest) { - using absl::random_internal::IntLog2Ceil; - constexpr uint64_t kZero = 0; - EXPECT_EQ(0, IntLog2Ceil(0)); // boundary. return 0. - EXPECT_EQ(0, IntLog2Ceil(1)); - EXPECT_EQ(1, IntLog2Ceil(2)); - EXPECT_EQ(64, IntLog2Ceil(~kZero)); - - // A boundary case: Converting 0xffffffffffffffff requires > 53 - // bits of precision, so the conversion to double rounds up, - // and the result of std::log2(x) > IntLog2Floor(x). - EXPECT_LE(IntLog2Ceil(~kZero), static_cast<int>(std::log2(~kZero))); - - for (int i = 0; i < 64; i++) { - const uint64_t i_pow_2 = static_cast<uint64_t>(1) << i; - EXPECT_EQ(i, IntLog2Ceil(i_pow_2)); -#ifndef ABSL_RANDOM_INACCURATE_LOG2 - EXPECT_EQ(i, static_cast<int>(std::ceil(std::log2(i_pow_2)))); -#endif - - uint64_t y = i_pow_2; - for (int j = i - 1; j > 0; --j) { - y = y | (i_pow_2 >> j); - EXPECT_EQ(i + 1, IntLog2Ceil(y)); - } - } -} - -TEST(FastMathTest, StirlingLogFactorial) { - using absl::random_internal::StirlingLogFactorial; - - EXPECT_NEAR(StirlingLogFactorial(1.0), 0, 1e-3); - EXPECT_NEAR(StirlingLogFactorial(1.50), 0.284683, 1e-3); - EXPECT_NEAR(StirlingLogFactorial(2.0), 0.69314718056, 1e-4); - - for (int i = 2; i < 50; i++) { - double d = static_cast<double>(i); - EXPECT_NEAR(StirlingLogFactorial(d), std::lgamma(d + 1), 3e-5); - } -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/gaussian_distribution_gentables.cc b/third_party/abseil_cpp/absl/random/internal/gaussian_distribution_gentables.cc deleted file mode 100644 index a95333d55f55..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/gaussian_distribution_gentables.cc +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Generates gaussian_distribution.cc -// -// $ blaze run :gaussian_distribution_gentables > gaussian_distribution.cc -// -#include "absl/random/gaussian_distribution.h" - -#include <cmath> -#include <cstddef> -#include <iostream> -#include <limits> -#include <string> - -#include "absl/base/macros.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -template <typename T, size_t N> -void FormatArrayContents(std::ostream* os, T (&data)[N]) { - if (!std::numeric_limits<T>::is_exact) { - // Note: T is either an integer or a float. - // float requires higher precision to ensure that values are - // reproduced exactly. - // Trivia: C99 has hexadecimal floating point literals, but C++11 does not. - // Using them would remove all concern of precision loss. - os->precision(std::numeric_limits<T>::max_digits10 + 2); - } - *os << " {"; - std::string separator = ""; - for (size_t i = 0; i < N; ++i) { - *os << separator << data[i]; - if ((i + 1) % 3 != 0) { - separator = ", "; - } else { - separator = ",\n "; - } - } - *os << "}"; -} - -} // namespace - -class TableGenerator : public gaussian_distribution_base { - public: - TableGenerator(); - void Print(std::ostream* os); - - using gaussian_distribution_base::kMask; - using gaussian_distribution_base::kR; - using gaussian_distribution_base::kV; - - private: - Tables tables_; -}; - -// Ziggurat gaussian initialization. For an explanation of the algorithm, see -// the Marsaglia paper, "The Ziggurat Method for Generating Random Variables". -// http://www.jstatsoft.org/v05/i08/ -// -// Further details are available in the Doornik paper -// https://www.doornik.com/research/ziggurat.pdf -// -TableGenerator::TableGenerator() { - // The constants here should match the values in gaussian_distribution.h - static constexpr int kC = kMask + 1; - - static_assert((ABSL_ARRAYSIZE(tables_.x) == kC + 1), - "xArray must be length kMask + 2"); - - static_assert((ABSL_ARRAYSIZE(tables_.x) == ABSL_ARRAYSIZE(tables_.f)), - "fx and x arrays must be identical length"); - - auto f = [](double x) { return std::exp(-0.5 * x * x); }; - auto f_inv = [](double x) { return std::sqrt(-2.0 * std::log(x)); }; - - tables_.x[0] = kV / f(kR); - tables_.f[0] = f(tables_.x[0]); - - tables_.x[1] = kR; - tables_.f[1] = f(tables_.x[1]); - - tables_.x[kC] = 0.0; - tables_.f[kC] = f(tables_.x[kC]); // 1.0 - - for (int i = 2; i < kC; i++) { - double v = (kV / tables_.x[i - 1]) + tables_.f[i - 1]; - tables_.x[i] = f_inv(v); - tables_.f[i] = v; - } -} - -void TableGenerator::Print(std::ostream* os) { - *os << "// BEGIN GENERATED CODE; DO NOT EDIT\n" - "// clang-format off\n" - "\n" - "#include \"absl/random/gaussian_distribution.h\"\n" - "\n" - "namespace absl {\n" - "ABSL_NAMESPACE_BEGIN\n" - "namespace random_internal {\n" - "\n" - "const gaussian_distribution_base::Tables\n" - " gaussian_distribution_base::zg_ = {\n"; - FormatArrayContents(os, tables_.x); - *os << ",\n"; - FormatArrayContents(os, tables_.f); - *os << "};\n" - "\n" - "} // namespace random_internal\n" - "ABSL_NAMESPACE_END\n" - "} // namespace absl\n" - "\n" - "// clang-format on\n" - "// END GENERATED CODE"; - *os << std::endl; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -int main(int, char**) { - std::cerr << "\nCopy the output to gaussian_distribution.cc" << std::endl; - absl::random_internal::TableGenerator generator; - generator.Print(&std::cout); - return 0; -} diff --git a/third_party/abseil_cpp/absl/random/internal/generate_real.h b/third_party/abseil_cpp/absl/random/internal/generate_real.h deleted file mode 100644 index 20f6d20807d5..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/generate_real.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ -#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ - -// This file contains some implementation details which are used by one or more -// of the absl random number distributions. - -#include <cstdint> -#include <cstring> -#include <limits> -#include <type_traits> - -#include "absl/base/internal/bits.h" -#include "absl/meta/type_traits.h" -#include "absl/random/internal/fastmath.h" -#include "absl/random/internal/traits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Tristate tag types controlling the output of GenerateRealFromBits. -struct GeneratePositiveTag {}; -struct GenerateNegativeTag {}; -struct GenerateSignedTag {}; - -// GenerateRealFromBits generates a single real value from a single 64-bit -// `bits` with template fields controlling the output. -// -// The `SignedTag` parameter controls whether positive, negative, -// or either signed/unsigned may be returned. -// When SignedTag == GeneratePositiveTag, range is U(0, 1) -// When SignedTag == GenerateNegativeTag, range is U(-1, 0) -// When SignedTag == GenerateSignedTag, range is U(-1, 1) -// -// When the `IncludeZero` parameter is true, the function may return 0 for some -// inputs, otherwise it never returns 0. -// -// When a value in U(0,1) is required, use: -// Uniform64ToReal<double, PositiveValueT, true>; -// -// When a value in U(-1,1) is required, use: -// Uniform64ToReal<double, SignedValueT, false>; -// -// This generates more distinct values than the mathematical equivalent -// `U(0, 1) * 2.0 - 1.0`. -// -// Scaling the result by powers of 2 (and avoiding a multiply) is also possible: -// GenerateRealFromBits<double>(..., -1); => U(0, 0.5) -// GenerateRealFromBits<double>(..., 1); => U(0, 2) -// -template <typename RealType, // Real type, either float or double. - typename SignedTag = GeneratePositiveTag, // Whether a positive, - // negative, or signed - // value is generated. - bool IncludeZero = true> -inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { - using real_type = RealType; - using uint_type = absl::conditional_t<std::is_same<real_type, float>::value, - uint32_t, uint64_t>; - - static_assert( - (std::is_same<double, real_type>::value || - std::is_same<float, real_type>::value), - "GenerateRealFromBits must be parameterized by either float or double."); - - static_assert(sizeof(uint_type) == sizeof(real_type), - "Mismatched unsinged and real types."); - - static_assert((std::numeric_limits<real_type>::is_iec559 && - std::numeric_limits<real_type>::radix == 2), - "RealType representation is not IEEE 754 binary."); - - static_assert((std::is_same<SignedTag, GeneratePositiveTag>::value || - std::is_same<SignedTag, GenerateNegativeTag>::value || - std::is_same<SignedTag, GenerateSignedTag>::value), - ""); - - static constexpr int kExp = std::numeric_limits<real_type>::digits - 1; - static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u; - static constexpr int kUintBits = sizeof(uint_type) * 8; - - int exp = exp_bias + int{std::numeric_limits<real_type>::max_exponent - 2}; - - // Determine the sign bit. - // Depending on the SignedTag, this may use the left-most bit - // or it may be a constant value. - uint_type sign = std::is_same<SignedTag, GenerateNegativeTag>::value - ? (static_cast<uint_type>(1) << (kUintBits - 1)) - : 0; - if (std::is_same<SignedTag, GenerateSignedTag>::value) { - if (std::is_same<uint_type, uint64_t>::value) { - sign = bits & uint64_t{0x8000000000000000}; - } - if (std::is_same<uint_type, uint32_t>::value) { - const uint64_t tmp = bits & uint64_t{0x8000000000000000}; - sign = static_cast<uint32_t>(tmp >> 32); - } - // adjust the bits and the exponent to account for removing - // the leading bit. - bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF}; - exp++; - } - if (IncludeZero) { - if (bits == 0u) return 0; - } - - // Number of leading zeros is mapped to the exponent: 2^-clz - // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0 - int clz = base_internal::CountLeadingZeros64(bits); - bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits. - exp -= clz; // set the exponent. - bits >>= (63 - kExp); - - // Construct the 32-bit or 64-bit IEEE 754 floating-point value from - // the individual fields: sign, exp, mantissa(bits). - uint_type val = - (std::is_same<SignedTag, GeneratePositiveTag>::value ? 0u : sign) | - (static_cast<uint_type>(exp) << kExp) | - (static_cast<uint_type>(bits) & kMask); - - // bit_cast to the output-type - real_type result; - memcpy(static_cast<void*>(&result), static_cast<const void*>(&val), - sizeof(result)); - return result; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/generate_real_test.cc b/third_party/abseil_cpp/absl/random/internal/generate_real_test.cc deleted file mode 100644 index 4bdc453483e4..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/generate_real_test.cc +++ /dev/null @@ -1,497 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/generate_real.h" - -#include <cfloat> -#include <cstddef> -#include <cstdint> -#include <string> - -#include "gtest/gtest.h" -#include "absl/base/internal/bits.h" -#include "absl/flags/flag.h" - -ABSL_FLAG(int64_t, absl_random_test_trials, 50000, - "Number of trials for the probability tests."); - -using absl::random_internal::GenerateNegativeTag; -using absl::random_internal::GeneratePositiveTag; -using absl::random_internal::GenerateRealFromBits; -using absl::random_internal::GenerateSignedTag; - -namespace { - -TEST(GenerateRealTest, U64ToFloat_Positive_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GeneratePositiveTag, false>(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 2.710505431e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); - EXPECT_EQ(ToFloat(0x8000000000000001), 0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloat_Positive_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GeneratePositiveTag, true>(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); - EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); - EXPECT_EQ(ToFloat(0x8000000000000001), 0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloat_Negative_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GenerateNegativeTag, false>(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), -2.710505431e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); - EXPECT_EQ(ToFloat(0x8000000000000001), -0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloat_Negative_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GenerateNegativeTag, true>(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); - EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); - EXPECT_EQ(ToFloat(0x8000000000000001), -0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloat_Signed_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GenerateSignedTag, false>(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloat_Signed_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GenerateSignedTag, true>(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0); - EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0); - EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloat_Signed_Bias_Test) { - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GenerateSignedTag, true>(a, 1); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0); - EXPECT_EQ(ToFloat(0x0000000000000001), 2 * 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 2 * 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0); - EXPECT_EQ(ToFloat(0x8000000000000001), 2 * -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 2 * -0.9999999404f); -} - -TEST(GenerateRealTest, U64ToFloatTest) { - auto ToFloat = [](uint64_t a) -> float { - return GenerateRealFromBits<float, GeneratePositiveTag, true>(a); - }; - - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0f); - - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5f); - EXPECT_EQ(ToFloat(0x8000000000000001), 0.5f); - EXPECT_EQ(ToFloat(0x800000FFFFFFFFFF), 0.5f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); - - EXPECT_GT(ToFloat(0x0000000000000001), 0.0f); - - EXPECT_NE(ToFloat(0x7FFFFF0000000000), ToFloat(0x7FFFFEFFFFFFFFFF)); - - EXPECT_LT(ToFloat(0xFFFFFFFFFFFFFFFF), 1.0f); - int32_t two_to_24 = 1 << 24; - EXPECT_EQ(static_cast<int32_t>(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24), - two_to_24 - 1); - EXPECT_NE(static_cast<int32_t>(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24 * 2), - two_to_24 * 2 - 1); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFF0000000000)); - EXPECT_NE(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFEFFFFFFFFFF)); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF8000000000)); - EXPECT_NE(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF7FFFFFFFFF)); - EXPECT_EQ(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFC000000000)); - EXPECT_NE(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFBFFFFFFFFF)); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 0; i < 100; ++i) { - EXPECT_EQ(i * ToFloat(0x0000000000000001), ToFloat(i)); - } - - // For each i: value generated from (1 << i). - float exp_values[64]; - exp_values[63] = 0.5f; - for (int i = 62; i >= 0; --i) exp_values[i] = 0.5f * exp_values[i + 1]; - constexpr uint64_t one = 1; - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(ToFloat(one << i), exp_values[i]); - for (int j = 1; j < FLT_MANT_DIG && i - j >= 0; ++j) { - EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), - exp_values[i] + exp_values[i - j]); - } - for (int j = FLT_MANT_DIG; i - j >= 0; ++j) { - EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), exp_values[i]); - } - } -} - -TEST(GenerateRealTest, U64ToDouble_Positive_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GeneratePositiveTag, false>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 2.710505431213761085e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); -} - -TEST(GenerateRealTest, U64ToDouble_Positive_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GeneratePositiveTag, true>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); -} - -TEST(GenerateRealTest, U64ToDouble_Negative_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GenerateNegativeTag, false>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), -2.710505431213761085e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); - EXPECT_EQ(ToDouble(0x8000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(GenerateRealTest, U64ToDouble_Negative_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GenerateNegativeTag, true>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); - EXPECT_EQ(ToDouble(0x8000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(GenerateRealTest, U64ToDouble_Signed_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GenerateSignedTag, false>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(GenerateRealTest, U64ToDouble_Signed_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GenerateSignedTag, true>(a); - }; - EXPECT_EQ(ToDouble(0x0000000000000000), 0); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0x8000000000000000), 0); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(GenerateRealTest, U64ToDouble_GenerateSignedTag_Bias_Test) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GenerateSignedTag, true>(a, -1); - }; - EXPECT_EQ(ToDouble(0x0000000000000000), 0); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19 / 2); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978 / 2); - EXPECT_EQ(ToDouble(0x8000000000000000), 0); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19 / 2); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978 / 2); -} - -TEST(GenerateRealTest, U64ToDoubleTest) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GeneratePositiveTag, true>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x7fffffffffffffef), 0.499999999999999944489); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - - // For values > 0.5, RandU64ToDouble discards up to 11 bits. (64-53). - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x80000000000007FF), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); - - EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFF), 1.0); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF800)); - EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF7FF)); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFBFF)); - EXPECT_EQ(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFE00)); - EXPECT_NE(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFDFF)); - - EXPECT_EQ(ToDouble(0x1000000000000001), 0.0625); - EXPECT_EQ(ToDouble(0x2000000000000001), 0.125); - EXPECT_EQ(ToDouble(0x3000000000000001), 0.1875); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.25); - EXPECT_EQ(ToDouble(0x5000000000000001), 0.3125); - EXPECT_EQ(ToDouble(0x6000000000000001), 0.375); - EXPECT_EQ(ToDouble(0x7000000000000001), 0.4375); - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x9000000000000001), 0.5625); - EXPECT_EQ(ToDouble(0xa000000000000001), 0.625); - EXPECT_EQ(ToDouble(0xb000000000000001), 0.6875); - EXPECT_EQ(ToDouble(0xc000000000000001), 0.75); - EXPECT_EQ(ToDouble(0xd000000000000001), 0.8125); - EXPECT_EQ(ToDouble(0xe000000000000001), 0.875); - EXPECT_EQ(ToDouble(0xf000000000000001), 0.9375); - - // Large powers of 2. - int64_t two_to_53 = int64_t{1} << 53; - EXPECT_EQ(static_cast<int64_t>(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), - two_to_53 - 1); - EXPECT_NE(static_cast<int64_t>(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53 * 2), - two_to_53 * 2 - 1); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 0; i < 100; ++i) { - EXPECT_EQ(i * ToDouble(0x0000000000000001), ToDouble(i)); - } - - // For each i: value generated from (1 << i). - double exp_values[64]; - exp_values[63] = 0.5; - for (int i = 62; i >= 0; --i) exp_values[i] = 0.5 * exp_values[i + 1]; - constexpr uint64_t one = 1; - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(ToDouble(one << i), exp_values[i]); - for (int j = 1; j < DBL_MANT_DIG && i - j >= 0; ++j) { - EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), - exp_values[i] + exp_values[i - j]); - } - for (int j = DBL_MANT_DIG; i - j >= 0; ++j) { - EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), exp_values[i]); - } - } -} - -TEST(GenerateRealTest, U64ToDoubleSignedTest) { - auto ToDouble = [](uint64_t a) { - return GenerateRealFromBits<double, GenerateSignedTag, false>(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - - EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - - const double e_plus = ToDouble(0x0000000000000001); - const double e_minus = ToDouble(0x8000000000000001); - EXPECT_EQ(e_plus, 1.084202172485504434e-19); - EXPECT_EQ(e_minus, -1.084202172485504434e-19); - - EXPECT_EQ(ToDouble(0x3fffffffffffffef), 0.499999999999999944489); - EXPECT_EQ(ToDouble(0xbfffffffffffffef), -0.499999999999999944489); - - // For values > 0.5, RandU64ToDouble discards up to 10 bits. (63-53). - EXPECT_EQ(ToDouble(0x4000000000000000), 0.5); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x40000000000003FF), 0.5); - - EXPECT_EQ(ToDouble(0xC000000000000000), -0.5); - EXPECT_EQ(ToDouble(0xC000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xC0000000000003FF), -0.5); - - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFe), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999999999888978); - - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); - - EXPECT_LT(ToDouble(0x7FFFFFFFFFFFFFFF), 1.0); - EXPECT_GT(ToDouble(0x7FFFFFFFFFFFFFFF), 0.9999999999); - - EXPECT_GT(ToDouble(0xFFFFFFFFFFFFFFFe), -1.0); - EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999); - - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFFC00)); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); - EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFF3FF)); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFF3FF)); - - EXPECT_EQ(ToDouble(0x1000000000000001), 0.125); - EXPECT_EQ(ToDouble(0x2000000000000001), 0.25); - EXPECT_EQ(ToDouble(0x3000000000000001), 0.375); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x5000000000000001), 0.625); - EXPECT_EQ(ToDouble(0x6000000000000001), 0.75); - EXPECT_EQ(ToDouble(0x7000000000000001), 0.875); - EXPECT_EQ(ToDouble(0x7800000000000001), 0.9375); - EXPECT_EQ(ToDouble(0x7c00000000000001), 0.96875); - EXPECT_EQ(ToDouble(0x7e00000000000001), 0.984375); - EXPECT_EQ(ToDouble(0x7f00000000000001), 0.9921875); - - // 0x8000000000000000 ~= 0 - EXPECT_EQ(ToDouble(0x9000000000000001), -0.125); - EXPECT_EQ(ToDouble(0xa000000000000001), -0.25); - EXPECT_EQ(ToDouble(0xb000000000000001), -0.375); - EXPECT_EQ(ToDouble(0xc000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xd000000000000001), -0.625); - EXPECT_EQ(ToDouble(0xe000000000000001), -0.75); - EXPECT_EQ(ToDouble(0xf000000000000001), -0.875); - - // Large powers of 2. - int64_t two_to_53 = int64_t{1} << 53; - EXPECT_EQ(static_cast<int64_t>(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53), - two_to_53 - 1); - EXPECT_EQ(static_cast<int64_t>(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), - -(two_to_53 - 1)); - - EXPECT_NE(static_cast<int64_t>(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53 * 2), - two_to_53 * 2 - 1); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 1; i < 100; ++i) { - EXPECT_EQ(i * e_plus, ToDouble(i)) << i; - EXPECT_EQ(i * e_minus, ToDouble(0x8000000000000000 | i)) << i; - } -} - -TEST(GenerateRealTest, ExhaustiveFloat) { - using absl::base_internal::CountLeadingZeros64; - auto ToFloat = [](uint64_t a) { - return GenerateRealFromBits<float, GeneratePositiveTag, true>(a); - }; - - // Rely on RandU64ToFloat generating values from greatest to least when - // supplied with uint64_t values from greatest (0xfff...) to least (0x0). - // Thus, this algorithm stores the previous value, and if the new value is at - // greater than or equal to the previous value, then there is a collision in - // the generation algorithm. - // - // Use the computation below to convert the random value into a result: - // double res = a() * (1.0f - sample) + b() * sample; - float last_f = 1.0, last_g = 2.0; - uint64_t f_collisions = 0, g_collisions = 0; - uint64_t f_unique = 0, g_unique = 0; - uint64_t total = 0; - auto count = [&](const float r) { - total++; - // `f` is mapped to the range [0, 1) (default) - const float f = 0.0f * (1.0f - r) + 1.0f * r; - if (f >= last_f) { - f_collisions++; - } else { - f_unique++; - last_f = f; - } - // `g` is mapped to the range [1, 2) - const float g = 1.0f * (1.0f - r) + 2.0f * r; - if (g >= last_g) { - g_collisions++; - } else { - g_unique++; - last_g = g; - } - }; - - size_t limit = absl::GetFlag(FLAGS_absl_random_test_trials); - - // Generate all uint64_t which have unique floating point values. - // Counting down from 0xFFFFFFFFFFFFFFFFu ... 0x0u - uint64_t x = ~uint64_t(0); - for (; x != 0 && limit > 0;) { - constexpr int kDig = (64 - FLT_MANT_DIG); - // Set a decrement value & the next point at which to change - // the decrement value. By default these are 1, 0. - uint64_t dec = 1; - uint64_t chk = 0; - - // Adjust decrement and check value based on how many leading 0 - // bits are set in the current value. - const int clz = CountLeadingZeros64(x); - if (clz < kDig) { - dec <<= (kDig - clz); - chk = (~uint64_t(0)) >> (clz + 1); - } - for (; x > chk && limit > 0; x -= dec) { - count(ToFloat(x)); - --limit; - } - } - - static_assert(FLT_MANT_DIG == 24, - "The float type is expected to have a 24 bit mantissa."); - - if (limit != 0) { - // There are between 2^28 and 2^29 unique values in the range [0, 1). For - // the low values of x, there are 2^24 -1 unique values. Once x > 2^24, - // there are 40 * 2^24 unique values. Thus: - // (2 + 4 + 8 ... + 2^23) + 40 * 2^23 - EXPECT_LT(1 << 28, f_unique); - EXPECT_EQ((1 << 24) + 40 * (1 << 23) - 1, f_unique); - EXPECT_EQ(total, f_unique); - EXPECT_EQ(0, f_collisions); - - // Expect at least 2^23 unique values for the range [1, 2) - EXPECT_LE(1 << 23, g_unique); - EXPECT_EQ(total - g_unique, g_collisions); - } -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/iostream_state_saver.h b/third_party/abseil_cpp/absl/random/internal/iostream_state_saver.h deleted file mode 100644 index e6e242ee1e66..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/iostream_state_saver.h +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_ -#define ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_ - -#include <cmath> -#include <iostream> -#include <limits> -#include <type_traits> - -#include "absl/meta/type_traits.h" -#include "absl/numeric/int128.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// The null_state_saver does nothing. -template <typename T> -class null_state_saver { - public: - using stream_type = T; - using flags_type = std::ios_base::fmtflags; - - null_state_saver(T&, flags_type) {} - ~null_state_saver() {} -}; - -// ostream_state_saver is a RAII object to save and restore the common -// basic_ostream flags used when implementing `operator <<()` on any of -// the absl random distributions. -template <typename OStream> -class ostream_state_saver { - public: - using ostream_type = OStream; - using flags_type = std::ios_base::fmtflags; - using fill_type = typename ostream_type::char_type; - using precision_type = std::streamsize; - - ostream_state_saver(ostream_type& os, // NOLINT(runtime/references) - flags_type flags, fill_type fill) - : os_(os), - flags_(os.flags(flags)), - fill_(os.fill(fill)), - precision_(os.precision()) { - // Save state in initialized variables. - } - - ~ostream_state_saver() { - // Restore saved state. - os_.precision(precision_); - os_.fill(fill_); - os_.flags(flags_); - } - - private: - ostream_type& os_; - const flags_type flags_; - const fill_type fill_; - const precision_type precision_; -}; - -#if defined(__NDK_MAJOR__) && __NDK_MAJOR__ < 16 -#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 1 -#else -#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 0 -#endif - -template <typename CharT, typename Traits> -ostream_state_saver<std::basic_ostream<CharT, Traits>> make_ostream_state_saver( - std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references) - std::ios_base::fmtflags flags = std::ios_base::dec | std::ios_base::left | -#if ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT - std::ios_base::fixed | -#endif - std::ios_base::scientific) { - using result_type = ostream_state_saver<std::basic_ostream<CharT, Traits>>; - return result_type(os, flags, os.widen(' ')); -} - -template <typename T> -typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value, - null_state_saver<T>> -make_ostream_state_saver(T& is, // NOLINT(runtime/references) - std::ios_base::fmtflags flags = std::ios_base::dec) { - std::cerr << "null_state_saver"; - using result_type = null_state_saver<T>; - return result_type(is, flags); -} - -// stream_precision_helper<type>::kPrecision returns the base 10 precision -// required to stream and reconstruct a real type exact binary value through -// a binary->decimal->binary transition. -template <typename T> -struct stream_precision_helper { - // max_digits10 may be 0 on MSVC; if so, use digits10 + 3. - static constexpr int kPrecision = - (std::numeric_limits<T>::max_digits10 > std::numeric_limits<T>::digits10) - ? std::numeric_limits<T>::max_digits10 - : (std::numeric_limits<T>::digits10 + 3); -}; - -template <> -struct stream_precision_helper<float> { - static constexpr int kPrecision = 9; -}; -template <> -struct stream_precision_helper<double> { - static constexpr int kPrecision = 17; -}; -template <> -struct stream_precision_helper<long double> { - static constexpr int kPrecision = 36; // assuming fp128 -}; - -// istream_state_saver is a RAII object to save and restore the common -// std::basic_istream<> flags used when implementing `operator >>()` on any of -// the absl random distributions. -template <typename IStream> -class istream_state_saver { - public: - using istream_type = IStream; - using flags_type = std::ios_base::fmtflags; - - istream_state_saver(istream_type& is, // NOLINT(runtime/references) - flags_type flags) - : is_(is), flags_(is.flags(flags)) {} - - ~istream_state_saver() { is_.flags(flags_); } - - private: - istream_type& is_; - flags_type flags_; -}; - -template <typename CharT, typename Traits> -istream_state_saver<std::basic_istream<CharT, Traits>> make_istream_state_saver( - std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references) - std::ios_base::fmtflags flags = std::ios_base::dec | - std::ios_base::scientific | - std::ios_base::skipws) { - using result_type = istream_state_saver<std::basic_istream<CharT, Traits>>; - return result_type(is, flags); -} - -template <typename T> -typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value, - null_state_saver<T>> -make_istream_state_saver(T& is, // NOLINT(runtime/references) - std::ios_base::fmtflags flags = std::ios_base::dec) { - using result_type = null_state_saver<T>; - return result_type(is, flags); -} - -// stream_format_type<T> is a helper struct to convert types which -// basic_iostream cannot output as decimal numbers into types which -// basic_iostream can output as decimal numbers. Specifically: -// * signed/unsigned char-width types are converted to int. -// * TODO(lar): __int128 => uint128, except there is no operator << yet. -// -template <typename T> -struct stream_format_type - : public std::conditional<(sizeof(T) == sizeof(char)), int, T> {}; - -// stream_u128_helper allows us to write out either absl::uint128 or -// __uint128_t types in the same way, which enables their use as internal -// state of PRNG engines. -template <typename T> -struct stream_u128_helper; - -template <> -struct stream_u128_helper<absl::uint128> { - template <typename IStream> - inline absl::uint128 read(IStream& in) { - uint64_t h = 0; - uint64_t l = 0; - in >> h >> l; - return absl::MakeUint128(h, l); - } - - template <typename OStream> - inline void write(absl::uint128 val, OStream& out) { - uint64_t h = absl::Uint128High64(val); - uint64_t l = absl::Uint128Low64(val); - out << h << out.fill() << l; - } -}; - -#ifdef ABSL_HAVE_INTRINSIC_INT128 -template <> -struct stream_u128_helper<__uint128_t> { - template <typename IStream> - inline __uint128_t read(IStream& in) { - uint64_t h = 0; - uint64_t l = 0; - in >> h >> l; - return (static_cast<__uint128_t>(h) << 64) | l; - } - - template <typename OStream> - inline void write(__uint128_t val, OStream& out) { - uint64_t h = static_cast<uint64_t>(val >> 64u); - uint64_t l = static_cast<uint64_t>(val); - out << h << out.fill() << l; - } -}; -#endif - -template <typename FloatType, typename IStream> -inline FloatType read_floating_point(IStream& is) { - static_assert(std::is_floating_point<FloatType>::value, ""); - FloatType dest; - is >> dest; - // Parsing a double value may report a subnormal value as an error - // despite being able to represent it. - // See https://stackoverflow.com/q/52410931/3286653 - // It may also report an underflow when parsing DOUBLE_MIN as an - // ERANGE error, as the parsed value may be smaller than DOUBLE_MIN - // and rounded up. - // See: https://stackoverflow.com/q/42005462 - if (is.fail() && - (std::fabs(dest) == (std::numeric_limits<FloatType>::min)() || - std::fpclassify(dest) == FP_SUBNORMAL)) { - is.clear(is.rdstate() & (~std::ios_base::failbit)); - } - return dest; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/iostream_state_saver_test.cc b/third_party/abseil_cpp/absl/random/internal/iostream_state_saver_test.cc deleted file mode 100644 index 7bb8ad959cf6..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/iostream_state_saver_test.cc +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/iostream_state_saver.h" - -#include <sstream> -#include <string> - -#include "gtest/gtest.h" - -namespace { - -using absl::random_internal::make_istream_state_saver; -using absl::random_internal::make_ostream_state_saver; -using absl::random_internal::stream_precision_helper; - -template <typename T> -typename absl::enable_if_t<std::is_integral<T>::value, T> // -StreamRoundTrip(T t) { - std::stringstream ss; - { - auto saver = make_ostream_state_saver(ss); - ss.precision(stream_precision_helper<T>::kPrecision); - ss << t; - } - T result = 0; - { - auto saver = make_istream_state_saver(ss); - ss >> result; - } - EXPECT_FALSE(ss.fail()) // - << ss.str() << " " // - << (ss.good() ? "good " : "") // - << (ss.bad() ? "bad " : "") // - << (ss.eof() ? "eof " : "") // - << (ss.fail() ? "fail " : ""); - - return result; -} - -template <typename T> -typename absl::enable_if_t<std::is_floating_point<T>::value, T> // -StreamRoundTrip(T t) { - std::stringstream ss; - { - auto saver = make_ostream_state_saver(ss); - ss.precision(stream_precision_helper<T>::kPrecision); - ss << t; - } - T result = 0; - { - auto saver = make_istream_state_saver(ss); - result = absl::random_internal::read_floating_point<T>(ss); - } - EXPECT_FALSE(ss.fail()) // - << ss.str() << " " // - << (ss.good() ? "good " : "") // - << (ss.bad() ? "bad " : "") // - << (ss.eof() ? "eof " : "") // - << (ss.fail() ? "fail " : ""); - - return result; -} - -TEST(IOStreamStateSaver, BasicSaverState) { - std::stringstream ss; - ss.precision(2); - ss.fill('x'); - ss.flags(std::ios_base::dec | std::ios_base::right); - - { - auto saver = make_ostream_state_saver(ss); - ss.precision(10); - EXPECT_NE('x', ss.fill()); - EXPECT_EQ(10, ss.precision()); - EXPECT_NE(std::ios_base::dec | std::ios_base::right, ss.flags()); - - ss << 1.23; - } - - EXPECT_EQ('x', ss.fill()); - EXPECT_EQ(2, ss.precision()); - EXPECT_EQ(std::ios_base::dec | std::ios_base::right, ss.flags()); -} - -TEST(IOStreamStateSaver, RoundTripInts) { - const uint64_t kUintValues[] = { - 0, - 1, - static_cast<uint64_t>(-1), - 2, - static_cast<uint64_t>(-2), - - 1 << 7, - 1 << 8, - 1 << 16, - 1ull << 32, - 1ull << 50, - 1ull << 62, - 1ull << 63, - - (1 << 7) - 1, - (1 << 8) - 1, - (1 << 16) - 1, - (1ull << 32) - 1, - (1ull << 50) - 1, - (1ull << 62) - 1, - (1ull << 63) - 1, - - static_cast<uint64_t>(-(1 << 8)), - static_cast<uint64_t>(-(1 << 16)), - static_cast<uint64_t>(-(1ll << 32)), - static_cast<uint64_t>(-(1ll << 50)), - static_cast<uint64_t>(-(1ll << 62)), - - static_cast<uint64_t>(-(1 << 8) - 1), - static_cast<uint64_t>(-(1 << 16) - 1), - static_cast<uint64_t>(-(1ll << 32) - 1), - static_cast<uint64_t>(-(1ll << 50) - 1), - static_cast<uint64_t>(-(1ll << 62) - 1), - }; - - for (const uint64_t u : kUintValues) { - EXPECT_EQ(u, StreamRoundTrip<uint64_t>(u)); - - int64_t x = static_cast<int64_t>(u); - EXPECT_EQ(x, StreamRoundTrip<int64_t>(x)); - - double d = static_cast<double>(x); - EXPECT_EQ(d, StreamRoundTrip<double>(d)); - - float f = d; - EXPECT_EQ(f, StreamRoundTrip<float>(f)); - } -} - -TEST(IOStreamStateSaver, RoundTripFloats) { - static_assert( - stream_precision_helper<float>::kPrecision >= 9, - "stream_precision_helper<float>::kPrecision should be at least 9"); - - const float kValues[] = { - 1, - std::nextafter(1.0f, 0.0f), // 1 - epsilon - std::nextafter(1.0f, 2.0f), // 1 + epsilon - - 1.0e+1f, - 1.0e-1f, - 1.0e+2f, - 1.0e-2f, - 1.0e+10f, - 1.0e-10f, - - 0.00000051110000111311111111f, - -0.00000051110000111211111111f, - - 1.234678912345678912345e+6f, - 1.234678912345678912345e-6f, - 1.234678912345678912345e+30f, - 1.234678912345678912345e-30f, - 1.234678912345678912345e+38f, - 1.0234678912345678912345e-38f, - - // Boundary cases. - std::numeric_limits<float>::max(), - std::numeric_limits<float>::lowest(), - std::numeric_limits<float>::epsilon(), - std::nextafter(std::numeric_limits<float>::min(), - 1.0f), // min + epsilon - std::numeric_limits<float>::min(), // smallest normal - // There are some errors dealing with denorms on apple platforms. - std::numeric_limits<float>::denorm_min(), // smallest denorm - std::numeric_limits<float>::min() / 2, - std::nextafter(std::numeric_limits<float>::min(), - 0.0f), // denorm_max - std::nextafter(std::numeric_limits<float>::denorm_min(), 1.0f), - }; - - for (const float f : kValues) { - EXPECT_EQ(f, StreamRoundTrip<float>(f)); - EXPECT_EQ(-f, StreamRoundTrip<float>(-f)); - - double d = f; - EXPECT_EQ(d, StreamRoundTrip<double>(d)); - EXPECT_EQ(-d, StreamRoundTrip<double>(-d)); - - // Avoid undefined behavior (overflow/underflow). - if (f <= static_cast<float>(std::numeric_limits<int64_t>::max()) && - f >= static_cast<float>(std::numeric_limits<int64_t>::lowest())) { - int64_t x = static_cast<int64_t>(f); - EXPECT_EQ(x, StreamRoundTrip<int64_t>(x)); - } - } -} - -TEST(IOStreamStateSaver, RoundTripDoubles) { - static_assert( - stream_precision_helper<double>::kPrecision >= 17, - "stream_precision_helper<double>::kPrecision should be at least 17"); - - const double kValues[] = { - 1, - std::nextafter(1.0, 0.0), // 1 - epsilon - std::nextafter(1.0, 2.0), // 1 + epsilon - - 1.0e+1, - 1.0e-1, - 1.0e+2, - 1.0e-2, - 1.0e+10, - 1.0e-10, - - 0.00000051110000111311111111, - -0.00000051110000111211111111, - - 1.234678912345678912345e+6, - 1.234678912345678912345e-6, - 1.234678912345678912345e+30, - 1.234678912345678912345e-30, - 1.234678912345678912345e+38, - 1.0234678912345678912345e-38, - - 1.0e+100, - 1.0e-100, - 1.234678912345678912345e+308, - 1.0234678912345678912345e-308, - 2.22507385850720138e-308, - - // Boundary cases. - std::numeric_limits<double>::max(), - std::numeric_limits<double>::lowest(), - std::numeric_limits<double>::epsilon(), - std::nextafter(std::numeric_limits<double>::min(), - 1.0), // min + epsilon - std::numeric_limits<double>::min(), // smallest normal - // There are some errors dealing with denorms on apple platforms. - std::numeric_limits<double>::denorm_min(), // smallest denorm - std::numeric_limits<double>::min() / 2, - std::nextafter(std::numeric_limits<double>::min(), - 0.0), // denorm_max - std::nextafter(std::numeric_limits<double>::denorm_min(), 1.0f), - }; - - for (const double d : kValues) { - EXPECT_EQ(d, StreamRoundTrip<double>(d)); - EXPECT_EQ(-d, StreamRoundTrip<double>(-d)); - - // Avoid undefined behavior (overflow/underflow). - if (d <= std::numeric_limits<float>::max() && - d >= std::numeric_limits<float>::lowest()) { - float f = static_cast<float>(d); - EXPECT_EQ(f, StreamRoundTrip<float>(f)); - } - - // Avoid undefined behavior (overflow/underflow). - if (d <= static_cast<double>(std::numeric_limits<int64_t>::max()) && - d >= static_cast<double>(std::numeric_limits<int64_t>::lowest())) { - int64_t x = static_cast<int64_t>(d); - EXPECT_EQ(x, StreamRoundTrip<int64_t>(x)); - } - } -} - -#if !defined(__EMSCRIPTEN__) -TEST(IOStreamStateSaver, RoundTripLongDoubles) { - // Technically, C++ only guarantees that long double is at least as large as a - // double. Practically it varies from 64-bits to 128-bits. - // - // So it is best to consider long double a best-effort extended precision - // type. - - static_assert( - stream_precision_helper<long double>::kPrecision >= 36, - "stream_precision_helper<long double>::kPrecision should be at least 36"); - - using real_type = long double; - const real_type kValues[] = { - 1, - std::nextafter(1.0, 0.0), // 1 - epsilon - std::nextafter(1.0, 2.0), // 1 + epsilon - - 1.0e+1, - 1.0e-1, - 1.0e+2, - 1.0e-2, - 1.0e+10, - 1.0e-10, - - 0.00000051110000111311111111, - -0.00000051110000111211111111, - - 1.2346789123456789123456789123456789e+6, - 1.2346789123456789123456789123456789e-6, - 1.2346789123456789123456789123456789e+30, - 1.2346789123456789123456789123456789e-30, - 1.2346789123456789123456789123456789e+38, - 1.2346789123456789123456789123456789e-38, - 1.2346789123456789123456789123456789e+308, - 1.2346789123456789123456789123456789e-308, - - 1.0e+100, - 1.0e-100, - 1.234678912345678912345e+308, - 1.0234678912345678912345e-308, - - // Boundary cases. - std::numeric_limits<real_type>::max(), - std::numeric_limits<real_type>::lowest(), - std::numeric_limits<real_type>::epsilon(), - std::nextafter(std::numeric_limits<real_type>::min(), - real_type(1)), // min + epsilon - std::numeric_limits<real_type>::min(), // smallest normal - // There are some errors dealing with denorms on apple platforms. - std::numeric_limits<real_type>::denorm_min(), // smallest denorm - std::numeric_limits<real_type>::min() / 2, - std::nextafter(std::numeric_limits<real_type>::min(), - 0.0), // denorm_max - std::nextafter(std::numeric_limits<real_type>::denorm_min(), 1.0f), - }; - - int index = -1; - for (const long double dd : kValues) { - index++; - EXPECT_EQ(dd, StreamRoundTrip<real_type>(dd)) << index; - EXPECT_EQ(-dd, StreamRoundTrip<real_type>(-dd)) << index; - - // Avoid undefined behavior (overflow/underflow). - if (dd <= std::numeric_limits<double>::max() && - dd >= std::numeric_limits<double>::lowest()) { - double d = static_cast<double>(dd); - EXPECT_EQ(d, StreamRoundTrip<double>(d)); - } - - // Avoid undefined behavior (overflow/underflow). - if (dd <= std::numeric_limits<int64_t>::max() && - dd >= std::numeric_limits<int64_t>::lowest()) { - int64_t x = static_cast<int64_t>(dd); - EXPECT_EQ(x, StreamRoundTrip<int64_t>(x)); - } - } -} -#endif // !defined(__EMSCRIPTEN__) - -TEST(StrToDTest, DoubleMin) { - const char kV[] = "2.22507385850720138e-308"; - char* end; - double x = std::strtod(kV, &end); - EXPECT_EQ(std::numeric_limits<double>::min(), x); - // errno may equal ERANGE. -} - -TEST(StrToDTest, DoubleDenormMin) { - const char kV[] = "4.94065645841246544e-324"; - char* end; - double x = std::strtod(kV, &end); - EXPECT_EQ(std::numeric_limits<double>::denorm_min(), x); - // errno may equal ERANGE. -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/mock_helpers.h b/third_party/abseil_cpp/absl/random/internal/mock_helpers.h deleted file mode 100644 index 9af27ab3a210..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/mock_helpers.h +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ -#define ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ - -#include <tuple> -#include <type_traits> - -#include "absl/base/internal/fast_type_id.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// MockHelpers works in conjunction with MockOverloadSet, MockingBitGen, and -// BitGenRef to enable the mocking capability for absl distribution functions. -// -// MockingBitGen registers mocks based on the typeid of a mock signature, KeyT, -// which is used to generate a unique id. -// -// KeyT is a signature of the form: -// result_type(discriminator_type, std::tuple<args...>) -// The mocked function signature will be composed from KeyT as: -// result_type(args...) -// -class MockHelpers { - using IdType = ::absl::base_internal::FastTypeIdType; - - // Given a key signature type used to index the mock, extract the components. - // KeyT is expected to have the form: - // result_type(discriminator_type, arg_tuple_type) - template <typename KeyT> - struct KeySignature; - - template <typename ResultT, typename DiscriminatorT, typename ArgTupleT> - struct KeySignature<ResultT(DiscriminatorT, ArgTupleT)> { - using result_type = ResultT; - using discriminator_type = DiscriminatorT; - using arg_tuple_type = ArgTupleT; - }; - - // Detector for InvokeMock. - template <class T> - using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( - std::declval<IdType>(), std::declval<void*>(), std::declval<void*>())); - - // Empty implementation of InvokeMock. - template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG, - typename... Args> - static absl::optional<ReturnT> InvokeMockImpl(char, URBG*, Args&&...) { - return absl::nullopt; - } - - // Non-empty implementation of InvokeMock. - template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG, - typename = invoke_mock_t<URBG>, typename... Args> - static absl::optional<ReturnT> InvokeMockImpl(int, URBG* urbg, - Args&&... args) { - ArgTupleT arg_tuple(std::forward<Args>(args)...); - ReturnT result; - if (urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple, - &result)) { - return result; - } - return absl::nullopt; - } - - public: - // Invoke a mock for the KeyT (may or may not be a signature). - // - // KeyT is used to generate a typeid-based lookup key for the mock. - // KeyT is a signature of the form: - // result_type(discriminator_type, std::tuple<args...>) - // The mocked function signature will be composed from KeyT as: - // result_type(args...) - // - // An instance of arg_tuple_type must be constructable from Args..., since - // the underlying mechanism requires a pointer to an argument tuple. - template <typename KeyT, typename URBG, typename... Args> - static auto MaybeInvokeMock(URBG* urbg, Args&&... args) - -> absl::optional<typename KeySignature<KeyT>::result_type> { - // Use function overloading to dispatch to the implemenation since - // more modern patterns (e.g. require + constexpr) are not supported in all - // compiler configurations. - return InvokeMockImpl<KeyT, typename KeySignature<KeyT>::result_type, - typename KeySignature<KeyT>::arg_tuple_type, URBG>( - 0, urbg, std::forward<Args>(args)...); - } - - // Acquire a mock for the KeyT (may or may not be a signature). - // - // KeyT is used to generate a typeid-based lookup for the mock. - // KeyT is a signature of the form: - // result_type(discriminator_type, std::tuple<args...>) - // The mocked function signature will be composed from KeyT as: - // result_type(args...) - template <typename KeyT, typename MockURBG> - static auto MockFor(MockURBG& m) -> decltype( - std::declval<MockURBG>() - .template RegisterMock<typename KeySignature<KeyT>::result_type, - typename KeySignature<KeyT>::arg_tuple_type>( - std::declval<IdType>())) { - return m.template RegisterMock<typename KeySignature<KeyT>::result_type, - typename KeySignature<KeyT>::arg_tuple_type>( - ::absl::base_internal::FastTypeId<KeyT>()); - } -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/mock_overload_set.h b/third_party/abseil_cpp/absl/random/internal/mock_overload_set.h deleted file mode 100644 index dccc6cee679c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/mock_overload_set.h +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ -#define ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ - -#include <type_traits> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/random/internal/mock_helpers.h" -#include "absl/random/mocking_bit_gen.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -template <typename DistrT, typename Fn> -struct MockSingleOverload; - -// MockSingleOverload -// -// MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros. -// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to -// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on -// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to -// arguments to MockingBitGen::Register. -// -// The underlying KeyT must match the KeyT constructed by DistributionCaller. -template <typename DistrT, typename Ret, typename... Args> -struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> { - static_assert(std::is_same<typename DistrT::result_type, Ret>::value, - "Overload signature must have return type matching the " - "distribution result_type."); - using KeyT = Ret(DistrT, std::tuple<Args...>); - auto gmock_Call( - absl::MockingBitGen& gen, // NOLINT(google-runtime-references) - const ::testing::Matcher<Args>&... matchers) - -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) { - return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...); - } -}; - -template <typename DistrT, typename Ret, typename Arg, typename... Args> -struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> { - static_assert(std::is_same<typename DistrT::result_type, Ret>::value, - "Overload signature must have return type matching the " - "distribution result_type."); - using KeyT = Ret(DistrT, std::tuple<Arg, Args...>); - auto gmock_Call( - const ::testing::Matcher<Arg>& matcher, - absl::MockingBitGen& gen, // NOLINT(google-runtime-references) - const ::testing::Matcher<Args>&... matchers) - -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, - matchers...)) { - return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...); - } -}; - -// MockOverloadSet -// -// MockOverloadSet takes a distribution and a collection of signatures and -// performs overload resolution amongst all the overloads. This makes -// `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution -// correctly. -template <typename DistrT, typename... Signatures> -struct MockOverloadSet; - -template <typename DistrT, typename Sig> -struct MockOverloadSet<DistrT, Sig> : public MockSingleOverload<DistrT, Sig> { - using MockSingleOverload<DistrT, Sig>::gmock_Call; -}; - -template <typename DistrT, typename FirstSig, typename... Rest> -struct MockOverloadSet<DistrT, FirstSig, Rest...> - : public MockSingleOverload<DistrT, FirstSig>, - public MockOverloadSet<DistrT, Rest...> { - using MockSingleOverload<DistrT, FirstSig>::gmock_Call; - using MockOverloadSet<DistrT, Rest...>::gmock_Call; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl -#endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/nanobenchmark.cc b/third_party/abseil_cpp/absl/random/internal/nanobenchmark.cc deleted file mode 100644 index c9181813f7f0..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/nanobenchmark.cc +++ /dev/null @@ -1,804 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/nanobenchmark.h" - -#include <sys/types.h> - -#include <algorithm> // sort -#include <atomic> -#include <cstddef> -#include <cstdint> -#include <cstdlib> -#include <cstring> // memcpy -#include <limits> -#include <string> -#include <utility> -#include <vector> - -#include "absl/base/attributes.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_engine.h" - -// OS -#if defined(_WIN32) || defined(_WIN64) -#define ABSL_OS_WIN -#include <windows.h> // NOLINT - -#elif defined(__ANDROID__) -#define ABSL_OS_ANDROID - -#elif defined(__linux__) -#define ABSL_OS_LINUX -#include <sched.h> // NOLINT -#include <sys/syscall.h> // NOLINT -#endif - -#if defined(ABSL_ARCH_X86_64) && !defined(ABSL_OS_WIN) -#include <cpuid.h> // NOLINT -#endif - -// __ppc_get_timebase_freq -#if defined(ABSL_ARCH_PPC) -#include <sys/platform/ppc.h> // NOLINT -#endif - -// clock_gettime -#if defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64) -#include <time.h> // NOLINT -#endif - -// ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE prevents inlining of the method. -#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE __attribute__((noinline)) -#elif defined(_MSC_VER) -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE __declspec(noinline) -#else -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE -#endif - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal_nanobenchmark { -namespace { - -// For code folding. -namespace platform { -#if defined(ABSL_ARCH_X86_64) - -// TODO(janwas): Merge with the one in randen_hwaes.cc? -void Cpuid(const uint32_t level, const uint32_t count, - uint32_t* ABSL_RANDOM_INTERNAL_RESTRICT abcd) { -#if defined(ABSL_OS_WIN) - int regs[4]; - __cpuidex(regs, level, count); - for (int i = 0; i < 4; ++i) { - abcd[i] = regs[i]; - } -#else - uint32_t a, b, c, d; - __cpuid_count(level, count, a, b, c, d); - abcd[0] = a; - abcd[1] = b; - abcd[2] = c; - abcd[3] = d; -#endif -} - -std::string BrandString() { - char brand_string[49]; - uint32_t abcd[4]; - - // Check if brand string is supported (it is on all reasonable Intel/AMD) - Cpuid(0x80000000U, 0, abcd); - if (abcd[0] < 0x80000004U) { - return std::string(); - } - - for (int i = 0; i < 3; ++i) { - Cpuid(0x80000002U + i, 0, abcd); - memcpy(brand_string + i * 16, &abcd, sizeof(abcd)); - } - brand_string[48] = 0; - return brand_string; -} - -// Returns the frequency quoted inside the brand string. This does not -// account for throttling nor Turbo Boost. -double NominalClockRate() { - const std::string& brand_string = BrandString(); - // Brand strings include the maximum configured frequency. These prefixes are - // defined by Intel CPUID documentation. - const char* prefixes[3] = {"MHz", "GHz", "THz"}; - const double multipliers[3] = {1E6, 1E9, 1E12}; - for (size_t i = 0; i < 3; ++i) { - const size_t pos_prefix = brand_string.find(prefixes[i]); - if (pos_prefix != std::string::npos) { - const size_t pos_space = brand_string.rfind(' ', pos_prefix - 1); - if (pos_space != std::string::npos) { - const std::string digits = - brand_string.substr(pos_space + 1, pos_prefix - pos_space - 1); - return std::stod(digits) * multipliers[i]; - } - } - } - - return 0.0; -} - -#endif // ABSL_ARCH_X86_64 -} // namespace platform - -// Prevents the compiler from eliding the computations that led to "output". -template <class T> -inline void PreventElision(T&& output) { -#ifndef ABSL_OS_WIN - // Works by indicating to the compiler that "output" is being read and - // modified. The +r constraint avoids unnecessary writes to memory, but only - // works for built-in types (typically FuncOutput). - asm volatile("" : "+r"(output) : : "memory"); -#else - // MSVC does not support inline assembly anymore (and never supported GCC's - // RTL constraints). Self-assignment with #pragma optimize("off") might be - // expected to prevent elision, but it does not with MSVC 2015. Type-punning - // with volatile pointers generates inefficient code on MSVC 2017. - static std::atomic<T> dummy(T{}); - dummy.store(output, std::memory_order_relaxed); -#endif -} - -namespace timer { - -// Start/Stop return absolute timestamps and must be placed immediately before -// and after the region to measure. We provide separate Start/Stop functions -// because they use different fences. -// -// Background: RDTSC is not 'serializing'; earlier instructions may complete -// after it, and/or later instructions may complete before it. 'Fences' ensure -// regions' elapsed times are independent of such reordering. The only -// documented unprivileged serializing instruction is CPUID, which acts as a -// full fence (no reordering across it in either direction). Unfortunately -// the latency of CPUID varies wildly (perhaps made worse by not initializing -// its EAX input). Because it cannot reliably be deducted from the region's -// elapsed time, it must not be included in the region to measure (i.e. -// between the two RDTSC). -// -// The newer RDTSCP is sometimes described as serializing, but it actually -// only serves as a half-fence with release semantics. Although all -// instructions in the region will complete before the final timestamp is -// captured, subsequent instructions may leak into the region and increase the -// elapsed time. Inserting another fence after the final RDTSCP would prevent -// such reordering without affecting the measured region. -// -// Fortunately, such a fence exists. The LFENCE instruction is only documented -// to delay later loads until earlier loads are visible. However, Intel's -// reference manual says it acts as a full fence (waiting until all earlier -// instructions have completed, and delaying later instructions until it -// completes). AMD assigns the same behavior to MFENCE. -// -// We need a fence before the initial RDTSC to prevent earlier instructions -// from leaking into the region, and arguably another after RDTSC to avoid -// region instructions from completing before the timestamp is recorded. -// When surrounded by fences, the additional RDTSCP half-fence provides no -// benefit, so the initial timestamp can be recorded via RDTSC, which has -// lower overhead than RDTSCP because it does not read TSC_AUX. In summary, -// we define Start = LFENCE/RDTSC/LFENCE; Stop = RDTSCP/LFENCE. -// -// Using Start+Start leads to higher variance and overhead than Stop+Stop. -// However, Stop+Stop includes an LFENCE in the region measurements, which -// adds a delay dependent on earlier loads. The combination of Start+Stop -// is faster than Start+Start and more consistent than Stop+Stop because -// the first LFENCE already delayed subsequent loads before the measured -// region. This combination seems not to have been considered in prior work: -// http://akaros.cs.berkeley.edu/lxr/akaros/kern/arch/x86/rdtsc_test.c -// -// Note: performance counters can measure 'exact' instructions-retired or -// (unhalted) cycle counts. The RDPMC instruction is not serializing and also -// requires fences. Unfortunately, it is not accessible on all OSes and we -// prefer to avoid kernel-mode drivers. Performance counters are also affected -// by several under/over-count errata, so we use the TSC instead. - -// Returns a 64-bit timestamp in unit of 'ticks'; to convert to seconds, -// divide by InvariantTicksPerSecond. -inline uint64_t Start64() { - uint64_t t; -#if defined(ABSL_ARCH_PPC) - asm volatile("mfspr %0, %1" : "=r"(t) : "i"(268)); -#elif defined(ABSL_ARCH_X86_64) -#if defined(ABSL_OS_WIN) - _ReadWriteBarrier(); - _mm_lfence(); - _ReadWriteBarrier(); - t = __rdtsc(); - _ReadWriteBarrier(); - _mm_lfence(); - _ReadWriteBarrier(); -#else - asm volatile( - "lfence\n\t" - "rdtsc\n\t" - "shl $32, %%rdx\n\t" - "or %%rdx, %0\n\t" - "lfence" - : "=a"(t) - : - // "memory" avoids reordering. rdx = TSC >> 32. - // "cc" = flags modified by SHL. - : "rdx", "memory", "cc"); -#endif -#else - // Fall back to OS - unsure how to reliably query cntvct_el0 frequency. - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - t = ts.tv_sec * 1000000000LL + ts.tv_nsec; -#endif - return t; -} - -inline uint64_t Stop64() { - uint64_t t; -#if defined(ABSL_ARCH_X86_64) -#if defined(ABSL_OS_WIN) - _ReadWriteBarrier(); - unsigned aux; - t = __rdtscp(&aux); - _ReadWriteBarrier(); - _mm_lfence(); - _ReadWriteBarrier(); -#else - // Use inline asm because __rdtscp generates code to store TSC_AUX (ecx). - asm volatile( - "rdtscp\n\t" - "shl $32, %%rdx\n\t" - "or %%rdx, %0\n\t" - "lfence" - : "=a"(t) - : - // "memory" avoids reordering. rcx = TSC_AUX. rdx = TSC >> 32. - // "cc" = flags modified by SHL. - : "rcx", "rdx", "memory", "cc"); -#endif -#else - t = Start64(); -#endif - return t; -} - -// Returns a 32-bit timestamp with about 4 cycles less overhead than -// Start64. Only suitable for measuring very short regions because the -// timestamp overflows about once a second. -inline uint32_t Start32() { - uint32_t t; -#if defined(ABSL_ARCH_X86_64) -#if defined(ABSL_OS_WIN) - _ReadWriteBarrier(); - _mm_lfence(); - _ReadWriteBarrier(); - t = static_cast<uint32_t>(__rdtsc()); - _ReadWriteBarrier(); - _mm_lfence(); - _ReadWriteBarrier(); -#else - asm volatile( - "lfence\n\t" - "rdtsc\n\t" - "lfence" - : "=a"(t) - : - // "memory" avoids reordering. rdx = TSC >> 32. - : "rdx", "memory"); -#endif -#else - t = static_cast<uint32_t>(Start64()); -#endif - return t; -} - -inline uint32_t Stop32() { - uint32_t t; -#if defined(ABSL_ARCH_X86_64) -#if defined(ABSL_OS_WIN) - _ReadWriteBarrier(); - unsigned aux; - t = static_cast<uint32_t>(__rdtscp(&aux)); - _ReadWriteBarrier(); - _mm_lfence(); - _ReadWriteBarrier(); -#else - // Use inline asm because __rdtscp generates code to store TSC_AUX (ecx). - asm volatile( - "rdtscp\n\t" - "lfence" - : "=a"(t) - : - // "memory" avoids reordering. rcx = TSC_AUX. rdx = TSC >> 32. - : "rcx", "rdx", "memory"); -#endif -#else - t = static_cast<uint32_t>(Stop64()); -#endif - return t; -} - -} // namespace timer - -namespace robust_statistics { - -// Sorts integral values in ascending order (e.g. for Mode). About 3x faster -// than std::sort for input distributions with very few unique values. -template <class T> -void CountingSort(T* values, size_t num_values) { - // Unique values and their frequency (similar to flat_map). - using Unique = std::pair<T, int>; - std::vector<Unique> unique; - for (size_t i = 0; i < num_values; ++i) { - const T value = values[i]; - const auto pos = - std::find_if(unique.begin(), unique.end(), - [value](const Unique u) { return u.first == value; }); - if (pos == unique.end()) { - unique.push_back(std::make_pair(value, 1)); - } else { - ++pos->second; - } - } - - // Sort in ascending order of value (pair.first). - std::sort(unique.begin(), unique.end()); - - // Write that many copies of each unique value to the array. - T* ABSL_RANDOM_INTERNAL_RESTRICT p = values; - for (const auto& value_count : unique) { - std::fill(p, p + value_count.second, value_count.first); - p += value_count.second; - } - ABSL_RAW_CHECK(p == values + num_values, "Did not produce enough output"); -} - -// @return i in [idx_begin, idx_begin + half_count) that minimizes -// sorted[i + half_count] - sorted[i]. -template <typename T> -size_t MinRange(const T* const ABSL_RANDOM_INTERNAL_RESTRICT sorted, - const size_t idx_begin, const size_t half_count) { - T min_range = (std::numeric_limits<T>::max)(); - size_t min_idx = 0; - - for (size_t idx = idx_begin; idx < idx_begin + half_count; ++idx) { - ABSL_RAW_CHECK(sorted[idx] <= sorted[idx + half_count], "Not sorted"); - const T range = sorted[idx + half_count] - sorted[idx]; - if (range < min_range) { - min_range = range; - min_idx = idx; - } - } - - return min_idx; -} - -// Returns an estimate of the mode by calling MinRange on successively -// halved intervals. "sorted" must be in ascending order. This is the -// Half Sample Mode estimator proposed by Bickel in "On a fast, robust -// estimator of the mode", with complexity O(N log N). The mode is less -// affected by outliers in highly-skewed distributions than the median. -// The averaging operation below assumes "T" is an unsigned integer type. -template <typename T> -T ModeOfSorted(const T* const ABSL_RANDOM_INTERNAL_RESTRICT sorted, - const size_t num_values) { - size_t idx_begin = 0; - size_t half_count = num_values / 2; - while (half_count > 1) { - idx_begin = MinRange(sorted, idx_begin, half_count); - half_count >>= 1; - } - - const T x = sorted[idx_begin + 0]; - if (half_count == 0) { - return x; - } - ABSL_RAW_CHECK(half_count == 1, "Should stop at half_count=1"); - const T average = (x + sorted[idx_begin + 1] + 1) / 2; - return average; -} - -// Returns the mode. Side effect: sorts "values". -template <typename T> -T Mode(T* values, const size_t num_values) { - CountingSort(values, num_values); - return ModeOfSorted(values, num_values); -} - -template <typename T, size_t N> -T Mode(T (&values)[N]) { - return Mode(&values[0], N); -} - -// Returns the median value. Side effect: sorts "values". -template <typename T> -T Median(T* values, const size_t num_values) { - ABSL_RAW_CHECK(num_values != 0, "Empty input"); - std::sort(values, values + num_values); - const size_t half = num_values / 2; - // Odd count: return middle - if (num_values % 2) { - return values[half]; - } - // Even count: return average of middle two. - return (values[half] + values[half - 1] + 1) / 2; -} - -// Returns a robust measure of variability. -template <typename T> -T MedianAbsoluteDeviation(const T* values, const size_t num_values, - const T median) { - ABSL_RAW_CHECK(num_values != 0, "Empty input"); - std::vector<T> abs_deviations; - abs_deviations.reserve(num_values); - for (size_t i = 0; i < num_values; ++i) { - const int64_t abs = std::abs(int64_t(values[i]) - int64_t(median)); - abs_deviations.push_back(static_cast<T>(abs)); - } - return Median(abs_deviations.data(), num_values); -} - -} // namespace robust_statistics - -// Ticks := platform-specific timer values (CPU cycles on x86). Must be -// unsigned to guarantee wraparound on overflow. 32 bit timers are faster to -// read than 64 bit. -using Ticks = uint32_t; - -// Returns timer overhead / minimum measurable difference. -Ticks TimerResolution() { - // Nested loop avoids exceeding stack/L1 capacity. - Ticks repetitions[Params::kTimerSamples]; - for (size_t rep = 0; rep < Params::kTimerSamples; ++rep) { - Ticks samples[Params::kTimerSamples]; - for (size_t i = 0; i < Params::kTimerSamples; ++i) { - const Ticks t0 = timer::Start32(); - const Ticks t1 = timer::Stop32(); - samples[i] = t1 - t0; - } - repetitions[rep] = robust_statistics::Mode(samples); - } - return robust_statistics::Mode(repetitions); -} - -static const Ticks timer_resolution = TimerResolution(); - -// Estimates the expected value of "lambda" values with a variable number of -// samples until the variability "rel_mad" is less than "max_rel_mad". -template <class Lambda> -Ticks SampleUntilStable(const double max_rel_mad, double* rel_mad, - const Params& p, const Lambda& lambda) { - auto measure_duration = [&lambda]() -> Ticks { - const Ticks t0 = timer::Start32(); - lambda(); - const Ticks t1 = timer::Stop32(); - return t1 - t0; - }; - - // Choose initial samples_per_eval based on a single estimated duration. - Ticks est = measure_duration(); - static const double ticks_per_second = InvariantTicksPerSecond(); - const size_t ticks_per_eval = ticks_per_second * p.seconds_per_eval; - size_t samples_per_eval = ticks_per_eval / est; - samples_per_eval = (std::max)(samples_per_eval, p.min_samples_per_eval); - - std::vector<Ticks> samples; - samples.reserve(1 + samples_per_eval); - samples.push_back(est); - - // Percentage is too strict for tiny differences, so also allow a small - // absolute "median absolute deviation". - const Ticks max_abs_mad = (timer_resolution + 99) / 100; - *rel_mad = 0.0; // ensure initialized - - for (size_t eval = 0; eval < p.max_evals; ++eval, samples_per_eval *= 2) { - samples.reserve(samples.size() + samples_per_eval); - for (size_t i = 0; i < samples_per_eval; ++i) { - const Ticks r = measure_duration(); - samples.push_back(r); - } - - if (samples.size() >= p.min_mode_samples) { - est = robust_statistics::Mode(samples.data(), samples.size()); - } else { - // For "few" (depends also on the variance) samples, Median is safer. - est = robust_statistics::Median(samples.data(), samples.size()); - } - ABSL_RAW_CHECK(est != 0, "Estimator returned zero duration"); - - // Median absolute deviation (mad) is a robust measure of 'variability'. - const Ticks abs_mad = robust_statistics::MedianAbsoluteDeviation( - samples.data(), samples.size(), est); - *rel_mad = static_cast<double>(static_cast<int>(abs_mad)) / est; - - if (*rel_mad <= max_rel_mad || abs_mad <= max_abs_mad) { - if (p.verbose) { - ABSL_RAW_LOG(INFO, - "%6zu samples => %5u (abs_mad=%4u, rel_mad=%4.2f%%)\n", - samples.size(), est, abs_mad, *rel_mad * 100.0); - } - return est; - } - } - - if (p.verbose) { - ABSL_RAW_LOG(WARNING, - "rel_mad=%4.2f%% still exceeds %4.2f%% after %6zu samples.\n", - *rel_mad * 100.0, max_rel_mad * 100.0, samples.size()); - } - return est; -} - -using InputVec = std::vector<FuncInput>; - -// Returns vector of unique input values. -InputVec UniqueInputs(const FuncInput* inputs, const size_t num_inputs) { - InputVec unique(inputs, inputs + num_inputs); - std::sort(unique.begin(), unique.end()); - unique.erase(std::unique(unique.begin(), unique.end()), unique.end()); - return unique; -} - -// Returns how often we need to call func for sufficient precision, or zero -// on failure (e.g. the elapsed time is too long for a 32-bit tick count). -size_t NumSkip(const Func func, const void* arg, const InputVec& unique, - const Params& p) { - // Min elapsed ticks for any input. - Ticks min_duration = ~0u; - - for (const FuncInput input : unique) { - // Make sure a 32-bit timer is sufficient. - const uint64_t t0 = timer::Start64(); - PreventElision(func(arg, input)); - const uint64_t t1 = timer::Stop64(); - const uint64_t elapsed = t1 - t0; - if (elapsed >= (1ULL << 30)) { - ABSL_RAW_LOG(WARNING, - "Measurement failed: need 64-bit timer for input=%zu\n", - static_cast<size_t>(input)); - return 0; - } - - double rel_mad; - const Ticks total = SampleUntilStable( - p.target_rel_mad, &rel_mad, p, - [func, arg, input]() { PreventElision(func(arg, input)); }); - min_duration = (std::min)(min_duration, total - timer_resolution); - } - - // Number of repetitions required to reach the target resolution. - const size_t max_skip = p.precision_divisor; - // Number of repetitions given the estimated duration. - const size_t num_skip = - min_duration == 0 ? 0 : (max_skip + min_duration - 1) / min_duration; - if (p.verbose) { - ABSL_RAW_LOG(INFO, "res=%u max_skip=%zu min_dur=%u num_skip=%zu\n", - timer_resolution, max_skip, min_duration, num_skip); - } - return num_skip; -} - -// Replicates inputs until we can omit "num_skip" occurrences of an input. -InputVec ReplicateInputs(const FuncInput* inputs, const size_t num_inputs, - const size_t num_unique, const size_t num_skip, - const Params& p) { - InputVec full; - if (num_unique == 1) { - full.assign(p.subset_ratio * num_skip, inputs[0]); - return full; - } - - full.reserve(p.subset_ratio * num_skip * num_inputs); - for (size_t i = 0; i < p.subset_ratio * num_skip; ++i) { - full.insert(full.end(), inputs, inputs + num_inputs); - } - absl::random_internal::randen_engine<uint32_t> rng; - std::shuffle(full.begin(), full.end(), rng); - return full; -} - -// Copies the "full" to "subset" in the same order, but with "num_skip" -// randomly selected occurrences of "input_to_skip" removed. -void FillSubset(const InputVec& full, const FuncInput input_to_skip, - const size_t num_skip, InputVec* subset) { - const size_t count = std::count(full.begin(), full.end(), input_to_skip); - // Generate num_skip random indices: which occurrence to skip. - std::vector<uint32_t> omit; - // Replacement for std::iota, not yet available in MSVC builds. - omit.reserve(count); - for (size_t i = 0; i < count; ++i) { - omit.push_back(i); - } - // omit[] is the same on every call, but that's OK because they identify the - // Nth instance of input_to_skip, so the position within full[] differs. - absl::random_internal::randen_engine<uint32_t> rng; - std::shuffle(omit.begin(), omit.end(), rng); - omit.resize(num_skip); - std::sort(omit.begin(), omit.end()); - - uint32_t occurrence = ~0u; // 0 after preincrement - size_t idx_omit = 0; // cursor within omit[] - size_t idx_subset = 0; // cursor within *subset - for (const FuncInput next : full) { - if (next == input_to_skip) { - ++occurrence; - // Haven't removed enough already - if (idx_omit < num_skip) { - // This one is up for removal - if (occurrence == omit[idx_omit]) { - ++idx_omit; - continue; - } - } - } - if (idx_subset < subset->size()) { - (*subset)[idx_subset++] = next; - } - } - ABSL_RAW_CHECK(idx_subset == subset->size(), "idx_subset not at end"); - ABSL_RAW_CHECK(idx_omit == omit.size(), "idx_omit not at end"); - ABSL_RAW_CHECK(occurrence == count - 1, "occurrence not at end"); -} - -// Returns total ticks elapsed for all inputs. -Ticks TotalDuration(const Func func, const void* arg, const InputVec* inputs, - const Params& p, double* max_rel_mad) { - double rel_mad; - const Ticks duration = - SampleUntilStable(p.target_rel_mad, &rel_mad, p, [func, arg, inputs]() { - for (const FuncInput input : *inputs) { - PreventElision(func(arg, input)); - } - }); - *max_rel_mad = (std::max)(*max_rel_mad, rel_mad); - return duration; -} - -// (Nearly) empty Func for measuring timer overhead/resolution. -ABSL_RANDOM_INTERNAL_ATTRIBUTE_NEVER_INLINE FuncOutput -EmptyFunc(const void* arg, const FuncInput input) { - return input; -} - -// Returns overhead of accessing inputs[] and calling a function; this will -// be deducted from future TotalDuration return values. -Ticks Overhead(const void* arg, const InputVec* inputs, const Params& p) { - double rel_mad; - // Zero tolerance because repeatability is crucial and EmptyFunc is fast. - return SampleUntilStable(0.0, &rel_mad, p, [arg, inputs]() { - for (const FuncInput input : *inputs) { - PreventElision(EmptyFunc(arg, input)); - } - }); -} - -} // namespace - -void PinThreadToCPU(int cpu) { - // We might migrate to another CPU before pinning below, but at least cpu - // will be one of the CPUs on which this thread ran. -#if defined(ABSL_OS_WIN) - if (cpu < 0) { - cpu = static_cast<int>(GetCurrentProcessorNumber()); - ABSL_RAW_CHECK(cpu >= 0, "PinThreadToCPU detect failed"); - if (cpu >= 64) { - // NOTE: On wine, at least, GetCurrentProcessorNumber() sometimes returns - // a value > 64, which is out of range. When this happens, log a message - // and don't set a cpu affinity. - ABSL_RAW_LOG(ERROR, "Invalid CPU number: %d", cpu); - return; - } - } else if (cpu >= 64) { - // User specified an explicit CPU affinity > the valid range. - ABSL_RAW_LOG(FATAL, "Invalid CPU number: %d", cpu); - } - const DWORD_PTR prev = SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu); - ABSL_RAW_CHECK(prev != 0, "SetAffinity failed"); -#elif defined(ABSL_OS_LINUX) && !defined(ABSL_OS_ANDROID) - if (cpu < 0) { - cpu = sched_getcpu(); - ABSL_RAW_CHECK(cpu >= 0, "PinThreadToCPU detect failed"); - } - const pid_t pid = 0; // current thread - cpu_set_t set; - CPU_ZERO(&set); - CPU_SET(cpu, &set); - const int err = sched_setaffinity(pid, sizeof(set), &set); - ABSL_RAW_CHECK(err == 0, "SetAffinity failed"); -#endif -} - -// Returns tick rate. Invariant means the tick counter frequency is independent -// of CPU throttling or sleep. May be expensive, caller should cache the result. -double InvariantTicksPerSecond() { -#if defined(ABSL_ARCH_PPC) - return __ppc_get_timebase_freq(); -#elif defined(ABSL_ARCH_X86_64) - // We assume the TSC is invariant; it is on all recent Intel/AMD CPUs. - return platform::NominalClockRate(); -#else - // Fall back to clock_gettime nanoseconds. - return 1E9; -#endif -} - -size_t MeasureImpl(const Func func, const void* arg, const size_t num_skip, - const InputVec& unique, const InputVec& full, - const Params& p, Result* results) { - const float mul = 1.0f / static_cast<int>(num_skip); - - InputVec subset(full.size() - num_skip); - const Ticks overhead = Overhead(arg, &full, p); - const Ticks overhead_skip = Overhead(arg, &subset, p); - if (overhead < overhead_skip) { - ABSL_RAW_LOG(WARNING, "Measurement failed: overhead %u < %u\n", overhead, - overhead_skip); - return 0; - } - - if (p.verbose) { - ABSL_RAW_LOG(INFO, "#inputs=%5zu,%5zu overhead=%5u,%5u\n", full.size(), - subset.size(), overhead, overhead_skip); - } - - double max_rel_mad = 0.0; - const Ticks total = TotalDuration(func, arg, &full, p, &max_rel_mad); - - for (size_t i = 0; i < unique.size(); ++i) { - FillSubset(full, unique[i], num_skip, &subset); - const Ticks total_skip = TotalDuration(func, arg, &subset, p, &max_rel_mad); - - if (total < total_skip) { - ABSL_RAW_LOG(WARNING, "Measurement failed: total %u < %u\n", total, - total_skip); - return 0; - } - - const Ticks duration = (total - overhead) - (total_skip - overhead_skip); - results[i].input = unique[i]; - results[i].ticks = duration * mul; - results[i].variability = max_rel_mad; - } - - return unique.size(); -} - -size_t Measure(const Func func, const void* arg, const FuncInput* inputs, - const size_t num_inputs, Result* results, const Params& p) { - ABSL_RAW_CHECK(num_inputs != 0, "No inputs"); - - const InputVec unique = UniqueInputs(inputs, num_inputs); - const size_t num_skip = NumSkip(func, arg, unique, p); // never 0 - if (num_skip == 0) return 0; // NumSkip already printed error message - - const InputVec full = - ReplicateInputs(inputs, num_inputs, unique.size(), num_skip, p); - - // MeasureImpl may fail up to p.max_measure_retries times. - for (size_t i = 0; i < p.max_measure_retries; i++) { - auto result = MeasureImpl(func, arg, num_skip, unique, full, p, results); - if (result != 0) { - return result; - } - } - // All retries failed. (Unusual) - return 0; -} - -} // namespace random_internal_nanobenchmark -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/nanobenchmark.h b/third_party/abseil_cpp/absl/random/internal/nanobenchmark.h deleted file mode 100644 index a5097ba27b0f..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/nanobenchmark.h +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_ -#define ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_ - -// Benchmarks functions of a single integer argument with realistic branch -// prediction hit rates. Uses a robust estimator to summarize the measurements. -// The precision is about 0.2%. -// -// Examples: see nanobenchmark_test.cc. -// -// Background: Microbenchmarks such as http://github.com/google/benchmark -// can measure elapsed times on the order of a microsecond. Shorter functions -// are typically measured by repeating them thousands of times and dividing -// the total elapsed time by this count. Unfortunately, repetition (especially -// with the same input parameter!) influences the runtime. In time-critical -// code, it is reasonable to expect warm instruction/data caches and TLBs, -// but a perfect record of which branches will be taken is unrealistic. -// Unless the application also repeatedly invokes the measured function with -// the same parameter, the benchmark is measuring something very different - -// a best-case result, almost as if the parameter were made a compile-time -// constant. This may lead to erroneous conclusions about branch-heavy -// algorithms outperforming branch-free alternatives. -// -// Our approach differs in three ways. Adding fences to the timer functions -// reduces variability due to instruction reordering, improving the timer -// resolution to about 40 CPU cycles. However, shorter functions must still -// be invoked repeatedly. For more realistic branch prediction performance, -// we vary the input parameter according to a user-specified distribution. -// Thus, instead of VaryInputs(Measure(Repeat(func))), we change the -// loop nesting to Measure(Repeat(VaryInputs(func))). We also estimate the -// central tendency of the measurement samples with the "half sample mode", -// which is more robust to outliers and skewed data than the mean or median. - -// NOTE: for compatibility with multiple translation units compiled with -// distinct flags, avoid #including headers that define functions. - -#include <stddef.h> -#include <stdint.h> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal_nanobenchmark { - -// Input influencing the function being measured (e.g. number of bytes to copy). -using FuncInput = size_t; - -// "Proof of work" returned by Func to ensure the compiler does not elide it. -using FuncOutput = uint64_t; - -// Function to measure: either 1) a captureless lambda or function with two -// arguments or 2) a lambda with capture, in which case the first argument -// is reserved for use by MeasureClosure. -using Func = FuncOutput (*)(const void*, FuncInput); - -// Internal parameters that determine precision/resolution/measuring time. -struct Params { - // For measuring timer overhead/resolution. Used in a nested loop => - // quadratic time, acceptable because we know timer overhead is "low". - // constexpr because this is used to define array bounds. - static constexpr size_t kTimerSamples = 256; - - // Best-case precision, expressed as a divisor of the timer resolution. - // Larger => more calls to Func and higher precision. - size_t precision_divisor = 1024; - - // Ratio between full and subset input distribution sizes. Cannot be less - // than 2; larger values increase measurement time but more faithfully - // model the given input distribution. - size_t subset_ratio = 2; - - // Together with the estimated Func duration, determines how many times to - // call Func before checking the sample variability. Larger values increase - // measurement time, memory/cache use and precision. - double seconds_per_eval = 4E-3; - - // The minimum number of samples before estimating the central tendency. - size_t min_samples_per_eval = 7; - - // The mode is better than median for estimating the central tendency of - // skewed/fat-tailed distributions, but it requires sufficient samples - // relative to the width of half-ranges. - size_t min_mode_samples = 64; - - // Maximum permissible variability (= median absolute deviation / center). - double target_rel_mad = 0.002; - - // Abort after this many evals without reaching target_rel_mad. This - // prevents infinite loops. - size_t max_evals = 9; - - // Retry the measure loop up to this many times. - size_t max_measure_retries = 2; - - // Whether to print additional statistics to stdout. - bool verbose = true; -}; - -// Measurement result for each unique input. -struct Result { - FuncInput input; - - // Robust estimate (mode or median) of duration. - float ticks; - - // Measure of variability (median absolute deviation relative to "ticks"). - float variability; -}; - -// Ensures the thread is running on the specified cpu, and no others. -// Reduces noise due to desynchronized socket RDTSC and context switches. -// If "cpu" is negative, pin to the currently running core. -void PinThreadToCPU(const int cpu = -1); - -// Returns tick rate, useful for converting measurements to seconds. Invariant -// means the tick counter frequency is independent of CPU throttling or sleep. -// This call may be expensive, callers should cache the result. -double InvariantTicksPerSecond(); - -// Precisely measures the number of ticks elapsed when calling "func" with the -// given inputs, shuffled to ensure realistic branch prediction hit rates. -// -// "func" returns a 'proof of work' to ensure its computations are not elided. -// "arg" is passed to Func, or reserved for internal use by MeasureClosure. -// "inputs" is an array of "num_inputs" (not necessarily unique) arguments to -// "func". The values should be chosen to maximize coverage of "func". This -// represents a distribution, so a value's frequency should reflect its -// probability in the real application. Order does not matter; for example, a -// uniform distribution over [0, 4) could be represented as {3,0,2,1}. -// Returns how many Result were written to "results": one per unique input, or -// zero if the measurement failed (an error message goes to stderr). -size_t Measure(const Func func, const void* arg, const FuncInput* inputs, - const size_t num_inputs, Result* results, - const Params& p = Params()); - -// Calls operator() of the given closure (lambda function). -template <class Closure> -static FuncOutput CallClosure(const void* f, const FuncInput input) { - return (*reinterpret_cast<const Closure*>(f))(input); -} - -// Same as Measure, except "closure" is typically a lambda function of -// FuncInput -> FuncOutput with a capture list. -template <class Closure> -static inline size_t MeasureClosure(const Closure& closure, - const FuncInput* inputs, - const size_t num_inputs, Result* results, - const Params& p = Params()) { - return Measure(reinterpret_cast<Func>(&CallClosure<Closure>), - reinterpret_cast<const void*>(&closure), inputs, num_inputs, - results, p); -} - -} // namespace random_internal_nanobenchmark -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/nanobenchmark_test.cc b/third_party/abseil_cpp/absl/random/internal/nanobenchmark_test.cc deleted file mode 100644 index f1571e269ff5..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/nanobenchmark_test.cc +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/nanobenchmark.h" - -#include "absl/base/internal/raw_logging.h" -#include "absl/strings/numbers.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal_nanobenchmark { -namespace { - -uint64_t Div(const void*, FuncInput in) { - // Here we're measuring the throughput because benchmark invocations are - // independent. - const int64_t d1 = 0xFFFFFFFFFFll / int64_t(in); // IDIV - return d1; -} - -template <size_t N> -void MeasureDiv(const FuncInput (&inputs)[N]) { - Result results[N]; - Params params; - params.max_evals = 6; // avoid test timeout - const size_t num_results = Measure(&Div, nullptr, inputs, N, results, params); - if (num_results == 0) { - ABSL_RAW_LOG( - WARNING, - "WARNING: Measurement failed, should not happen when using " - "PinThreadToCPU unless the region to measure takes > 1 second.\n"); - return; - } - for (size_t i = 0; i < num_results; ++i) { - ABSL_RAW_LOG(INFO, "%5zu: %6.2f ticks; MAD=%4.2f%%\n", results[i].input, - results[i].ticks, results[i].variability * 100.0); - ABSL_RAW_CHECK(results[i].ticks != 0.0f, "Zero duration"); - } -} - -void RunAll(const int argc, char* argv[]) { - // Avoid migrating between cores - important on multi-socket systems. - int cpu = -1; - if (argc == 2) { - if (!absl::SimpleAtoi(argv[1], &cpu)) { - ABSL_RAW_LOG(FATAL, "The optional argument must be a CPU number >= 0.\n"); - } - } - PinThreadToCPU(cpu); - - // unpredictable == 1 but the compiler doesn't know that. - const FuncInput unpredictable = argc != 999; - static const FuncInput inputs[] = {unpredictable * 10, unpredictable * 100}; - - MeasureDiv(inputs); -} - -} // namespace -} // namespace random_internal_nanobenchmark -ABSL_NAMESPACE_END -} // namespace absl - -int main(int argc, char* argv[]) { - absl::random_internal_nanobenchmark::RunAll(argc, argv); - return 0; -} diff --git a/third_party/abseil_cpp/absl/random/internal/nonsecure_base.h b/third_party/abseil_cpp/absl/random/internal/nonsecure_base.h deleted file mode 100644 index 730fa2ea12d2..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/nonsecure_base.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_ -#define ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_ - -#include <algorithm> -#include <cstdint> -#include <iostream> -#include <iterator> -#include <random> -#include <string> -#include <type_traits> -#include <vector> - -#include "absl/base/macros.h" -#include "absl/meta/type_traits.h" -#include "absl/random/internal/pool_urbg.h" -#include "absl/random/internal/salted_seed_seq.h" -#include "absl/random/internal/seed_material.h" -#include "absl/types/optional.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Each instance of NonsecureURBGBase<URBG> will be seeded by variates produced -// by a thread-unique URBG-instance. -template <typename URBG> -class NonsecureURBGBase { - public: - using result_type = typename URBG::result_type; - - // Default constructor - NonsecureURBGBase() : urbg_(ConstructURBG()) {} - - // Copy disallowed, move allowed. - NonsecureURBGBase(const NonsecureURBGBase&) = delete; - NonsecureURBGBase& operator=(const NonsecureURBGBase&) = delete; - NonsecureURBGBase(NonsecureURBGBase&&) = default; - NonsecureURBGBase& operator=(NonsecureURBGBase&&) = default; - - // Constructor using a seed - template <class SSeq, typename = typename absl::enable_if_t< - !std::is_same<SSeq, NonsecureURBGBase>::value>> - explicit NonsecureURBGBase(SSeq&& seq) - : urbg_(ConstructURBG(std::forward<SSeq>(seq))) {} - - // Note: on MSVC, min() or max() can be interpreted as MIN() or MAX(), so we - // enclose min() or max() in parens as (min)() and (max)(). - // Additionally, clang-format requires no space before this construction. - - // NonsecureURBGBase::min() - static constexpr result_type(min)() { return (URBG::min)(); } - - // NonsecureURBGBase::max() - static constexpr result_type(max)() { return (URBG::max)(); } - - // NonsecureURBGBase::operator()() - result_type operator()() { return urbg_(); } - - // NonsecureURBGBase::discard() - void discard(unsigned long long values) { // NOLINT(runtime/int) - urbg_.discard(values); - } - - bool operator==(const NonsecureURBGBase& other) const { - return urbg_ == other.urbg_; - } - - bool operator!=(const NonsecureURBGBase& other) const { - return !(urbg_ == other.urbg_); - } - - private: - // Seeder is a custom seed sequence type where generate() fills the provided - // buffer via the RandenPool entropy source. - struct Seeder { - using result_type = uint32_t; - - size_t size() { return 0; } - - template <typename OutIterator> - void param(OutIterator) const {} - - template <typename RandomAccessIterator> - void generate(RandomAccessIterator begin, RandomAccessIterator end) { - if (begin != end) { - // begin, end must be random access iterators assignable from uint32_t. - generate_impl( - std::integral_constant<bool, sizeof(*begin) == sizeof(uint32_t)>{}, - begin, end); - } - } - - // Commonly, generate is invoked with a pointer to a buffer which - // can be cast to a uint32_t. - template <typename RandomAccessIterator> - void generate_impl(std::integral_constant<bool, true>, - RandomAccessIterator begin, RandomAccessIterator end) { - auto buffer = absl::MakeSpan(begin, end); - auto target = absl::MakeSpan(reinterpret_cast<uint32_t*>(buffer.data()), - buffer.size()); - RandenPool<uint32_t>::Fill(target); - } - - // The non-uint32_t case should be uncommon, and involves an extra copy, - // filling the uint32_t buffer and then mixing into the output. - template <typename RandomAccessIterator> - void generate_impl(std::integral_constant<bool, false>, - RandomAccessIterator begin, RandomAccessIterator end) { - const size_t n = std::distance(begin, end); - absl::InlinedVector<uint32_t, 8> data(n, 0); - RandenPool<uint32_t>::Fill(absl::MakeSpan(data.begin(), data.end())); - std::copy(std::begin(data), std::end(data), begin); - } - }; - - static URBG ConstructURBG() { - Seeder seeder; - return URBG(seeder); - } - - template <typename SSeq> - static URBG ConstructURBG(SSeq&& seq) { // NOLINT(runtime/references) - auto salted_seq = - random_internal::MakeSaltedSeedSeq(std::forward<SSeq>(seq)); - return URBG(salted_seq); - } - - URBG urbg_; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/nonsecure_base_test.cc b/third_party/abseil_cpp/absl/random/internal/nonsecure_base_test.cc deleted file mode 100644 index 698027fc6e0d..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/nonsecure_base_test.cc +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/nonsecure_base.h" - -#include <algorithm> -#include <iostream> -#include <memory> -#include <random> -#include <sstream> - -#include "gtest/gtest.h" -#include "absl/random/distributions.h" -#include "absl/random/random.h" -#include "absl/strings/str_cat.h" - -namespace { - -using ExampleNonsecureURBG = - absl::random_internal::NonsecureURBGBase<std::mt19937>; - -template <typename T> -void Use(const T&) {} - -} // namespace - -TEST(NonsecureURBGBase, DefaultConstructorIsValid) { - ExampleNonsecureURBG urbg; -} - -// Ensure that the recommended template-instantiations are valid. -TEST(RecommendedTemplates, CanBeConstructed) { - absl::BitGen default_generator; - absl::InsecureBitGen insecure_generator; -} - -TEST(RecommendedTemplates, CanDiscardValues) { - absl::BitGen default_generator; - absl::InsecureBitGen insecure_generator; - - default_generator.discard(5); - insecure_generator.discard(5); -} - -TEST(NonsecureURBGBase, StandardInterface) { - // Names after definition of [rand.req.urbg] in C++ standard. - // e us a value of E - // v is a lvalue of E - // x, y are possibly const values of E - // s is a value of T - // q is a value satisfying requirements of seed_sequence - // z is a value of type unsigned long long - // os is a some specialization of basic_ostream - // is is a some specialization of basic_istream - - using E = absl::random_internal::NonsecureURBGBase<std::minstd_rand>; - - using T = typename E::result_type; - - static_assert(!std::is_copy_constructible<E>::value, - "NonsecureURBGBase should not be copy constructible"); - - static_assert(!absl::is_copy_assignable<E>::value, - "NonsecureURBGBase should not be copy assignable"); - - static_assert(std::is_move_constructible<E>::value, - "NonsecureURBGBase should be move constructible"); - - static_assert(absl::is_move_assignable<E>::value, - "NonsecureURBGBase should be move assignable"); - - static_assert(std::is_same<decltype(std::declval<E>()()), T>::value, - "return type of operator() must be result_type"); - - { - const E x, y; - Use(x); - Use(y); - - static_assert(std::is_same<decltype(x == y), bool>::value, - "return type of operator== must be bool"); - - static_assert(std::is_same<decltype(x != y), bool>::value, - "return type of operator== must be bool"); - } - - E e; - std::seed_seq q{1, 2, 3}; - - E{}; - E{q}; - - // Copy constructor not supported. - // E{x}; - - // result_type seed constructor not supported. - // E{T{1}}; - - // Move constructors are supported. - { - E tmp(q); - E m = std::move(tmp); - E n(std::move(m)); - EXPECT_TRUE(e != n); - } - - // Comparisons work. - { - // MSVC emits error 2718 when using EXPECT_EQ(e, x) - // * actual parameter with __declspec(align('#')) won't be aligned - E a(q); - E b(q); - - EXPECT_TRUE(a != e); - EXPECT_TRUE(a == b); - - a(); - EXPECT_TRUE(a != b); - } - - // e.seed(s) not supported. - - // [rand.req.eng] specifies the parameter as 'unsigned long long' - // e.discard(unsigned long long) is supported. - unsigned long long z = 1; // NOLINT(runtime/int) - e.discard(z); -} - -TEST(NonsecureURBGBase, SeedSeqConstructorIsValid) { - std::seed_seq seq; - ExampleNonsecureURBG rbg(seq); -} - -TEST(NonsecureURBGBase, CompatibleWithDistributionUtils) { - ExampleNonsecureURBG rbg; - - absl::Uniform(rbg, 0, 100); - absl::Uniform(rbg, 0.5, 0.7); - absl::Poisson<uint32_t>(rbg); - absl::Exponential<float>(rbg); -} - -TEST(NonsecureURBGBase, CompatibleWithStdDistributions) { - ExampleNonsecureURBG rbg; - - // Cast to void to suppress [[nodiscard]] warnings - static_cast<void>(std::uniform_int_distribution<uint32_t>(0, 100)(rbg)); - static_cast<void>(std::uniform_real_distribution<float>()(rbg)); - static_cast<void>(std::bernoulli_distribution(0.2)(rbg)); -} - -TEST(NonsecureURBGBase, ConsecutiveDefaultInstancesYieldUniqueVariates) { - const size_t kNumSamples = 128; - - ExampleNonsecureURBG rbg1; - ExampleNonsecureURBG rbg2; - - for (size_t i = 0; i < kNumSamples; i++) { - EXPECT_NE(rbg1(), rbg2()); - } -} - -TEST(NonsecureURBGBase, EqualSeedSequencesYieldEqualVariates) { - std::seed_seq seq; - - ExampleNonsecureURBG rbg1(seq); - ExampleNonsecureURBG rbg2(seq); - - // ExampleNonsecureURBG rbg3({1, 2, 3}); // Should not compile. - - for (uint32_t i = 0; i < 1000; i++) { - EXPECT_EQ(rbg1(), rbg2()); - } - - rbg1.discard(100); - rbg2.discard(100); - - // The sequences should continue after discarding - for (uint32_t i = 0; i < 1000; i++) { - EXPECT_EQ(rbg1(), rbg2()); - } -} - -// This is a PRNG-compatible type specifically designed to test -// that NonsecureURBGBase::Seeder can correctly handle iterators -// to arbitrary non-uint32_t size types. -template <typename T> -struct SeederTestEngine { - using result_type = T; - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - template <class SeedSequence, - typename = typename absl::enable_if_t< - !std::is_same<SeedSequence, SeederTestEngine>::value>> - explicit SeederTestEngine(SeedSequence&& seq) { - seed(seq); - } - - SeederTestEngine(const SeederTestEngine&) = default; - SeederTestEngine& operator=(const SeederTestEngine&) = default; - SeederTestEngine(SeederTestEngine&&) = default; - SeederTestEngine& operator=(SeederTestEngine&&) = default; - - result_type operator()() { return state[0]; } - - template <class SeedSequence> - void seed(SeedSequence&& seq) { - std::fill(std::begin(state), std::end(state), T(0)); - seq.generate(std::begin(state), std::end(state)); - } - - T state[2]; -}; - -TEST(NonsecureURBGBase, SeederWorksForU32) { - using U32 = - absl::random_internal::NonsecureURBGBase<SeederTestEngine<uint32_t>>; - U32 x; - EXPECT_NE(0, x()); -} - -TEST(NonsecureURBGBase, SeederWorksForU64) { - using U64 = - absl::random_internal::NonsecureURBGBase<SeederTestEngine<uint64_t>>; - - U64 x; - EXPECT_NE(0, x()); -} diff --git a/third_party/abseil_cpp/absl/random/internal/pcg_engine.h b/third_party/abseil_cpp/absl/random/internal/pcg_engine.h deleted file mode 100644 index 53c23fe1b492..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/pcg_engine.h +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_ -#define ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_ - -#include <type_traits> - -#include "absl/base/config.h" -#include "absl/meta/type_traits.h" -#include "absl/numeric/int128.h" -#include "absl/random/internal/fastmath.h" -#include "absl/random/internal/iostream_state_saver.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in -// C++. PCG combines a linear congruential generator (LCG) with output state -// mixing functions to generate each random variate. pcg_engine supports only a -// single sequence (oneseq), and does not support streams. -// -// pcg_engine is parameterized by two types: -// Params, which provides the multiplier and increment values; -// Mix, which mixes the state into the result. -// -template <typename Params, typename Mix> -class pcg_engine { - static_assert(std::is_same<typename Params::state_type, - typename Mix::state_type>::value, - "Class-template absl::pcg_engine must be parameterized by " - "Params and Mix with identical state_type"); - - static_assert(std::is_unsigned<typename Mix::result_type>::value, - "Class-template absl::pcg_engine must be parameterized by " - "an unsigned Mix::result_type"); - - using params_type = Params; - using mix_type = Mix; - using state_type = typename Mix::state_type; - - public: - // C++11 URBG interface: - using result_type = typename Mix::result_type; - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - explicit pcg_engine(uint64_t seed_value = 0) { seed(seed_value); } - - template <class SeedSequence, - typename = typename absl::enable_if_t< - !std::is_same<SeedSequence, pcg_engine>::value>> - explicit pcg_engine(SeedSequence&& seq) { - seed(seq); - } - - pcg_engine(const pcg_engine&) = default; - pcg_engine& operator=(const pcg_engine&) = default; - pcg_engine(pcg_engine&&) = default; - pcg_engine& operator=(pcg_engine&&) = default; - - result_type operator()() { - // Advance the LCG state, always using the new value to generate the output. - state_ = lcg(state_); - return Mix{}(state_); - } - - void seed(uint64_t seed_value = 0) { - state_type tmp = seed_value; - state_ = lcg(tmp + Params::increment()); - } - - template <class SeedSequence> - typename absl::enable_if_t< - !std::is_convertible<SeedSequence, uint64_t>::value, void> - seed(SeedSequence&& seq) { - reseed(seq); - } - - void discard(uint64_t count) { state_ = advance(state_, count); } - - bool operator==(const pcg_engine& other) const { - return state_ == other.state_; - } - - bool operator!=(const pcg_engine& other) const { return !(*this == other); } - - template <class CharT, class Traits> - friend typename absl::enable_if_t<(sizeof(state_type) == 16), - std::basic_ostream<CharT, Traits>&> - operator<<( - std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references) - const pcg_engine& engine) { - auto saver = random_internal::make_ostream_state_saver(os); - random_internal::stream_u128_helper<state_type> helper; - helper.write(pcg_engine::params_type::multiplier(), os); - os << os.fill(); - helper.write(pcg_engine::params_type::increment(), os); - os << os.fill(); - helper.write(engine.state_, os); - return os; - } - - template <class CharT, class Traits> - friend typename absl::enable_if_t<(sizeof(state_type) <= 8), - std::basic_ostream<CharT, Traits>&> - operator<<( - std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references) - const pcg_engine& engine) { - auto saver = random_internal::make_ostream_state_saver(os); - os << pcg_engine::params_type::multiplier() << os.fill(); - os << pcg_engine::params_type::increment() << os.fill(); - os << engine.state_; - return os; - } - - template <class CharT, class Traits> - friend typename absl::enable_if_t<(sizeof(state_type) == 16), - std::basic_istream<CharT, Traits>&> - operator>>( - std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references) - pcg_engine& engine) { // NOLINT(runtime/references) - random_internal::stream_u128_helper<state_type> helper; - auto mult = helper.read(is); - auto inc = helper.read(is); - auto tmp = helper.read(is); - if (mult != pcg_engine::params_type::multiplier() || - inc != pcg_engine::params_type::increment()) { - // signal failure by setting the failbit. - is.setstate(is.rdstate() | std::ios_base::failbit); - } - if (!is.fail()) { - engine.state_ = tmp; - } - return is; - } - - template <class CharT, class Traits> - friend typename absl::enable_if_t<(sizeof(state_type) <= 8), - std::basic_istream<CharT, Traits>&> - operator>>( - std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references) - pcg_engine& engine) { // NOLINT(runtime/references) - state_type mult{}, inc{}, tmp{}; - is >> mult >> inc >> tmp; - if (mult != pcg_engine::params_type::multiplier() || - inc != pcg_engine::params_type::increment()) { - // signal failure by setting the failbit. - is.setstate(is.rdstate() | std::ios_base::failbit); - } - if (!is.fail()) { - engine.state_ = tmp; - } - return is; - } - - private: - state_type state_; - - // Returns the linear-congruential generator next state. - static inline constexpr state_type lcg(state_type s) { - return s * Params::multiplier() + Params::increment(); - } - - // Returns the linear-congruential arbitrary seek state. - inline state_type advance(state_type s, uint64_t n) const { - state_type mult = Params::multiplier(); - state_type inc = Params::increment(); - state_type m = 1; - state_type i = 0; - while (n > 0) { - if (n & 1) { - m *= mult; - i = i * mult + inc; - } - inc = (mult + 1) * inc; - mult *= mult; - n >>= 1; - } - return m * s + i; - } - - template <class SeedSequence> - void reseed(SeedSequence& seq) { - using sequence_result_type = typename SeedSequence::result_type; - constexpr size_t kBufferSize = - sizeof(state_type) / sizeof(sequence_result_type); - sequence_result_type buffer[kBufferSize]; - seq.generate(std::begin(buffer), std::end(buffer)); - // Convert the seed output to a single state value. - state_type tmp = buffer[0]; - for (size_t i = 1; i < kBufferSize; i++) { - tmp <<= (sizeof(sequence_result_type) * 8); - tmp |= buffer[i]; - } - state_ = lcg(tmp + params_type::increment()); - } -}; - -// Parameterized implementation of the PCG 128-bit oneseq state. -// This provides state_type, multiplier, and increment for pcg_engine. -template <uint64_t kMultA, uint64_t kMultB, uint64_t kIncA, uint64_t kIncB> -class pcg128_params { - public: -#if ABSL_HAVE_INTRINSIC_INT128 - using state_type = __uint128_t; - static inline constexpr state_type make_u128(uint64_t a, uint64_t b) { - return (static_cast<__uint128_t>(a) << 64) | b; - } -#else - using state_type = absl::uint128; - static inline constexpr state_type make_u128(uint64_t a, uint64_t b) { - return absl::MakeUint128(a, b); - } -#endif - - static inline constexpr state_type multiplier() { - return make_u128(kMultA, kMultB); - } - static inline constexpr state_type increment() { - return make_u128(kIncA, kIncB); - } -}; - -// Implementation of the PCG xsl_rr_128_64 128-bit mixing function, which -// accepts an input of state_type and mixes it into an output of result_type. -struct pcg_xsl_rr_128_64 { -#if ABSL_HAVE_INTRINSIC_INT128 - using state_type = __uint128_t; -#else - using state_type = absl::uint128; -#endif - using result_type = uint64_t; - - inline uint64_t operator()(state_type state) { - // This is equivalent to the xsl_rr_128_64 mixing function. -#if ABSL_HAVE_INTRINSIC_INT128 - uint64_t rotate = static_cast<uint64_t>(state >> 122u); - state ^= state >> 64; - uint64_t s = static_cast<uint64_t>(state); -#else - uint64_t h = Uint128High64(state); - uint64_t rotate = h >> 58u; - uint64_t s = Uint128Low64(state) ^ h; -#endif - return random_internal::rotr(s, rotate); - } -}; - -// Parameterized implementation of the PCG 64-bit oneseq state. -// This provides state_type, multiplier, and increment for pcg_engine. -template <uint64_t kMult, uint64_t kInc> -class pcg64_params { - public: - using state_type = uint64_t; - static inline constexpr state_type multiplier() { return kMult; } - static inline constexpr state_type increment() { return kInc; } -}; - -// Implementation of the PCG xsh_rr_64_32 64-bit mixing function, which accepts -// an input of state_type and mixes it into an output of result_type. -struct pcg_xsh_rr_64_32 { - using state_type = uint64_t; - using result_type = uint32_t; - inline uint32_t operator()(uint64_t state) { - return random_internal::rotr( - static_cast<uint32_t>(((state >> 18) ^ state) >> 27), state >> 59); - } -}; - -// Stable pcg_engine implementations: -// This is a 64-bit generator using 128-bits of state. -// The output sequence is equivalent to Melissa O'Neil's pcg64_oneseq. -using pcg64_2018_engine = pcg_engine< - random_internal::pcg128_params<0x2360ed051fc65da4ull, 0x4385df649fccf645ull, - 0x5851f42d4c957f2d, 0x14057b7ef767814f>, - random_internal::pcg_xsl_rr_128_64>; - -// This is a 32-bit generator using 64-bits of state. -// This is equivalent to Melissa O'Neil's pcg32_oneseq. -using pcg32_2018_engine = pcg_engine< - random_internal::pcg64_params<0x5851f42d4c957f2dull, 0x14057b7ef767814full>, - random_internal::pcg_xsh_rr_64_32>; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/pcg_engine_test.cc b/third_party/abseil_cpp/absl/random/internal/pcg_engine_test.cc deleted file mode 100644 index 4d763e89eb58..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/pcg_engine_test.cc +++ /dev/null @@ -1,638 +0,0 @@ -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/pcg_engine.h" - -#include <algorithm> -#include <bitset> -#include <random> -#include <sstream> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/random/internal/explicit_seed_seq.h" -#include "absl/time/clock.h" - -#define UPDATE_GOLDEN 0 - -namespace { - -using absl::random_internal::ExplicitSeedSeq; -using absl::random_internal::pcg32_2018_engine; -using absl::random_internal::pcg64_2018_engine; - -template <typename EngineType> -class PCGEngineTest : public ::testing::Test {}; - -using EngineTypes = ::testing::Types<pcg64_2018_engine, pcg32_2018_engine>; - -TYPED_TEST_SUITE(PCGEngineTest, EngineTypes); - -TYPED_TEST(PCGEngineTest, VerifyReseedChangesAllValues) { - using engine_type = TypeParam; - using result_type = typename engine_type::result_type; - - const size_t kNumOutputs = 16; - engine_type engine; - - // MSVC emits error 2719 without the use of std::ref below. - // * formal parameter with __declspec(align('#')) won't be aligned - - { - std::seed_seq seq1{1, 2, 3, 4, 5, 6, 7}; - engine.seed(seq1); - } - result_type a[kNumOutputs]; - std::generate(std::begin(a), std::end(a), std::ref(engine)); - - { - std::random_device rd; - std::seed_seq seq2{rd(), rd(), rd()}; - engine.seed(seq2); - } - result_type b[kNumOutputs]; - std::generate(std::begin(b), std::end(b), std::ref(engine)); - - // Verify that two uncorrelated values have ~50% of there bits in common. Use - // a 10% margin-of-error to reduce flakiness. - size_t changed_bits = 0; - size_t unchanged_bits = 0; - size_t total_set = 0; - size_t total_bits = 0; - size_t equal_count = 0; - for (size_t i = 0; i < kNumOutputs; ++i) { - equal_count += (a[i] == b[i]) ? 1 : 0; - std::bitset<sizeof(result_type) * 8> bitset(a[i] ^ b[i]); - changed_bits += bitset.count(); - unchanged_bits += bitset.size() - bitset.count(); - - std::bitset<sizeof(result_type) * 8> a_set(a[i]); - std::bitset<sizeof(result_type) * 8> b_set(b[i]); - total_set += a_set.count() + b_set.count(); - total_bits += 2 * 8 * sizeof(result_type); - } - // On average, half the bits are changed between two calls. - EXPECT_LE(changed_bits, 0.60 * (changed_bits + unchanged_bits)); - EXPECT_GE(changed_bits, 0.40 * (changed_bits + unchanged_bits)); - - // verify using a quick normal-approximation to the binomial. - EXPECT_NEAR(total_set, total_bits * 0.5, 4 * std::sqrt(total_bits)) - << "@" << total_set / static_cast<double>(total_bits); - - // Also, A[i] == B[i] with probability (1/range) * N. - // Give this a pretty wide latitude, though. - const double kExpected = kNumOutputs / (1.0 * sizeof(result_type) * 8); - EXPECT_LE(equal_count, 1.0 + kExpected); -} - -// Number of values that needs to be consumed to clean two sizes of buffer -// and trigger third refresh. (slightly overestimates the actual state size). -constexpr size_t kTwoBufferValues = 16; - -TYPED_TEST(PCGEngineTest, VerifyDiscard) { - using engine_type = TypeParam; - - for (size_t num_used = 0; num_used < kTwoBufferValues; ++num_used) { - engine_type engine_used; - for (size_t i = 0; i < num_used; ++i) { - engine_used(); - } - - for (size_t num_discard = 0; num_discard < kTwoBufferValues; - ++num_discard) { - engine_type engine1 = engine_used; - engine_type engine2 = engine_used; - for (size_t i = 0; i < num_discard; ++i) { - engine1(); - } - engine2.discard(num_discard); - for (size_t i = 0; i < kTwoBufferValues; ++i) { - const auto r1 = engine1(); - const auto r2 = engine2(); - ASSERT_EQ(r1, r2) << "used=" << num_used << " discard=" << num_discard; - } - } - } -} - -TYPED_TEST(PCGEngineTest, StreamOperatorsResult) { - using engine_type = TypeParam; - - std::wostringstream os; - std::wistringstream is; - engine_type engine; - - EXPECT_EQ(&(os << engine), &os); - EXPECT_EQ(&(is >> engine), &is); -} - -TYPED_TEST(PCGEngineTest, StreamSerialization) { - using engine_type = TypeParam; - - for (size_t discard = 0; discard < kTwoBufferValues; ++discard) { - ExplicitSeedSeq seed_sequence{12, 34, 56}; - engine_type engine(seed_sequence); - engine.discard(discard); - - std::stringstream stream; - stream << engine; - - engine_type new_engine; - stream >> new_engine; - for (size_t i = 0; i < 64; ++i) { - EXPECT_EQ(engine(), new_engine()) << " " << i; - } - } -} - -constexpr size_t kNumGoldenOutputs = 127; - -// This test is checking if randen_engine is meets interface requirements -// defined in [rand.req.urbg]. -TYPED_TEST(PCGEngineTest, RandomNumberEngineInterface) { - using engine_type = TypeParam; - - using E = engine_type; - using T = typename E::result_type; - - static_assert(std::is_copy_constructible<E>::value, - "engine_type must be copy constructible"); - - static_assert(absl::is_copy_assignable<E>::value, - "engine_type must be copy assignable"); - - static_assert(std::is_move_constructible<E>::value, - "engine_type must be move constructible"); - - static_assert(absl::is_move_assignable<E>::value, - "engine_type must be move assignable"); - - static_assert(std::is_same<decltype(std::declval<E>()()), T>::value, - "return type of operator() must be result_type"); - - // Names after definition of [rand.req.urbg] in C++ standard. - // e us a value of E - // v is a lvalue of E - // x, y are possibly const values of E - // s is a value of T - // q is a value satisfying requirements of seed_sequence - // z is a value of type unsigned long long - // os is a some specialization of basic_ostream - // is is a some specialization of basic_istream - - E e, v; - const E x, y; - T s = 1; - std::seed_seq q{1, 2, 3}; - unsigned long long z = 1; // NOLINT(runtime/int) - std::wostringstream os; - std::wistringstream is; - - E{}; - E{x}; - E{s}; - E{q}; - - e.seed(); - - // MSVC emits error 2718 when using EXPECT_EQ(e, x) - // * actual parameter with __declspec(align('#')) won't be aligned - EXPECT_TRUE(e == x); - - e.seed(q); - { - E tmp(q); - EXPECT_TRUE(e == tmp); - } - - e(); - { - E tmp(q); - EXPECT_TRUE(e != tmp); - } - - e.discard(z); - - static_assert(std::is_same<decltype(x == y), bool>::value, - "return type of operator== must be bool"); - - static_assert(std::is_same<decltype(x != y), bool>::value, - "return type of operator== must be bool"); -} - -TYPED_TEST(PCGEngineTest, RandenEngineSFINAETest) { - using engine_type = TypeParam; - using result_type = typename engine_type::result_type; - - { - engine_type engine(result_type(1)); - engine.seed(result_type(1)); - } - - { - result_type n = 1; - engine_type engine(n); - engine.seed(n); - } - - { - engine_type engine(1); - engine.seed(1); - } - - { - int n = 1; - engine_type engine(n); - engine.seed(n); - } - - { - std::seed_seq seed_seq; - engine_type engine(seed_seq); - engine.seed(seed_seq); - } - - { - engine_type engine{std::seed_seq()}; - engine.seed(std::seed_seq()); - } -} - -// ------------------------------------------------------------------ -// Stability tests for pcg64_2018_engine -// ------------------------------------------------------------------ -TEST(PCG642018EngineTest, VerifyGolden) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0x01070196e695f8f1, 0x703ec840c59f4493, 0xe54954914b3a44fa, - 0x96130ff204b9285e, 0x7d9fdef535ceb21a, 0x666feed42e1219a0, - 0x981f685721c8326f, 0xad80710d6eab4dda, 0xe202c480b037a029, - 0x5d3390eaedd907e2, 0x0756befb39c6b8aa, 0x1fb44ba6634d62a3, - 0x8d20423662426642, 0x34ea910167a39fb4, 0x93010b43a80d0ab6, - 0x663db08a98fc568a, 0x720b0a1335956fae, 0x2c35483e31e1d3ba, - 0x429f39776337409d, 0xb46d99e638687344, 0x105370b96aedcaee, - 0x3999e92f811cff71, 0xd230f8bcb591cfc9, 0x0dce3db2ba7bdea5, - 0xcf2f52c91eec99af, 0x2bc7c24a8b998a39, 0xbd8af1b0d599a19c, - 0x56bc45abc66059f5, 0x170a46dc170f7f1e, 0xc25daf5277b85fad, - 0xe629c2e0c948eadb, 0x1720a796915542ed, 0x22fb0caa4f909951, - 0x7e0c0f4175acd83d, 0xd9fcab37ff2a860c, 0xab2280fb2054bad1, - 0x58e8a06f37fa9e99, 0xc3a52a30b06528c7, 0x0175f773a13fc1bd, - 0x731cfc584b00e840, 0x404cc7b2648069cb, 0x5bc29153b0b7f783, - 0x771310a38cc999d1, 0x766a572f0a71a916, 0x90f450fb4fc48348, - 0xf080ea3e1c7b1a0d, 0x15471a4507d66a44, 0x7d58e55a78f3df69, - 0x0130a094576ac99c, 0x46669cb2d04b1d87, 0x17ab5bed20191840, - 0x95b177d260adff3e, 0x025fb624b6ee4c07, 0xb35de4330154a95f, - 0xe8510fff67e24c79, 0x132c3cbcd76ed2d3, 0x35e7cc145a093904, - 0x9f5b5b5f81583b79, 0x3ee749a533966233, 0x4af85886cdeda8cd, - 0x0ca5380ecb3ef3aa, 0x4f674eb7661d3192, 0x88a29aad00cd7733, - 0x70b627ca045ffac6, 0x5912b43ea887623d, 0x95dc9fc6f62cf221, - 0x926081a12a5c905b, 0x9c57d4cd7dfce651, 0x85ab2cbf23e3bb5d, - 0xc5cd669f63023152, 0x3067be0fad5d898e, 0x12b56f444cb53d05, - 0xbc2e5a640c3434fc, 0x9280bff0e4613fe1, 0x98819094c528743e, - 0x999d1c98d829df33, 0x9ff82a012dc89242, 0xf99183ed39c8be94, - 0xf0f59161cd421c55, 0x3c705730c2f6c48d, 0x66ad85c6e9278a61, - 0x2a3428e4a428d5d0, 0x79207d68fd04940d, 0xea7f2b402edc8430, - 0xa06b419ac857f63b, 0xcb1dd0e6fbc47e1c, 0x4f55229200ada6a4, - 0x9647b5e6359c927f, 0x30bf8f9197c7efe5, 0xa79519529cc384d0, - 0xbb22c4f339ad6497, 0xd7b9782f59d14175, 0x0dff12fff2ec0118, - 0xa331ad8305343a7c, 0x48dad7e3f17e0862, 0x324c6fb3fd3c9665, - 0xf0e4350e7933dfc4, 0x7ccda2f30b8b03b6, 0xa0afc6179005de40, - 0xee65da6d063b3a30, 0xb9506f42f2bfe87a, 0xc9a2e26b0ef5baa0, - 0x39fa9d4f495011d6, 0xbecc21a45d023948, 0x6bf484c6593f737f, - 0x8065e0070cadc3b7, 0x9ef617ed8d419799, 0xac692cf8c233dd15, - 0xd2ed87583c4ebb98, 0xad95ba1bebfedc62, 0x9b60b160a8264e43, - 0x0bc8c45f71fcf25b, 0x4a78035cdf1c9931, 0x4602dc106667e029, - 0xb335a3c250498ac8, 0x0256ebc4df20cab8, 0x0c61efd153f0c8d9, - 0xe5d0150a4f806f88, 0x99d6521d351e7d87, 0x8d4888c9f80f4325, - 0x106c5735c1ba868d, 0x73414881b880a878, 0x808a9a58a3064751, - 0x339a29f3746de3d5, 0x5410d7fa4f873896, 0xd84623c81d7b8a03, - 0x1f7c7e7a7f47f462, - }; - - pcg64_2018_engine engine(0); -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%016lx, ", engine()); - if (i % 3 == 2) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(PCG642018EngineTest, VerifyGoldenSeeded) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0xb03988f1e39691ee, 0xbd2a1eb5ac31e97a, 0x8f00d6d433634d02, - 0x1823c28d483d5776, 0x000c3ee3e1aeb74a, 0xfa82ef27a4f3df9c, - 0xc6f382308654e454, 0x414afb1a238996c2, 0x4703a4bc252eb411, - 0x99d64f62c8f7f654, 0xbb07ebe11a34fa44, 0x79eb06a363c06131, - 0xf66ad3756f1c6b21, 0x130c01d5e869f457, 0x5ca2b9963aecbc81, - 0xfef7bebc1de27e6c, 0x1d174faa5ed2cdbf, 0xd75b7a773f2bb889, - 0xc35c872327a170a5, 0x46da6d88646a42fe, 0x4622985e0442dae2, - 0xbe3cbd67297f1f9b, 0xe7c37b4a4798bfd1, 0x173d5dfad15a25c3, - 0x0eb6849ba2961522, 0xb0ff7246e6700d73, 0x88cb9c42d3afa577, - 0xb609731dbd94d917, 0xd3941cda04b40081, 0x28d140f7409bea3a, - 0x3c96699a920a124a, 0xdb28be521958b2fd, 0x0a3f44db3d4c5124, - 0x7ac8e60ba13b70d2, 0x75f03a41ded5195a, 0xaed10ac7c4e4825d, - 0xb92a3b18aadb7adc, 0xda45e0081f2bca46, 0x74d39ab3753143fc, - 0xb686038018fac9ca, 0x4cc309fe99542dbb, 0xf3e1a4fcb311097c, - 0x58763d6fa698d69d, 0xd11c365dbecd8d60, 0x2c15d55725b1dee7, - 0x89805f254d85658c, 0x2374c44dfc62158b, 0x9a8350fa7995328d, - 0x198f838970cf91da, 0x96aff569562c0e53, 0xd76c8c52b7ec6e3f, - 0x23a01cd9ae4baa81, 0x3adb366b6d02a893, 0xb3313e2a4c5b333f, - 0x04c11230b96a5425, 0x1f7f7af04787d571, 0xaddb019365275ec7, - 0x5c960468ccb09f42, 0x8438db698c69a44a, 0x492be1e46111637e, - 0x9c6c01e18100c610, 0xbfe48e75b7d0aceb, 0xb5e0b89ec1ce6a00, - 0x9d280ecbc2fe8997, 0x290d9e991ba5fcab, 0xeec5bec7d9d2a4f0, - 0x726e81488f19150e, 0x1a6df7955a7e462c, 0x37a12d174ba46bb5, - 0x3cdcdffd96b1b5c5, 0x2c5d5ac10661a26e, 0xa742ed18f22e50c4, - 0x00e0ed88ff0d8a35, 0x3d3c1718cb1efc0b, 0x1d70c51ffbccbf11, - 0xfbbb895132a4092f, 0x619d27f2fb095f24, 0x69af68200985e5c4, - 0xbee4885f57373f8d, 0x10b7a6bfe0587e40, 0xa885e6cf2f7e5f0a, - 0x59f879464f767550, 0x24e805d69056990d, 0x860970b911095891, - 0xca3189954f84170d, 0x6652a5edd4590134, 0x5e1008cef76174bf, - 0xcbd417881f2bcfe5, 0xfd49fc9d706ecd17, 0xeebf540221ebd066, - 0x46af7679464504cb, 0xd4028486946956f1, 0xd4f41864b86c2103, - 0x7af090e751583372, 0x98cdaa09278cb642, 0xffd42b921215602f, - 0x1d05bec8466b1740, 0xf036fa78a0132044, 0x787880589d1ecc78, - 0x5644552cfef33230, 0x0a97e275fe06884b, 0x96d1b13333d470b5, - 0xc8b3cdad52d3b034, 0x091357b9db7376fd, 0xa5fe4232555edf8c, - 0x3371bc3b6ada76b5, 0x7deeb2300477c995, 0x6fc6d4244f2849c1, - 0x750e8cc797ca340a, 0x81728613cd79899f, 0x3467f4ee6f9aeb93, - 0x5ef0a905f58c640f, 0x432db85e5101c98a, 0x6488e96f46ac80c2, - 0x22fddb282625048c, 0x15b287a0bc2d4c5d, 0xa7e2343ef1f28bce, - 0xc87ee1aa89bed09e, 0x220610107812c5e9, 0xcbdab6fcd640f586, - 0x8d41047970928784, 0x1aa431509ec1ade0, 0xac3f0be53f518ddc, - 0x16f4428ad81d0cbb, 0x675b13c2736fc4bb, 0x6db073afdd87e32d, - 0x572f3ca2f1a078c6, - }; - - ExplicitSeedSeq seed_sequence{12, 34, 56}; - pcg64_2018_engine engine(seed_sequence); -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%016lx, ", engine()); - if (i % 3 == 2) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(seed_sequence); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(PCG642018EngineTest, VerifyGoldenFromDeserializedEngine) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0xdd425b47b4113dea, 0x1b07176479d444b0, 0x6b391027586f2e42, - 0xa166f2b15f4a2143, 0xffb6dbd7a179ee97, 0xb2c00035365bf0b1, - 0x8fbb518b45855521, 0xfc789a55ddf87c3b, 0x429531f0f17ff355, - 0xbe708560d603d283, 0x5bff415175c5cb6b, 0xe813491f4ad45394, - 0xa853f4506d55880d, 0x7e538453e568172e, 0xe101f1e098ddd0ec, - 0x6ee31266ee4c766d, 0xa8786d92d66b39d7, 0xfee622a2acf5e5b0, - 0x5fe8e82c102fa7b3, 0x01f10be4cdb53c9d, 0xbe0545366f857022, - 0x12e74f010a339bca, 0xb10d85ca40d5ce34, 0xe80d6feba5054875, - 0x2b7c1ee6d567d4ee, 0x2a9cd043bfd03b66, 0x5cfc531bd239f3f1, - 0x1c4734e4647d70f5, 0x85a8f60f006b5760, 0x6a4239ce76dca387, - 0x8da0f86d7339335c, 0xf055b0468551374d, 0x486e8567e9bea9a0, - 0x4cb531b8405192dd, 0xf813b1ee3157110b, 0x214c2a664a875d8e, - 0x74531237b29b35f7, 0xa6f0267bb77a771e, 0x64b552bff54184a4, - 0xa2d6f7af2d75b6fc, 0x460a10018e03b5ab, 0x76fd1fdcb81d0800, - 0x76f5f81805070d9d, 0x1fb75cb1a70b289a, 0x9dfd25a022c4b27f, - 0x9a31a14a80528e9e, 0x910dc565ddc25820, 0xd6aef8e2b0936c10, - 0xe1773c507fe70225, 0xe027fd7aadd632bc, 0xc1fecb427089c8b8, - 0xb5c74c69fa9dbf26, 0x71bf9b0e4670227d, 0x25f48fad205dcfdd, - 0x905248ec4d689c56, 0x5c2b7631b0de5c9d, 0x9f2ee0f8f485036c, - 0xfd6ce4ebb90bf7ea, 0xd435d20046085574, 0x6b7eadcb0625f986, - 0x679d7d44b48be89e, 0x49683b8e1cdc49de, 0x4366cf76e9a2f4ca, - 0x54026ec1cdad7bed, 0xa9a04385207f28d3, 0xc8e66de4eba074b2, - 0x40b08c42de0f4cc0, 0x1d4c5e0e93c5bbc0, 0x19b80792e470ae2d, - 0x6fcaaeaa4c2a5bd9, 0xa92cb07c4238438e, 0x8bb5c918a007e298, - 0x7cd671e944874cf4, 0x88166470b1ba3cac, 0xd013d476eaeeade6, - 0xcee416947189b3c3, 0x5d7c16ab0dce6088, 0xd3578a5c32b13d27, - 0x3875db5adc9cc973, 0xfbdaba01c5b5dc56, 0xffc4fdd391b231c3, - 0x2334520ecb164fec, 0x361c115e7b6de1fa, 0xeee58106cc3563d7, - 0x8b7f35a8db25ebb8, 0xb29d00211e2cafa6, 0x22a39fe4614b646b, - 0x92ca6de8b998506d, 0x40922fe3d388d1db, 0x9da47f1e540f802a, - 0x811dceebf16a25db, 0xf6524ae22e0e53a9, 0x52d9e780a16eb99d, - 0x4f504286bb830207, 0xf6654d4786bd5cc3, 0x00bd98316003a7e1, - 0xefda054a6ab8f5f3, 0x46cfb0f4c1872827, 0xc22b316965c0f3b2, - 0xd1a28087c7e7562a, 0xaa4f6a094b7f5cff, 0xfe2bc853a041f7da, - 0xe9d531402a83c3ba, 0xe545d8663d3ce4dd, 0xfa2dcd7d91a13fa8, - 0xda1a080e52a127b8, 0x19c98f1f809c3d84, 0x2cef109af4678c88, - 0x53462accab3b9132, 0x176b13a80415394e, 0xea70047ef6bc178b, - 0x57bca80506d6dcdf, 0xd853ba09ff09f5c4, 0x75f4df3a7ddd4775, - 0x209c367ade62f4fe, 0xa9a0bbc74d5f4682, 0x5dfe34bada86c21a, - 0xc2c05bbcd38566d1, 0x6de8088e348c916a, 0x6a7001c6000c2196, - 0xd9fb51865fc4a367, 0x12f320e444ece8ff, 0x6d56f7f793d65035, - 0x138f31b7a865f8aa, 0x58fc68b4026b9adf, 0xcd48954b79fb6436, - 0x27dfce4a0232af87, - }; - -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - std::seed_seq seed_sequence{1, 2, 3}; - pcg64_2018_engine engine(seed_sequence); - std::ostringstream stream; - stream << engine; - auto str = stream.str(); - printf("%s\n\n", str.c_str()); - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%016lx, ", engine()); - if (i % 3 == 2) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - pcg64_2018_engine engine; - std::istringstream stream( - "2549297995355413924 4865540595714422341 6364136223846793005 " - "1442695040888963407 18088519957565336995 4845369368158826708"); - stream >> engine; - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -// ------------------------------------------------------------------ -// Stability tests for pcg32_2018_engine -// ------------------------------------------------------------------ -TEST(PCG322018EngineTest, VerifyGolden) { - constexpr uint32_t kGolden[kNumGoldenOutputs] = { - 0x7a7ecbd9, 0x89fd6c06, 0xae646aa8, 0xcd3cf945, 0x6204b303, 0x198c8585, - 0x49fce611, 0xd1e9297a, 0x142d9440, 0xee75f56b, 0x473a9117, 0xe3a45903, - 0xbce807a1, 0xe54e5f4d, 0x497d6c51, 0x61829166, 0xa740474b, 0x031912a8, - 0x9de3defa, 0xd266dbf1, 0x0f38bebb, 0xec3c4f65, 0x07c5057d, 0xbbce03c8, - 0xfd2ac7a8, 0xffcf4773, 0x5b10affb, 0xede1c842, 0xe22b01b7, 0xda133c8c, - 0xaf89b0f4, 0x25d1b8bc, 0x9f625482, 0x7bfd6882, 0x2e2210c0, 0x2c8fb9a6, - 0x42cb3b83, 0x40ce0dab, 0x644a3510, 0x36230ef2, 0xe2cb6d43, 0x1012b343, - 0x746c6c9f, 0x36714cf8, 0xed1f5026, 0x8bbbf83e, 0xe98710f4, 0x8a2afa36, - 0x09035349, 0x6dc1a487, 0x682b634b, 0xc106794f, 0x7dd78beb, 0x628c262b, - 0x852fb232, 0xb153ac4c, 0x4f169d1b, 0xa69ab774, 0x4bd4b6f2, 0xdc351dd3, - 0x93ff3c8c, 0xa30819ab, 0xff07758c, 0x5ab13c62, 0xd16d7fb5, 0xc4950ffa, - 0xd309ae49, 0xb9677a87, 0x4464e317, 0x90dc44f1, 0xc694c1d4, 0x1d5e1168, - 0xadf37a2d, 0xda38990d, 0x1ec4bd33, 0x36ca25ce, 0xfa0dc76a, 0x968a9d43, - 0x6950ac39, 0xdd3276bc, 0x06d5a71e, 0x1f6f282d, 0x5c626c62, 0xdde3fc31, - 0x152194ce, 0xc35ed14c, 0xb1f7224e, 0x47f76bb8, 0xb34fdd08, 0x7011395e, - 0x162d2a49, 0x0d1bf09f, 0x9428a952, 0x03c5c344, 0xd3525616, 0x7816fff3, - 0x6bceb8a8, 0x8345a081, 0x366420fd, 0x182abeda, 0x70f82745, 0xaf15ded8, - 0xc7f52ca2, 0xa98db9c5, 0x919d99ba, 0x9c376c1c, 0xed8d34c2, 0x716ae9f5, - 0xef062fa5, 0xee3b6c56, 0x52325658, 0x61afa9c3, 0xfdaf02f0, 0x961cf3ab, - 0x9f291565, 0x4fbf3045, 0x0590c899, 0xde901385, 0x45005ffb, 0x509db162, - 0x262fa941, 0x4c421653, 0x4b17c21e, 0xea0d1530, 0xde803845, 0x61bfd515, - 0x438523ef, - }; - - pcg32_2018_engine engine(0); -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%08x, ", engine()); - if (i % 6 == 5) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(PCG322018EngineTest, VerifyGoldenSeeded) { - constexpr uint32_t kGolden[kNumGoldenOutputs] = { - 0x60b5a64c, 0x978502f9, 0x80a75f60, 0x241f1158, 0xa4cd1dbb, 0xe7284017, - 0x3b678da5, 0x5223ec99, 0xe4bdd5d9, 0x72190e6d, 0xe6e702c9, 0xff80c768, - 0xcf126ed3, 0x1fbd20ab, 0x60980489, 0xbc72bf89, 0x407ac6c0, 0x00bf3c51, - 0xf9087897, 0x172e4eb6, 0xe9e4f443, 0x1a6098bf, 0xbf44f8c2, 0xdd84a0e5, - 0xd9a52364, 0xc0e2e786, 0x061ae2ba, 0x9facb8e3, 0x6109432d, 0xd4e0a013, - 0xbd8eb9a6, 0x7e86c3b6, 0x629c0e68, 0x05337430, 0xb495b9f4, 0x11ccd65d, - 0xb578db25, 0x66f1246d, 0x6ef20a7f, 0x5e429812, 0x11772130, 0xb944b5c2, - 0x01624128, 0xa2385ab7, 0xd3e10d35, 0xbe570ec3, 0xc951656f, 0xbe8944a0, - 0x7be41062, 0x5709f919, 0xd745feda, 0x9870b9ae, 0xb44b8168, 0x19e7683b, - 0xded8017f, 0xc6e4d544, 0x91ae4225, 0xd6745fba, 0xb992f284, 0x65b12b33, - 0xa9d5fdb4, 0xf105ce1a, 0x35ca1a6e, 0x2ff70dd0, 0xd8335e49, 0xfb71ddf2, - 0xcaeabb89, 0x5c6f5f84, 0x9a811a7d, 0xbcecbbd1, 0x0f661ba0, 0x9ad93b9d, - 0xedd23e0b, 0x42062f48, 0xd38dd7e4, 0x6cd63c9c, 0x640b98ae, 0x4bff5653, - 0x12626371, 0x13266017, 0xe7a698d8, 0x39c74667, 0xe8fdf2e3, 0x52803bf8, - 0x2af6895b, 0x91335b7b, 0x699e4961, 0x00a40fff, 0x253ff2b6, 0x4a6cf672, - 0x9584e85f, 0xf2a5000c, 0x4d58aba8, 0xb8513e6a, 0x767fad65, 0x8e326f9e, - 0x182f15a1, 0x163dab52, 0xdf99c780, 0x047282a1, 0xee4f90dd, 0xd50394ae, - 0x6c9fd5f0, 0xb06a9194, 0x387e3840, 0x04a9487b, 0xf678a4c2, 0xd0a78810, - 0xd502c97e, 0xd6a9b12a, 0x4accc5dc, 0x416ed53e, 0x50411536, 0xeeb89c24, - 0x813a7902, 0x034ebca6, 0xffa52e7c, 0x7ecd3d0e, 0xfa37a0d2, 0xb1fbe2c1, - 0xb7efc6d1, 0xefa4ccee, 0xf6f80424, 0x2283f3d9, 0x68732284, 0x94f3b5c8, - 0xbbdeceb9, - }; - - ExplicitSeedSeq seed_sequence{12, 34, 56}; - pcg32_2018_engine engine(seed_sequence); -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%08x, ", engine()); - if (i % 6 == 5) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(seed_sequence); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(PCG322018EngineTest, VerifyGoldenFromDeserializedEngine) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0x780f7042, 0xba137215, 0x43ab6f22, 0x0cb55f46, 0x44b2627d, 0x835597af, - 0xea973ea1, 0x0d2abd35, 0x4fdd601c, 0xac4342fe, 0x7db7e93c, 0xe56ebcaf, - 0x3596470a, 0x7770a9ad, 0x9b893320, 0x57db3415, 0xb432de54, 0xa02baf71, - 0xa256aadb, 0x88921fc7, 0xa35fa6b3, 0xde3eca46, 0x605739a7, 0xa890b82b, - 0xe457b7ad, 0x335fb903, 0xeb06790c, 0xb3c54bf6, 0x6141e442, 0xa599a482, - 0xb78987cc, 0xc61dfe9d, 0x0f1d6ace, 0x17460594, 0x8f6a5061, 0x083dc354, - 0xe9c337fb, 0xcfd105f7, 0x926764b6, 0x638d24dc, 0xeaac650a, 0x67d2cb9c, - 0xd807733c, 0x205fc52e, 0xf5399e2e, 0x6c46ddcc, 0xb603e875, 0xce113a25, - 0x3c8d4813, 0xfb584db8, 0xf6d255ff, 0xea80954f, 0x42e8be85, 0xb2feee72, - 0x62bd8d16, 0x1be4a142, 0x97dca1a4, 0xdd6e7333, 0xb2caa20e, 0xa12b1588, - 0xeb3a5a1a, 0x6fa5ba89, 0x077ea931, 0x8ddb1713, 0x0dd03079, 0x2c2ba965, - 0xa77fac17, 0xc8325742, 0x8bb893bf, 0xc2315741, 0xeaceee92, 0x81dd2ee2, - 0xe5214216, 0x1b9b8fb2, 0x01646d03, 0x24facc25, 0xd8c0e0bb, 0xa33fe106, - 0xf34fe976, 0xb3b4b44e, 0x65618fed, 0x032c6192, 0xa9dd72ce, 0xf391887b, - 0xf41c6a6e, 0x05c4bd6d, 0x37fa260e, 0x46b05659, 0xb5f6348a, 0x62d26d89, - 0x39f6452d, 0xb17b30a2, 0xbdd82743, 0x38ecae3b, 0xfe90f0a2, 0xcb2d226d, - 0xcf8a0b1c, 0x0eed3d4d, 0xa1f69cfc, 0xd7ac3ba5, 0xce9d9a6b, 0x121deb4c, - 0x4a0d03f3, 0xc1821ed1, 0x59c249ac, 0xc0abb474, 0x28149985, 0xfd9a82ba, - 0x5960c3b2, 0xeff00cba, 0x6073aa17, 0x25dc0919, 0x9976626e, 0xdd2ccc33, - 0x39ecb6ec, 0xc6e15d13, 0xfac94cfd, 0x28cfd34f, 0xf2d2c32d, 0x51c23d08, - 0x4fdb2f48, 0x97baa807, 0xf2c1004c, 0xc4ae8136, 0x71f31c94, 0x8c92d601, - 0x36caf5cd, - }; - -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - std::seed_seq seed_sequence{1, 2, 3}; - pcg32_2018_engine engine(seed_sequence); - std::ostringstream stream; - stream << engine; - auto str = stream.str(); - printf("%s\n\n", str.c_str()); - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%08x, ", engine()); - if (i % 6 == 5) { - printf("\n"); - } - } - printf("\n\n\n"); - - EXPECT_FALSE(true); -#else - pcg32_2018_engine engine; - std::istringstream stream( - "6364136223846793005 1442695040888963407 6537028157270659894"); - stream >> engine; - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/platform.h b/third_party/abseil_cpp/absl/random/internal/platform.h deleted file mode 100644 index bbdb4e620816..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/platform.h +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_PLATFORM_H_ -#define ABSL_RANDOM_INTERNAL_PLATFORM_H_ - -// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate -// symbols from arbitrary system and other headers, since it may be built -// with different flags from other targets, using different levels of -// optimization, potentially introducing ODR violations. - -// ----------------------------------------------------------------------------- -// Platform Feature Checks -// ----------------------------------------------------------------------------- - -// Currently supported operating systems and associated preprocessor -// symbols: -// -// Linux and Linux-derived __linux__ -// Android __ANDROID__ (implies __linux__) -// Linux (non-Android) __linux__ && !__ANDROID__ -// Darwin (macOS and iOS) __APPLE__ -// Akaros (http://akaros.org) __ros__ -// Windows _WIN32 -// NaCL __native_client__ -// AsmJS __asmjs__ -// WebAssembly __wasm__ -// Fuchsia __Fuchsia__ -// -// Note that since Android defines both __ANDROID__ and __linux__, one -// may probe for either Linux or Android by simply testing for __linux__. -// -// NOTE: For __APPLE__ platforms, we use #include <TargetConditionals.h> -// to distinguish os variants. -// -// http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system - -#if defined(__APPLE__) -#include <TargetConditionals.h> -#endif - -// ----------------------------------------------------------------------------- -// Architecture Checks -// ----------------------------------------------------------------------------- - -// These preprocessor directives are trying to determine CPU architecture, -// including necessary headers to support hardware AES. -// -// ABSL_ARCH_{X86/PPC/ARM} macros determine the platform. -#if defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || \ - defined(_M_X64) -#define ABSL_ARCH_X86_64 -#elif defined(__i386) || defined(_M_IX86) -#define ABSL_ARCH_X86_32 -#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) -#define ABSL_ARCH_AARCH64 -#elif defined(__arm__) || defined(__ARMEL__) || defined(_M_ARM) -#define ABSL_ARCH_ARM -#elif defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \ - defined(__ppc__) || defined(__PPC__) -#define ABSL_ARCH_PPC -#else -// Unsupported architecture. -// * https://sourceforge.net/p/predef/wiki/Architectures/ -// * https://msdn.microsoft.com/en-us/library/b0084kay.aspx -// * for gcc, clang: "echo | gcc -E -dM -" -#endif - -// ----------------------------------------------------------------------------- -// Attribute Checks -// ----------------------------------------------------------------------------- - -// ABSL_RANDOM_INTERNAL_RESTRICT annotates whether pointers may be considered -// to be unaliased. -#if defined(__clang__) || defined(__GNUC__) -#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict__ -#elif defined(_MSC_VER) -#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict -#else -#define ABSL_RANDOM_INTERNAL_RESTRICT -#endif - -// ABSL_HAVE_ACCELERATED_AES indicates whether the currently active compiler -// flags (e.g. -maes) allow using hardware accelerated AES instructions, which -// implies us assuming that the target platform supports them. -#define ABSL_HAVE_ACCELERATED_AES 0 - -#if defined(ABSL_ARCH_X86_64) - -#if defined(__AES__) || defined(__AVX__) -#undef ABSL_HAVE_ACCELERATED_AES -#define ABSL_HAVE_ACCELERATED_AES 1 -#endif - -#elif defined(ABSL_ARCH_PPC) - -// Rely on VSX and CRYPTO extensions for vcipher on PowerPC. -#if (defined(__VEC__) || defined(__ALTIVEC__)) && defined(__VSX__) && \ - defined(__CRYPTO__) -#undef ABSL_HAVE_ACCELERATED_AES -#define ABSL_HAVE_ACCELERATED_AES 1 -#endif - -#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64) - -// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf -// Rely on NEON+CRYPTO extensions for ARM. -#if defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO) -#undef ABSL_HAVE_ACCELERATED_AES -#define ABSL_HAVE_ACCELERATED_AES 1 -#endif - -#endif - -// NaCl does not allow AES. -#if defined(__native_client__) -#undef ABSL_HAVE_ACCELERATED_AES -#define ABSL_HAVE_ACCELERATED_AES 0 -#endif - -// ABSL_RANDOM_INTERNAL_AES_DISPATCH indicates whether the currently active -// platform has, or should use run-time dispatch for selecting the -// acclerated Randen implementation. -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0 - -#if defined(ABSL_ARCH_X86_64) -// Dispatch is available on x86_64 -#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1 -#elif defined(__linux__) && defined(ABSL_ARCH_PPC) -// Or when running linux PPC -#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1 -#elif defined(__linux__) && defined(ABSL_ARCH_AARCH64) -// Or when running linux AArch64 -#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1 -#elif defined(__linux__) && defined(ABSL_ARCH_ARM) && (__ARM_ARCH >= 8) -// Or when running linux ARM v8 or higher. -// (This captures a lot of Android configurations.) -#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1 -#endif - -// NaCl does not allow dispatch. -#if defined(__native_client__) -#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0 -#endif - -// iOS does not support dispatch, even on x86, since applications -// should be bundled as fat binaries, with a different build tailored for -// each specific supported platform/architecture. -#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ - (defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR) -#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH -#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0 -#endif - -#endif // ABSL_RANDOM_INTERNAL_PLATFORM_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/pool_urbg.cc b/third_party/abseil_cpp/absl/random/internal/pool_urbg.cc deleted file mode 100644 index 5bee530770eb..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/pool_urbg.cc +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/pool_urbg.h" - -#include <algorithm> -#include <atomic> -#include <cstdint> -#include <cstring> -#include <iterator> - -#include "absl/base/attributes.h" -#include "absl/base/call_once.h" -#include "absl/base/config.h" -#include "absl/base/internal/endian.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/spinlock.h" -#include "absl/base/internal/sysinfo.h" -#include "absl/base/internal/unaligned_access.h" -#include "absl/base/optimization.h" -#include "absl/random/internal/randen.h" -#include "absl/random/internal/seed_material.h" -#include "absl/random/seed_gen_exception.h" - -using absl::base_internal::SpinLock; -using absl::base_internal::SpinLockHolder; - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -// RandenPoolEntry is a thread-safe pseudorandom bit generator, implementing a -// single generator within a RandenPool<T>. It is an internal implementation -// detail, and does not aim to conform to [rand.req.urng]. -// -// NOTE: There are alignment issues when used on ARM, for instance. -// See the allocation code in PoolAlignedAlloc(). -class RandenPoolEntry { - public: - static constexpr size_t kState = RandenTraits::kStateBytes / sizeof(uint32_t); - static constexpr size_t kCapacity = - RandenTraits::kCapacityBytes / sizeof(uint32_t); - - void Init(absl::Span<const uint32_t> data) { - SpinLockHolder l(&mu_); // Always uncontested. - std::copy(data.begin(), data.end(), std::begin(state_)); - next_ = kState; - } - - // Copy bytes into out. - void Fill(uint8_t* out, size_t bytes) ABSL_LOCKS_EXCLUDED(mu_); - - // Returns random bits from the buffer in units of T. - template <typename T> - inline T Generate() ABSL_LOCKS_EXCLUDED(mu_); - - inline void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { - if (next_ >= kState) { - next_ = kCapacity; - impl_.Generate(state_); - } - } - - private: - // Randen URBG state. - uint32_t state_[kState] ABSL_GUARDED_BY(mu_); // First to satisfy alignment. - SpinLock mu_; - const Randen impl_; - size_t next_ ABSL_GUARDED_BY(mu_); -}; - -template <> -inline uint8_t RandenPoolEntry::Generate<uint8_t>() { - SpinLockHolder l(&mu_); - MaybeRefill(); - return static_cast<uint8_t>(state_[next_++]); -} - -template <> -inline uint16_t RandenPoolEntry::Generate<uint16_t>() { - SpinLockHolder l(&mu_); - MaybeRefill(); - return static_cast<uint16_t>(state_[next_++]); -} - -template <> -inline uint32_t RandenPoolEntry::Generate<uint32_t>() { - SpinLockHolder l(&mu_); - MaybeRefill(); - return state_[next_++]; -} - -template <> -inline uint64_t RandenPoolEntry::Generate<uint64_t>() { - SpinLockHolder l(&mu_); - if (next_ >= kState - 1) { - next_ = kCapacity; - impl_.Generate(state_); - } - auto p = state_ + next_; - next_ += 2; - - uint64_t result; - std::memcpy(&result, p, sizeof(result)); - return result; -} - -void RandenPoolEntry::Fill(uint8_t* out, size_t bytes) { - SpinLockHolder l(&mu_); - while (bytes > 0) { - MaybeRefill(); - size_t remaining = (kState - next_) * sizeof(state_[0]); - size_t to_copy = std::min(bytes, remaining); - std::memcpy(out, &state_[next_], to_copy); - out += to_copy; - bytes -= to_copy; - next_ += (to_copy + sizeof(state_[0]) - 1) / sizeof(state_[0]); - } -} - -// Number of pooled urbg entries. -static constexpr int kPoolSize = 8; - -// Shared pool entries. -static absl::once_flag pool_once; -ABSL_CACHELINE_ALIGNED static RandenPoolEntry* shared_pools[kPoolSize]; - -// Returns an id in the range [0 ... kPoolSize), which indexes into the -// pool of random engines. -// -// Each thread to access the pool is assigned a sequential ID (without reuse) -// from the pool-id space; the id is cached in a thread_local variable. -// This id is assigned based on the arrival-order of the thread to the -// GetPoolID call; this has no binary, CL, or runtime stability because -// on subsequent runs the order within the same program may be significantly -// different. However, as other thread IDs are not assigned sequentially, -// this is not expected to matter. -int GetPoolID() { - static_assert(kPoolSize >= 1, - "At least one urbg instance is required for PoolURBG"); - - ABSL_CONST_INIT static std::atomic<int64_t> sequence{0}; - -#ifdef ABSL_HAVE_THREAD_LOCAL - static thread_local int my_pool_id = -1; - if (ABSL_PREDICT_FALSE(my_pool_id < 0)) { - my_pool_id = (sequence++ % kPoolSize); - } - return my_pool_id; -#else - static pthread_key_t tid_key = [] { - pthread_key_t tmp_key; - int err = pthread_key_create(&tmp_key, nullptr); - if (err) { - ABSL_RAW_LOG(FATAL, "pthread_key_create failed with %d", err); - } - return tmp_key; - }(); - - // Store the value in the pthread_{get/set}specific. However an uninitialized - // value is 0, so add +1 to distinguish from the null value. - intptr_t my_pool_id = - reinterpret_cast<intptr_t>(pthread_getspecific(tid_key)); - if (ABSL_PREDICT_FALSE(my_pool_id == 0)) { - // No allocated ID, allocate the next value, cache it, and return. - my_pool_id = (sequence++ % kPoolSize) + 1; - int err = pthread_setspecific(tid_key, reinterpret_cast<void*>(my_pool_id)); - if (err) { - ABSL_RAW_LOG(FATAL, "pthread_setspecific failed with %d", err); - } - } - return my_pool_id - 1; -#endif -} - -// Allocate a RandenPoolEntry with at least 32-byte alignment, which is required -// by ARM platform code. -RandenPoolEntry* PoolAlignedAlloc() { - constexpr size_t kAlignment = - ABSL_CACHELINE_SIZE > 32 ? ABSL_CACHELINE_SIZE : 32; - - // Not all the platforms that we build for have std::aligned_alloc, however - // since we never free these objects, we can over allocate and munge the - // pointers to the correct alignment. - void* memory = std::malloc(sizeof(RandenPoolEntry) + kAlignment); - auto x = reinterpret_cast<intptr_t>(memory); - auto y = x % kAlignment; - void* aligned = - (y == 0) ? memory : reinterpret_cast<void*>(x + kAlignment - y); - return new (aligned) RandenPoolEntry(); -} - -// Allocate and initialize kPoolSize objects of type RandenPoolEntry. -// -// The initialization strategy is to initialize one object directly from -// OS entropy, then to use that object to seed all of the individual -// pool instances. -void InitPoolURBG() { - static constexpr size_t kSeedSize = - RandenTraits::kStateBytes / sizeof(uint32_t); - // Read the seed data from OS entropy once. - uint32_t seed_material[kPoolSize * kSeedSize]; - if (!random_internal::ReadSeedMaterialFromOSEntropy( - absl::MakeSpan(seed_material))) { - random_internal::ThrowSeedGenException(); - } - for (int i = 0; i < kPoolSize; i++) { - shared_pools[i] = PoolAlignedAlloc(); - shared_pools[i]->Init( - absl::MakeSpan(&seed_material[i * kSeedSize], kSeedSize)); - } -} - -// Returns the pool entry for the current thread. -RandenPoolEntry* GetPoolForCurrentThread() { - absl::call_once(pool_once, InitPoolURBG); - return shared_pools[GetPoolID()]; -} - -} // namespace - -template <typename T> -typename RandenPool<T>::result_type RandenPool<T>::Generate() { - auto* pool = GetPoolForCurrentThread(); - return pool->Generate<T>(); -} - -template <typename T> -void RandenPool<T>::Fill(absl::Span<result_type> data) { - auto* pool = GetPoolForCurrentThread(); - pool->Fill(reinterpret_cast<uint8_t*>(data.data()), - data.size() * sizeof(result_type)); -} - -template class RandenPool<uint8_t>; -template class RandenPool<uint16_t>; -template class RandenPool<uint32_t>; -template class RandenPool<uint64_t>; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/pool_urbg.h b/third_party/abseil_cpp/absl/random/internal/pool_urbg.h deleted file mode 100644 index 05721929f54e..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/pool_urbg.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_POOL_URBG_H_ -#define ABSL_RANDOM_INTERNAL_POOL_URBG_H_ - -#include <cinttypes> -#include <limits> - -#include "absl/random/internal/traits.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// RandenPool is a thread-safe random number generator [random.req.urbg] that -// uses an underlying pool of Randen generators to generate values. Each thread -// has affinity to one instance of the underlying pool generators. Concurrent -// access is guarded by a spin-lock. -template <typename T> -class RandenPool { - public: - using result_type = T; - static_assert(std::is_unsigned<result_type>::value, - "RandenPool template argument must be a built-in unsigned " - "integer type"); - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - RandenPool() {} - - // Returns a single value. - inline result_type operator()() { return Generate(); } - - // Fill data with random values. - static void Fill(absl::Span<result_type> data); - - protected: - // Generate returns a single value. - static result_type Generate(); -}; - -extern template class RandenPool<uint8_t>; -extern template class RandenPool<uint16_t>; -extern template class RandenPool<uint32_t>; -extern template class RandenPool<uint64_t>; - -// PoolURBG uses an underlying pool of random generators to implement a -// thread-compatible [random.req.urbg] interface with an internal cache of -// values. -template <typename T, size_t kBufferSize> -class PoolURBG { - // Inheritance to access the protected static members of RandenPool. - using unsigned_type = typename make_unsigned_bits<T>::type; - using PoolType = RandenPool<unsigned_type>; - using SpanType = absl::Span<unsigned_type>; - - static constexpr size_t kInitialBuffer = kBufferSize + 1; - static constexpr size_t kHalfBuffer = kBufferSize / 2; - - public: - using result_type = T; - - static_assert(std::is_unsigned<result_type>::value, - "PoolURBG must be parameterized by an unsigned integer type"); - - static_assert(kBufferSize > 1, - "PoolURBG must be parameterized by a buffer-size > 1"); - - static_assert(kBufferSize <= 256, - "PoolURBG must be parameterized by a buffer-size <= 256"); - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - PoolURBG() : next_(kInitialBuffer) {} - - // copy-constructor does not copy cache. - PoolURBG(const PoolURBG&) : next_(kInitialBuffer) {} - const PoolURBG& operator=(const PoolURBG&) { - next_ = kInitialBuffer; - return *this; - } - - // move-constructor does move cache. - PoolURBG(PoolURBG&&) = default; - PoolURBG& operator=(PoolURBG&&) = default; - - inline result_type operator()() { - if (next_ >= kBufferSize) { - next_ = (kBufferSize > 2 && next_ > kBufferSize) ? kHalfBuffer : 0; - PoolType::Fill(SpanType(reinterpret_cast<unsigned_type*>(state_ + next_), - kBufferSize - next_)); - } - return state_[next_++]; - } - - private: - // Buffer size. - size_t next_; // index within state_ - result_type state_[kBufferSize]; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_POOL_URBG_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/pool_urbg_test.cc b/third_party/abseil_cpp/absl/random/internal/pool_urbg_test.cc deleted file mode 100644 index 53f4eacf16fe..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/pool_urbg_test.cc +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/pool_urbg.h" - -#include <algorithm> -#include <bitset> -#include <cmath> -#include <cstdint> -#include <iterator> - -#include "gtest/gtest.h" -#include "absl/meta/type_traits.h" -#include "absl/types/span.h" - -using absl::random_internal::PoolURBG; -using absl::random_internal::RandenPool; - -namespace { - -// is_randen_pool trait is true when parameterized by an RandenPool -template <typename T> -using is_randen_pool = typename absl::disjunction< // - std::is_same<T, RandenPool<uint8_t>>, // - std::is_same<T, RandenPool<uint16_t>>, // - std::is_same<T, RandenPool<uint32_t>>, // - std::is_same<T, RandenPool<uint64_t>>>; // - -// MyFill either calls RandenPool::Fill() or std::generate(..., rng) -template <typename T, typename V> -typename absl::enable_if_t<absl::negation<is_randen_pool<T>>::value, void> // -MyFill(T& rng, absl::Span<V> data) { // NOLINT(runtime/references) - std::generate(std::begin(data), std::end(data), rng); -} - -template <typename T, typename V> -typename absl::enable_if_t<is_randen_pool<T>::value, void> // -MyFill(T& rng, absl::Span<V> data) { // NOLINT(runtime/references) - rng.Fill(data); -} - -template <typename EngineType> -class PoolURBGTypedTest : public ::testing::Test {}; - -using EngineTypes = ::testing::Types< // - RandenPool<uint8_t>, // - RandenPool<uint16_t>, // - RandenPool<uint32_t>, // - RandenPool<uint64_t>, // - PoolURBG<uint8_t, 2>, // - PoolURBG<uint16_t, 2>, // - PoolURBG<uint32_t, 2>, // - PoolURBG<uint64_t, 2>, // - PoolURBG<unsigned int, 8>, // NOLINT(runtime/int) - PoolURBG<unsigned long, 8>, // NOLINT(runtime/int) - PoolURBG<unsigned long int, 4>, // NOLINT(runtime/int) - PoolURBG<unsigned long long, 4>>; // NOLINT(runtime/int) - -TYPED_TEST_SUITE(PoolURBGTypedTest, EngineTypes); - -// This test is checks that the engines meet the URBG interface requirements -// defined in [rand.req.urbg]. -TYPED_TEST(PoolURBGTypedTest, URBGInterface) { - using E = TypeParam; - using T = typename E::result_type; - - static_assert(std::is_copy_constructible<E>::value, - "engine must be copy constructible"); - - static_assert(absl::is_copy_assignable<E>::value, - "engine must be copy assignable"); - - E e; - const E x; - - e(); - - static_assert(std::is_same<decltype(e()), T>::value, - "return type of operator() must be result_type"); - - E u0(x); - u0(); - - E u1 = e; - u1(); -} - -// This validates that sequences are independent. -TYPED_TEST(PoolURBGTypedTest, VerifySequences) { - using E = TypeParam; - using result_type = typename E::result_type; - - E rng; - (void)rng(); // Discard one value. - - constexpr int kNumOutputs = 64; - result_type a[kNumOutputs]; - result_type b[kNumOutputs]; - std::fill(std::begin(b), std::end(b), 0); - - // Fill a using Fill or generate, depending on the engine type. - { - E x = rng; - MyFill(x, absl::MakeSpan(a)); - } - - // Fill b using std::generate(). - { - E x = rng; - std::generate(std::begin(b), std::end(b), x); - } - - // Test that generated sequence changed as sequence of bits, i.e. if about - // half of the bites were flipped between two non-correlated values. - size_t changed_bits = 0; - size_t unchanged_bits = 0; - size_t total_set = 0; - size_t total_bits = 0; - size_t equal_count = 0; - for (size_t i = 0; i < kNumOutputs; ++i) { - equal_count += (a[i] == b[i]) ? 1 : 0; - std::bitset<sizeof(result_type) * 8> bitset(a[i] ^ b[i]); - changed_bits += bitset.count(); - unchanged_bits += bitset.size() - bitset.count(); - - std::bitset<sizeof(result_type) * 8> a_set(a[i]); - std::bitset<sizeof(result_type) * 8> b_set(b[i]); - total_set += a_set.count() + b_set.count(); - total_bits += 2 * 8 * sizeof(result_type); - } - // On average, half the bits are changed between two calls. - EXPECT_LE(changed_bits, 0.60 * (changed_bits + unchanged_bits)); - EXPECT_GE(changed_bits, 0.40 * (changed_bits + unchanged_bits)); - - // verify using a quick normal-approximation to the binomial. - EXPECT_NEAR(total_set, total_bits * 0.5, 4 * std::sqrt(total_bits)) - << "@" << total_set / static_cast<double>(total_bits); - - // Also, A[i] == B[i] with probability (1/range) * N. - // Give this a pretty wide latitude, though. - const double kExpected = kNumOutputs / (1.0 * sizeof(result_type) * 8); - EXPECT_LE(equal_count, 1.0 + kExpected); -} - -} // namespace - -/* -$ nanobenchmarks 1 RandenPool construct -$ nanobenchmarks 1 PoolURBG construct - -RandenPool<uint32_t> | 1 | 1000 | 48482.00 ticks | 48.48 ticks | 13.9 ns -RandenPool<uint32_t> | 10 | 2000 | 1028795.00 ticks | 51.44 ticks | 14.7 ns -RandenPool<uint32_t> | 100 | 1000 | 5119968.00 ticks | 51.20 ticks | 14.6 ns -RandenPool<uint32_t> | 1000 | 500 | 25867936.00 ticks | 51.74 ticks | 14.8 ns - -RandenPool<uint64_t> | 1 | 1000 | 49921.00 ticks | 49.92 ticks | 14.3 ns -RandenPool<uint64_t> | 10 | 2000 | 1208269.00 ticks | 60.41 ticks | 17.3 ns -RandenPool<uint64_t> | 100 | 1000 | 5844955.00 ticks | 58.45 ticks | 16.7 ns -RandenPool<uint64_t> | 1000 | 500 | 28767404.00 ticks | 57.53 ticks | 16.4 ns - -PoolURBG<uint32_t,8> | 1 | 1000 | 86431.00 ticks | 86.43 ticks | 24.7 ns -PoolURBG<uint32_t,8> | 10 | 1000 | 206191.00 ticks | 20.62 ticks | 5.9 ns -PoolURBG<uint32_t,8> | 100 | 1000 | 1516049.00 ticks | 15.16 ticks | 4.3 ns -PoolURBG<uint32_t,8> | 1000 | 500 | 7613936.00 ticks | 15.23 ticks | 4.4 ns - -PoolURBG<uint64_t,4> | 1 | 1000 | 96668.00 ticks | 96.67 ticks | 27.6 ns -PoolURBG<uint64_t,4> | 10 | 1000 | 282423.00 ticks | 28.24 ticks | 8.1 ns -PoolURBG<uint64_t,4> | 100 | 1000 | 2609587.00 ticks | 26.10 ticks | 7.5 ns -PoolURBG<uint64_t,4> | 1000 | 500 | 12408757.00 ticks | 24.82 ticks | 7.1 ns - -*/ diff --git a/third_party/abseil_cpp/absl/random/internal/randen.cc b/third_party/abseil_cpp/absl/random/internal/randen.cc deleted file mode 100644 index 78a1e00c0832..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen.h" - -#include "absl/base/internal/raw_logging.h" -#include "absl/random/internal/randen_detect.h" - -// RANDen = RANDom generator or beetroots in Swiss German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -// -// High-level summary: -// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is -// a sponge-like random generator that requires a cryptographic permutation. -// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by -// achieving backtracking resistance with only one Permute() per buffer. -// -// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round -// Function" constructs up to 1024-bit permutations using an improved -// Generalized Feistel network with 2-round AES-128 functions. This Feistel -// block shuffle achieves diffusion faster and is less vulnerable to -// sliced-biclique attacks than the Type-2 cyclic shuffle. -// -// 3) "Improving the Generalized Feistel" and "New criterion for diffusion -// property" extends the same kind of improved Feistel block shuffle to 16 -// branches, which enables a 2048-bit permutation. -// -// We combine these three ideas and also change Simpira's subround keys from -// structured/low-entropy counters to digits of Pi. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -struct RandenState { - const void* keys; - bool has_crypto; -}; - -RandenState GetRandenState() { - static const RandenState state = []() { - RandenState tmp; -#if ABSL_RANDOM_INTERNAL_AES_DISPATCH - // HW AES Dispatch. - if (HasRandenHwAesImplementation() && CPUSupportsRandenHwAes()) { - tmp.has_crypto = true; - tmp.keys = RandenHwAes::GetKeys(); - } else { - tmp.has_crypto = false; - tmp.keys = RandenSlow::GetKeys(); - } -#elif ABSL_HAVE_ACCELERATED_AES - // HW AES is enabled. - tmp.has_crypto = true; - tmp.keys = RandenHwAes::GetKeys(); -#else - // HW AES is disabled. - tmp.has_crypto = false; - tmp.keys = RandenSlow::GetKeys(); -#endif - return tmp; - }(); - return state; -} - -} // namespace - -Randen::Randen() { - auto tmp = GetRandenState(); - keys_ = tmp.keys; -#if ABSL_RANDOM_INTERNAL_AES_DISPATCH - has_crypto_ = tmp.has_crypto; -#endif -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/randen.h b/third_party/abseil_cpp/absl/random/internal/randen.h deleted file mode 100644 index c2834aaf3d2c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_H_ -#define ABSL_RANDOM_INTERNAL_RANDEN_H_ - -#include <cstddef> - -#include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_hwaes.h" -#include "absl/random/internal/randen_slow.h" -#include "absl/random/internal/randen_traits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// RANDen = RANDom generator or beetroots in Swiss German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -// -// Randen implements the basic state manipulation methods. -class Randen { - public: - static constexpr size_t kStateBytes = RandenTraits::kStateBytes; - static constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes; - static constexpr size_t kSeedBytes = RandenTraits::kSeedBytes; - - ~Randen() = default; - - Randen(); - - // Generate updates the randen sponge. The outer portion of the sponge - // (kCapacityBytes .. kStateBytes) may be consumed as PRNG state. - template <typename T, size_t N> - void Generate(T (&state)[N]) const { - static_assert(N * sizeof(T) == kStateBytes, - "Randen::Generate() requires kStateBytes of state"); -#if ABSL_RANDOM_INTERNAL_AES_DISPATCH - // HW AES Dispatch. - if (has_crypto_) { - RandenHwAes::Generate(keys_, state); - } else { - RandenSlow::Generate(keys_, state); - } -#elif ABSL_HAVE_ACCELERATED_AES - // HW AES is enabled. - RandenHwAes::Generate(keys_, state); -#else - // HW AES is disabled. - RandenSlow::Generate(keys_, state); -#endif - } - - // Absorb incorporates additional seed material into the randen sponge. After - // absorb returns, Generate must be called before the state may be consumed. - template <typename S, size_t M, typename T, size_t N> - void Absorb(const S (&seed)[M], T (&state)[N]) const { - static_assert(M * sizeof(S) == RandenTraits::kSeedBytes, - "Randen::Absorb() requires kSeedBytes of seed"); - - static_assert(N * sizeof(T) == RandenTraits::kStateBytes, - "Randen::Absorb() requires kStateBytes of state"); -#if ABSL_RANDOM_INTERNAL_AES_DISPATCH - // HW AES Dispatch. - if (has_crypto_) { - RandenHwAes::Absorb(seed, state); - } else { - RandenSlow::Absorb(seed, state); - } -#elif ABSL_HAVE_ACCELERATED_AES - // HW AES is enabled. - RandenHwAes::Absorb(seed, state); -#else - // HW AES is disabled. - RandenSlow::Absorb(seed, state); -#endif - } - - private: - const void* keys_; -#if ABSL_RANDOM_INTERNAL_AES_DISPATCH - bool has_crypto_; -#endif -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/randen_benchmarks.cc b/third_party/abseil_cpp/absl/random/internal/randen_benchmarks.cc deleted file mode 100644 index f589172c0466..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_benchmarks.cc +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#include "absl/random/internal/randen.h" - -#include <cstdint> -#include <cstdio> -#include <cstring> - -#include "absl/base/internal/raw_logging.h" -#include "absl/random/internal/nanobenchmark.h" -#include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_engine.h" -#include "absl/random/internal/randen_hwaes.h" -#include "absl/random/internal/randen_slow.h" -#include "absl/strings/numbers.h" - -namespace { - -using absl::random_internal::Randen; -using absl::random_internal::RandenHwAes; -using absl::random_internal::RandenSlow; - -using absl::random_internal_nanobenchmark::FuncInput; -using absl::random_internal_nanobenchmark::FuncOutput; -using absl::random_internal_nanobenchmark::InvariantTicksPerSecond; -using absl::random_internal_nanobenchmark::MeasureClosure; -using absl::random_internal_nanobenchmark::Params; -using absl::random_internal_nanobenchmark::PinThreadToCPU; -using absl::random_internal_nanobenchmark::Result; - -// Local state parameters. -static constexpr size_t kStateSizeT = Randen::kStateBytes / sizeof(uint64_t); -static constexpr size_t kSeedSizeT = Randen::kSeedBytes / sizeof(uint32_t); - -// Randen implementation benchmarks. -template <typename T> -struct AbsorbFn : public T { - mutable uint64_t state[kStateSizeT] = {}; - mutable uint32_t seed[kSeedSizeT] = {}; - - static constexpr size_t bytes() { return sizeof(seed); } - - FuncOutput operator()(const FuncInput num_iters) const { - for (size_t i = 0; i < num_iters; ++i) { - this->Absorb(seed, state); - } - return state[0]; - } -}; - -template <typename T> -struct GenerateFn : public T { - mutable uint64_t state[kStateSizeT]; - GenerateFn() { std::memset(state, 0, sizeof(state)); } - - static constexpr size_t bytes() { return sizeof(state); } - - FuncOutput operator()(const FuncInput num_iters) const { - const auto* keys = this->GetKeys(); - for (size_t i = 0; i < num_iters; ++i) { - this->Generate(keys, state); - } - return state[0]; - } -}; - -template <typename UInt> -struct Engine { - mutable absl::random_internal::randen_engine<UInt> rng; - - static constexpr size_t bytes() { return sizeof(UInt); } - - FuncOutput operator()(const FuncInput num_iters) const { - for (size_t i = 0; i < num_iters - 1; ++i) { - rng(); - } - return rng(); - } -}; - -template <size_t N> -void Print(const char* name, const size_t n, const Result (&results)[N], - const size_t bytes) { - if (n == 0) { - ABSL_RAW_LOG( - WARNING, - "WARNING: Measurement failed, should not happen when using " - "PinThreadToCPU unless the region to measure takes > 1 second.\n"); - return; - } - - static const double ns_per_tick = 1e9 / InvariantTicksPerSecond(); - static constexpr const double kNsPerS = 1e9; // ns/s - static constexpr const double kMBPerByte = 1.0 / 1048576.0; // Mb / b - static auto header = [] { - return printf("%20s %8s: %12s ticks; %9s (%9s) %8s\n", "Name", "Count", - "Total", "Variance", "Time", "bytes/s"); - }(); - (void)header; - - for (size_t i = 0; i < n; ++i) { - const double ticks_per_call = results[i].ticks / results[i].input; - const double ns_per_call = ns_per_tick * ticks_per_call; - const double bytes_per_ns = bytes / ns_per_call; - const double mb_per_s = bytes_per_ns * kNsPerS * kMBPerByte; - // Output - printf("%20s %8zu: %12.2f ticks; MAD=%4.2f%% (%6.1f ns) %8.1f Mb/s\n", - name, results[i].input, results[i].ticks, - results[i].variability * 100.0, ns_per_call, mb_per_s); - } -} - -// Fails here -template <typename Op, size_t N> -void Measure(const char* name, const FuncInput (&inputs)[N]) { - Op op; - - Result results[N]; - Params params; - params.verbose = false; - params.max_evals = 6; // avoid test timeout - const size_t num_results = MeasureClosure(op, inputs, N, results, params); - Print(name, num_results, results, op.bytes()); -} - -// unpredictable == 1 but the compiler does not know that. -void RunAll(const int argc, char* argv[]) { - if (argc == 2) { - int cpu = -1; - if (!absl::SimpleAtoi(argv[1], &cpu)) { - ABSL_RAW_LOG(FATAL, "The optional argument must be a CPU number >= 0.\n"); - } - PinThreadToCPU(cpu); - } - - // The compiler cannot reduce this to a constant. - const FuncInput unpredictable = (argc != 999); - static const FuncInput inputs[] = {unpredictable * 100, unpredictable * 1000}; - -#if !defined(ABSL_INTERNAL_DISABLE_AES) && ABSL_HAVE_ACCELERATED_AES - Measure<AbsorbFn<RandenHwAes>>("Absorb (HwAes)", inputs); -#endif - Measure<AbsorbFn<RandenSlow>>("Absorb (Slow)", inputs); - -#if !defined(ABSL_INTERNAL_DISABLE_AES) && ABSL_HAVE_ACCELERATED_AES - Measure<GenerateFn<RandenHwAes>>("Generate (HwAes)", inputs); -#endif - Measure<GenerateFn<RandenSlow>>("Generate (Slow)", inputs); - - // Measure the production engine. - static const FuncInput inputs1[] = {unpredictable * 1000, - unpredictable * 10000}; - Measure<Engine<uint64_t>>("randen_engine<uint64_t>", inputs1); - Measure<Engine<uint32_t>>("randen_engine<uint32_t>", inputs1); -} - -} // namespace - -int main(int argc, char* argv[]) { - RunAll(argc, argv); - return 0; -} diff --git a/third_party/abseil_cpp/absl/random/internal/randen_detect.cc b/third_party/abseil_cpp/absl/random/internal/randen_detect.cc deleted file mode 100644 index bbe7b965329c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_detect.cc +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate -// symbols from arbitrary system and other headers, since it may be built -// with different flags from other targets, using different levels of -// optimization, potentially introducing ODR violations. - -#include "absl/random/internal/randen_detect.h" - -#include <cstdint> -#include <cstring> - -#include "absl/random/internal/platform.h" - -#if defined(ABSL_ARCH_X86_64) -#define ABSL_INTERNAL_USE_X86_CPUID -#elif defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \ - defined(ABSL_ARCH_AARCH64) -#if defined(__ANDROID__) -#define ABSL_INTERNAL_USE_ANDROID_GETAUXVAL -#define ABSL_INTERNAL_USE_GETAUXVAL -#elif defined(__linux__) -#define ABSL_INTERNAL_USE_LINUX_GETAUXVAL -#define ABSL_INTERNAL_USE_GETAUXVAL -#endif -#endif - -#if defined(ABSL_INTERNAL_USE_X86_CPUID) -#if defined(_WIN32) || defined(_WIN64) -#include <intrin.h> // NOLINT(build/include_order) -#pragma intrinsic(__cpuid) -#else -// MSVC-equivalent __cpuid intrinsic function. -static void __cpuid(int cpu_info[4], int info_type) { - __asm__ volatile("cpuid \n\t" - : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), - "=d"(cpu_info[3]) - : "a"(info_type), "c"(0)); -} -#endif -#endif // ABSL_INTERNAL_USE_X86_CPUID - -// On linux, just use the c-library getauxval call. -#if defined(ABSL_INTERNAL_USE_LINUX_GETAUXVAL) - -extern "C" unsigned long getauxval(unsigned long type); // NOLINT(runtime/int) - -static uint32_t GetAuxval(uint32_t hwcap_type) { - return static_cast<uint32_t>(getauxval(hwcap_type)); -} - -#endif - -// On android, probe the system's C library for getauxval(). -// This is the same technique used by the android NDK cpu features library -// as well as the google open-source cpu_features library. -// -// TODO(absl-team): Consider implementing a fallback of directly reading -// /proc/self/auxval. -#if defined(ABSL_INTERNAL_USE_ANDROID_GETAUXVAL) -#include <dlfcn.h> - -static uint32_t GetAuxval(uint32_t hwcap_type) { - // NOLINTNEXTLINE(runtime/int) - typedef unsigned long (*getauxval_func_t)(unsigned long); - - dlerror(); // Cleaning error state before calling dlopen. - void* libc_handle = dlopen("libc.so", RTLD_NOW); - if (!libc_handle) { - return 0; - } - uint32_t result = 0; - void* sym = dlsym(libc_handle, "getauxval"); - if (sym) { - getauxval_func_t func; - memcpy(&func, &sym, sizeof(func)); - result = static_cast<uint32_t>((*func)(hwcap_type)); - } - dlclose(libc_handle); - return result; -} - -#endif - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// The default return at the end of the function might be unreachable depending -// on the configuration. Ignore that warning. -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunreachable-code-return" -#endif - -// CPUSupportsRandenHwAes returns whether the CPU is a microarchitecture -// which supports the crpyto/aes instructions or extensions necessary to use the -// accelerated RandenHwAes implementation. -// -// 1. For x86 it is sufficient to use the CPUID instruction to detect whether -// the cpu supports AES instructions. Done. -// -// Fon non-x86 it is much more complicated. -// -// 2. When ABSL_INTERNAL_USE_GETAUXVAL is defined, use getauxval() (either -// the direct c-library version, or the android probing version which loads -// libc), and read the hardware capability bits. -// This is based on the technique used by boringssl uses to detect -// cpu capabilities, and should allow us to enable crypto in the android -// builds where it is supported. -// -// 3. Use the default for the compiler architecture. -// - -bool CPUSupportsRandenHwAes() { -#if defined(ABSL_INTERNAL_USE_X86_CPUID) - // 1. For x86: Use CPUID to detect the required AES instruction set. - int regs[4]; - __cpuid(reinterpret_cast<int*>(regs), 1); - return regs[2] & (1 << 25); // AES - -#elif defined(ABSL_INTERNAL_USE_GETAUXVAL) - // 2. Use getauxval() to read the hardware bits and determine - // cpu capabilities. - -#define AT_HWCAP 16 -#define AT_HWCAP2 26 -#if defined(ABSL_ARCH_PPC) - // For Power / PPC: Expect that the cpu supports VCRYPTO - // See https://members.openpowerfoundation.org/document/dl/576 - // VCRYPTO should be present in POWER8 >= 2.07. - // Uses Linux kernel constants from arch/powerpc/include/uapi/asm/cputable.h - static const uint32_t kVCRYPTO = 0x02000000; - const uint32_t hwcap = GetAuxval(AT_HWCAP2); - return (hwcap & kVCRYPTO) != 0; - -#elif defined(ABSL_ARCH_ARM) - // For ARM: Require crypto+neon - // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html - // Uses Linux kernel constants from arch/arm64/include/asm/hwcap.h - static const uint32_t kNEON = 1 << 12; - uint32_t hwcap = GetAuxval(AT_HWCAP); - if ((hwcap & kNEON) == 0) { - return false; - } - - // And use it again to detect AES. - static const uint32_t kAES = 1 << 0; - const uint32_t hwcap2 = GetAuxval(AT_HWCAP2); - return (hwcap2 & kAES) != 0; - -#elif defined(ABSL_ARCH_AARCH64) - // For AARCH64: Require crypto+neon - // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html - static const uint32_t kNEON = 1 << 1; - static const uint32_t kAES = 1 << 3; - const uint32_t hwcap = GetAuxval(AT_HWCAP); - return ((hwcap & kNEON) != 0) && ((hwcap & kAES) != 0); -#endif - -#else // ABSL_INTERNAL_USE_GETAUXVAL - // 3. By default, assume that the compiler default. - return ABSL_HAVE_ACCELERATED_AES ? true : false; - -#endif - // NOTE: There are some other techniques that may be worth trying: - // - // * Use an environment variable: ABSL_RANDOM_USE_HWAES - // - // * Rely on compiler-generated target-based dispatch. - // Using x86/gcc it might look something like this: - // - // int __attribute__((target("aes"))) HasAes() { return 1; } - // int __attribute__((target("default"))) HasAes() { return 0; } - // - // This does not work on all architecture/compiler combinations. - // - // * On Linux consider reading /proc/cpuinfo and/or /proc/self/auxv. - // These files have lines which are easy to parse; for ARM/AARCH64 it is quite - // easy to find the Features: line and extract aes / neon. Likewise for - // PPC. - // - // * Fork a process and test for SIGILL: - // - // * Many architectures have instructions to read the ISA. Unfortunately - // most of those require that the code is running in ring 0 / - // protected-mode. - // - // There are several examples. e.g. Valgrind detects PPC ISA 2.07: - // https://github.com/lu-zero/valgrind/blob/master/none/tests/ppc64/test_isa_2_07_part1.c - // - // MRS <Xt>, ID_AA64ISAR0_EL1 ; Read ID_AA64ISAR0_EL1 into Xt - // - // uint64_t val; - // __asm __volatile("mrs %0, id_aa64isar0_el1" :"=&r" (val)); - // - // * Use a CPUID-style heuristic database. - // - // * On Apple (__APPLE__), AES is available on Arm v8. - // https://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios -} - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/randen_detect.h b/third_party/abseil_cpp/absl/random/internal/randen_detect.h deleted file mode 100644 index f283f4322647..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_detect.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ -#define ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Returns whether the current CPU supports RandenHwAes implementation. -// This typically involves supporting cryptographic extensions on whichever -// platform is currently running. -bool CPUSupportsRandenHwAes(); - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/randen_engine.h b/third_party/abseil_cpp/absl/random/internal/randen_engine.h deleted file mode 100644 index 6b33731336e7..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_engine.h +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_ -#define ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_ - -#include <algorithm> -#include <cinttypes> -#include <cstdlib> -#include <iostream> -#include <iterator> -#include <limits> -#include <type_traits> - -#include "absl/meta/type_traits.h" -#include "absl/random/internal/iostream_state_saver.h" -#include "absl/random/internal/randen.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Deterministic pseudorandom byte generator with backtracking resistance -// (leaking the state does not compromise prior outputs). Based on Reverie -// (see "A Robust and Sponge-Like PRNG with Improved Efficiency") instantiated -// with an improved Simpira-like permutation. -// Returns values of type "T" (must be a built-in unsigned integer type). -// -// RANDen = RANDom generator or beetroots in Swiss High German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -template <typename T> -class alignas(16) randen_engine { - public: - // C++11 URBG interface: - using result_type = T; - static_assert(std::is_unsigned<result_type>::value, - "randen_engine template argument must be a built-in unsigned " - "integer type"); - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - explicit randen_engine(result_type seed_value = 0) { seed(seed_value); } - - template <class SeedSequence, - typename = typename absl::enable_if_t< - !std::is_same<SeedSequence, randen_engine>::value>> - explicit randen_engine(SeedSequence&& seq) { - seed(seq); - } - - randen_engine(const randen_engine&) = default; - - // Returns random bits from the buffer in units of result_type. - result_type operator()() { - // Refill the buffer if needed (unlikely). - if (next_ >= kStateSizeT) { - next_ = kCapacityT; - impl_.Generate(state_); - } - - return state_[next_++]; - } - - template <class SeedSequence> - typename absl::enable_if_t< - !std::is_convertible<SeedSequence, result_type>::value> - seed(SeedSequence&& seq) { - // Zeroes the state. - seed(); - reseed(seq); - } - - void seed(result_type seed_value = 0) { - next_ = kStateSizeT; - // Zeroes the inner state and fills the outer state with seed_value to - // mimics behaviour of reseed - std::fill(std::begin(state_), std::begin(state_) + kCapacityT, 0); - std::fill(std::begin(state_) + kCapacityT, std::end(state_), seed_value); - } - - // Inserts entropy into (part of) the state. Calling this periodically with - // sufficient entropy ensures prediction resistance (attackers cannot predict - // future outputs even if state is compromised). - template <class SeedSequence> - void reseed(SeedSequence& seq) { - using sequence_result_type = typename SeedSequence::result_type; - static_assert(sizeof(sequence_result_type) == 4, - "SeedSequence::result_type must be 32-bit"); - - constexpr size_t kBufferSize = - Randen::kSeedBytes / sizeof(sequence_result_type); - alignas(16) sequence_result_type buffer[kBufferSize]; - - // Randen::Absorb XORs the seed into state, which is then mixed by a call - // to Randen::Generate. Seeding with only the provided entropy is preferred - // to using an arbitrary generate() call, so use [rand.req.seed_seq] - // size as a proxy for the number of entropy units that can be generated - // without relying on seed sequence mixing... - const size_t entropy_size = seq.size(); - if (entropy_size < kBufferSize) { - // ... and only request that many values, or 256-bits, when unspecified. - const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size; - std::fill(std::begin(buffer) + requested_entropy, std::end(buffer), 0); - seq.generate(std::begin(buffer), std::begin(buffer) + requested_entropy); - // The Randen paper suggests preferentially initializing even-numbered - // 128-bit vectors of the randen state (there are 16 such vectors). - // The seed data is merged into the state offset by 128-bits, which - // implies prefering seed bytes [16..31, ..., 208..223]. Since the - // buffer is 32-bit values, we swap the corresponding buffer positions in - // 128-bit chunks. - size_t dst = kBufferSize; - while (dst > 7) { - // leave the odd bucket as-is. - dst -= 4; - size_t src = dst >> 1; - // swap 128-bits into the even bucket - std::swap(buffer[--dst], buffer[--src]); - std::swap(buffer[--dst], buffer[--src]); - std::swap(buffer[--dst], buffer[--src]); - std::swap(buffer[--dst], buffer[--src]); - } - } else { - seq.generate(std::begin(buffer), std::end(buffer)); - } - impl_.Absorb(buffer, state_); - - // Generate will be called when operator() is called - next_ = kStateSizeT; - } - - void discard(uint64_t count) { - uint64_t step = std::min<uint64_t>(kStateSizeT - next_, count); - count -= step; - - constexpr uint64_t kRateT = kStateSizeT - kCapacityT; - while (count > 0) { - next_ = kCapacityT; - impl_.Generate(state_); - step = std::min<uint64_t>(kRateT, count); - count -= step; - } - next_ += step; - } - - bool operator==(const randen_engine& other) const { - return next_ == other.next_ && - std::equal(std::begin(state_), std::end(state_), - std::begin(other.state_)); - } - - bool operator!=(const randen_engine& other) const { - return !(*this == other); - } - - template <class CharT, class Traits> - friend std::basic_ostream<CharT, Traits>& operator<<( - std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references) - const randen_engine<T>& engine) { // NOLINT(runtime/references) - using numeric_type = - typename random_internal::stream_format_type<result_type>::type; - auto saver = random_internal::make_ostream_state_saver(os); - for (const auto& elem : engine.state_) { - // In the case that `elem` is `uint8_t`, it must be cast to something - // larger so that it prints as an integer rather than a character. For - // simplicity, apply the cast all circumstances. - os << static_cast<numeric_type>(elem) << os.fill(); - } - os << engine.next_; - return os; - } - - template <class CharT, class Traits> - friend std::basic_istream<CharT, Traits>& operator>>( - std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references) - randen_engine<T>& engine) { // NOLINT(runtime/references) - using numeric_type = - typename random_internal::stream_format_type<result_type>::type; - result_type state[kStateSizeT]; - size_t next; - for (auto& elem : state) { - // It is not possible to read uint8_t from wide streams, so it is - // necessary to read a wider type and then cast it to uint8_t. - numeric_type value; - is >> value; - elem = static_cast<result_type>(value); - } - is >> next; - if (is.fail()) { - return is; - } - std::memcpy(engine.state_, state, sizeof(engine.state_)); - engine.next_ = next; - return is; - } - - private: - static constexpr size_t kStateSizeT = - Randen::kStateBytes / sizeof(result_type); - static constexpr size_t kCapacityT = - Randen::kCapacityBytes / sizeof(result_type); - - // First kCapacityT are `inner', the others are accessible random bits. - alignas(16) result_type state_[kStateSizeT]; - size_t next_; // index within state_ - Randen impl_; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/randen_engine_test.cc b/third_party/abseil_cpp/absl/random/internal/randen_engine_test.cc deleted file mode 100644 index c8e7685bddad..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_engine_test.cc +++ /dev/null @@ -1,656 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen_engine.h" - -#include <algorithm> -#include <bitset> -#include <random> -#include <sstream> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/random/internal/explicit_seed_seq.h" -#include "absl/strings/str_cat.h" -#include "absl/time/clock.h" - -#define UPDATE_GOLDEN 0 - -using randen_u64 = absl::random_internal::randen_engine<uint64_t>; -using randen_u32 = absl::random_internal::randen_engine<uint32_t>; -using absl::random_internal::ExplicitSeedSeq; - -namespace { - -template <typename UIntType> -class RandenEngineTypedTest : public ::testing::Test {}; - -using UIntTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t>; - -TYPED_TEST_SUITE(RandenEngineTypedTest, UIntTypes); - -TYPED_TEST(RandenEngineTypedTest, VerifyReseedChangesAllValues) { - using randen = typename absl::random_internal::randen_engine<TypeParam>; - using result_type = typename randen::result_type; - - const size_t kNumOutputs = (sizeof(randen) * 2 / sizeof(TypeParam)) + 1; - randen engine; - - // MSVC emits error 2719 without the use of std::ref below. - // * formal parameter with __declspec(align('#')) won't be aligned - - { - std::seed_seq seq1{1, 2, 3, 4, 5, 6, 7}; - engine.seed(seq1); - } - result_type a[kNumOutputs]; - std::generate(std::begin(a), std::end(a), std::ref(engine)); - - { - std::random_device rd; - std::seed_seq seq2{rd(), rd(), rd()}; - engine.seed(seq2); - } - result_type b[kNumOutputs]; - std::generate(std::begin(b), std::end(b), std::ref(engine)); - - // Test that generated sequence changed as sequence of bits, i.e. if about - // half of the bites were flipped between two non-correlated values. - size_t changed_bits = 0; - size_t unchanged_bits = 0; - size_t total_set = 0; - size_t total_bits = 0; - size_t equal_count = 0; - for (size_t i = 0; i < kNumOutputs; ++i) { - equal_count += (a[i] == b[i]) ? 1 : 0; - std::bitset<sizeof(result_type) * 8> bitset(a[i] ^ b[i]); - changed_bits += bitset.count(); - unchanged_bits += bitset.size() - bitset.count(); - - std::bitset<sizeof(result_type) * 8> a_set(a[i]); - std::bitset<sizeof(result_type) * 8> b_set(b[i]); - total_set += a_set.count() + b_set.count(); - total_bits += 2 * 8 * sizeof(result_type); - } - // On average, half the bits are changed between two calls. - EXPECT_LE(changed_bits, 0.60 * (changed_bits + unchanged_bits)); - EXPECT_GE(changed_bits, 0.40 * (changed_bits + unchanged_bits)); - - // Verify using a quick normal-approximation to the binomial. - EXPECT_NEAR(total_set, total_bits * 0.5, 4 * std::sqrt(total_bits)) - << "@" << total_set / static_cast<double>(total_bits); - - // Also, A[i] == B[i] with probability (1/range) * N. - // Give this a pretty wide latitude, though. - const double kExpected = kNumOutputs / (1.0 * sizeof(result_type) * 8); - EXPECT_LE(equal_count, 1.0 + kExpected); -} - -// Number of values that needs to be consumed to clean two sizes of buffer -// and trigger third refresh. (slightly overestimates the actual state size). -constexpr size_t kTwoBufferValues = sizeof(randen_u64) / sizeof(uint16_t) + 1; - -TYPED_TEST(RandenEngineTypedTest, VerifyDiscard) { - using randen = typename absl::random_internal::randen_engine<TypeParam>; - - for (size_t num_used = 0; num_used < kTwoBufferValues; ++num_used) { - randen engine_used; - for (size_t i = 0; i < num_used; ++i) { - engine_used(); - } - - for (size_t num_discard = 0; num_discard < kTwoBufferValues; - ++num_discard) { - randen engine1 = engine_used; - randen engine2 = engine_used; - for (size_t i = 0; i < num_discard; ++i) { - engine1(); - } - engine2.discard(num_discard); - for (size_t i = 0; i < kTwoBufferValues; ++i) { - const auto r1 = engine1(); - const auto r2 = engine2(); - ASSERT_EQ(r1, r2) << "used=" << num_used << " discard=" << num_discard; - } - } - } -} - -TYPED_TEST(RandenEngineTypedTest, StreamOperatorsResult) { - using randen = typename absl::random_internal::randen_engine<TypeParam>; - std::wostringstream os; - std::wistringstream is; - randen engine; - - EXPECT_EQ(&(os << engine), &os); - EXPECT_EQ(&(is >> engine), &is); -} - -TYPED_TEST(RandenEngineTypedTest, StreamSerialization) { - using randen = typename absl::random_internal::randen_engine<TypeParam>; - - for (size_t discard = 0; discard < kTwoBufferValues; ++discard) { - ExplicitSeedSeq seed_sequence{12, 34, 56}; - randen engine(seed_sequence); - engine.discard(discard); - - std::stringstream stream; - stream << engine; - - randen new_engine; - stream >> new_engine; - for (size_t i = 0; i < 64; ++i) { - EXPECT_EQ(engine(), new_engine()) << " " << i; - } - } -} - -constexpr size_t kNumGoldenOutputs = 127; - -// This test is checking if randen_engine is meets interface requirements -// defined in [rand.req.urbg]. -TYPED_TEST(RandenEngineTypedTest, RandomNumberEngineInterface) { - using randen = typename absl::random_internal::randen_engine<TypeParam>; - - using E = randen; - using T = typename E::result_type; - - static_assert(std::is_copy_constructible<E>::value, - "randen_engine must be copy constructible"); - - static_assert(absl::is_copy_assignable<E>::value, - "randen_engine must be copy assignable"); - - static_assert(std::is_move_constructible<E>::value, - "randen_engine must be move constructible"); - - static_assert(absl::is_move_assignable<E>::value, - "randen_engine must be move assignable"); - - static_assert(std::is_same<decltype(std::declval<E>()()), T>::value, - "return type of operator() must be result_type"); - - // Names after definition of [rand.req.urbg] in C++ standard. - // e us a value of E - // v is a lvalue of E - // x, y are possibly const values of E - // s is a value of T - // q is a value satisfying requirements of seed_sequence - // z is a value of type unsigned long long - // os is a some specialization of basic_ostream - // is is a some specialization of basic_istream - - E e, v; - const E x, y; - T s = 1; - std::seed_seq q{1, 2, 3}; - unsigned long long z = 1; // NOLINT(runtime/int) - std::wostringstream os; - std::wistringstream is; - - E{}; - E{x}; - E{s}; - E{q}; - - e.seed(); - - // MSVC emits error 2718 when using EXPECT_EQ(e, x) - // * actual parameter with __declspec(align('#')) won't be aligned - EXPECT_TRUE(e == x); - - e.seed(q); - { - E tmp(q); - EXPECT_TRUE(e == tmp); - } - - e(); - { - E tmp(q); - EXPECT_TRUE(e != tmp); - } - - e.discard(z); - - static_assert(std::is_same<decltype(x == y), bool>::value, - "return type of operator== must be bool"); - - static_assert(std::is_same<decltype(x != y), bool>::value, - "return type of operator== must be bool"); -} - -TYPED_TEST(RandenEngineTypedTest, RandenEngineSFINAETest) { - using randen = typename absl::random_internal::randen_engine<TypeParam>; - using result_type = typename randen::result_type; - - { - randen engine(result_type(1)); - engine.seed(result_type(1)); - } - - { - result_type n = 1; - randen engine(n); - engine.seed(n); - } - - { - randen engine(1); - engine.seed(1); - } - - { - int n = 1; - randen engine(n); - engine.seed(n); - } - - { - std::seed_seq seed_seq; - randen engine(seed_seq); - engine.seed(seed_seq); - } - - { - randen engine{std::seed_seq()}; - engine.seed(std::seed_seq()); - } -} - -TEST(RandenTest, VerifyGoldenRanden64Default) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0xc3c14f134e433977, 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, - 0xf0b780f545c72912, 0x15dbb1d37696599f, 0x30ec63baff3c6d59, - 0xb29f73606f7f20a6, 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, - 0x9cbf605e3fd9de8a, 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, - 0xf4b327fe0fc73c37, 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, - 0xd5af05dd3eff9556, 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, - 0x58d3575834956d42, 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, - 0x497cabf3431154fc, 0x4e24370570029a8b, 0xd88b5749f090e5ea, - 0xc651a582a970692f, 0x78fcec2cbb6342f5, 0x463cb745612f55db, - 0x352ee4ad1816afe3, 0x026ff374c101da7e, 0x811ef0821c3de851, - 0x6f7e616704c4fa59, 0xa0660379992d58fc, 0x04b0a374a3b795c7, - 0x915f3445685da798, 0x26802a8ac76571ce, 0x4663352533ce1882, - 0xb9fdefb4a24dc738, 0x5588ba3a4d6e6c51, 0xa2101a42d35f1956, - 0x607195a5e200f5fd, 0x7e100308f3290764, 0xe1e5e03c759c0709, - 0x082572cc5da6606f, 0xcbcf585399e432f1, 0xe8a2be4f8335d8f1, - 0x0904469acbfee8f2, 0xf08bd31b6daecd51, 0x08e8a1f1a69da69a, - 0x6542a20aad57bff5, 0x2e9705bb053d6b46, 0xda2fc9db0713c391, - 0x78e3a810213b6ffb, 0xdc16a59cdd85f8a6, 0xc0932718cd55781f, - 0xb9bfb29c2b20bfe5, 0xb97289c1be0f2f9c, 0xc0a2a0e403a892d4, - 0x5524bb834771435b, 0x8265da3d39d1a750, 0xff4af3ab8d1b78c5, - 0xf0ec5f424bcad77f, 0x66e455f627495189, 0xc82d3120b57e3270, - 0x3424e47dc22596e3, 0xbc0c95129ccedcdd, 0xc191c595afc4dcbf, - 0x120392bd2bb70939, 0x7f90650ea6cd6ab4, 0x7287491832695ad3, - 0xa7c8fac5a7917eb0, 0xd088cb9418be0361, 0x7c1bf9839c7c1ce5, - 0xe2e991fa58e1e79e, 0x78565cdefd28c4ad, 0x7351b9fef98bafad, - 0x2a9eac28b08c96bf, 0x6c4f179696cb2225, 0x13a685861bab87e0, - 0x64c6de5aa0501971, 0x30537425cac70991, 0x01590d9dc6c532b7, - 0x7e05e3aa8ec720dc, 0x74a07d9c54e3e63f, 0x738184388f3bc1d2, - 0x26ffdc5067be3acb, 0x6bcdf185561f255f, 0xa0eaf2e1cf99b1c6, - 0x171df81934f68604, 0x7ea5a21665683e5a, 0x5d1cb02075ba1cea, - 0x957f38cbd2123fdf, 0xba6364eff80de02f, 0x606e0a0e41d452ee, - 0x892d8317de82f7a2, 0xe707b1db50f7b43e, 0x4eb28826766fcf5b, - 0x5a362d56e80a0951, 0x6ee217df16527d78, 0xf6737962ba6b23dd, - 0x443e63857d4076ca, 0x790d9a5f048adfeb, 0xd796b052151ee94d, - 0x033ed95c12b04a03, 0x8b833ff84893da5d, 0x3d6724b1bb15eab9, - 0x9877c4225061ca76, 0xd68d6810adf74fb3, 0x42e5352fe30ce989, - 0x265b565a7431fde7, 0x3cdbf7e358df4b8b, 0x2922a47f6d3e8779, - 0x52d2242f65b37f88, 0x5d836d6e2958d6b5, 0x29d40f00566d5e26, - 0x288db0e1124b14a0, 0x6c056608b7d9c1b6, 0x0b9471bdb8f19d32, - 0x8fb946504faa6c9d, 0x8943a9464540251c, 0xfd1fe27d144a09e0, - 0xea6ac458da141bda, 0x8048f217633fce36, 0xfeda1384ade74d31, - 0x4334b8b02ff7612f, 0xdbc8441f5227e216, 0x096d119a3605c85b, - 0x2b72b31c21b7d7d0}; - - randen_u64 engine; -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%016lx, ", engine()); - if (i % 3 == 2) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(RandenTest, VerifyGoldenRanden64Seeded) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0x83a9e58f94d3dcd5, 0x70bbdff3d97949fb, 0x0438481f7471c1b4, - 0x34fdc58ee5fb5930, 0xceee4f2d2a937d17, 0xb5a26a68e432aea9, - 0x8b64774a3fb51740, 0xd89ac1fc74249c74, 0x03910d1d23fc3fdf, - 0xd38f630878aa897f, 0x0ee8f0f5615f7e44, 0x98f5a53df8279d52, - 0xb403f52c25938d0e, 0x240072996ea6e838, 0xd3a791246190fa61, - 0xaaedd3df7a7b4f80, 0xc6eacabe05deaf6e, 0xb7967dd8790edf4d, - 0x9a0a8e67e049d279, 0x0494f606aebc23e7, 0x598dcd687bc3e0ee, - 0x010ac81802d452a1, 0x6407c87160aa2842, 0x5a56e276486f93a0, - 0xc887a399d46a8f02, 0x9e1e6100fe93b740, 0x12d02e330f8901f6, - 0xc39ca52b47e790b7, 0xb0b0a2fa11e82e61, 0x1542d841a303806a, - 0x1fe659fd7d6e9d86, 0xb8c90d80746541ac, 0x239d56a5669ddc94, - 0xd40db57c8123d13c, 0x3abc2414153a0db0, 0x9bad665630cb8d61, - 0x0bd1fb90ee3f4bbc, 0x8f0b4d7e079b4e42, 0xfa0fb0e0ee59e793, - 0x51080b283e071100, 0x2c4b9e715081cc15, 0xbe10ed49de4941df, - 0xf8eaac9d4b1b0d37, 0x4bcce4b54605e139, 0xa64722b76765dda6, - 0xb9377d738ca28ab5, 0x779fad81a8ccc1af, 0x65cb3ee61ffd3ba7, - 0xd74e79087862836f, 0xd05b9c584c3f25bf, 0x2ba93a4693579827, - 0xd81530aff05420ce, 0xec06cea215478621, 0x4b1798a6796d65ad, - 0xf142f3fb3a6f6fa6, 0x002b7bf7e237b560, 0xf47f2605ef65b4f8, - 0x9804ec5517effc18, 0xaed3d7f8b7d481cd, 0x5651c24c1ce338d1, - 0x3e7a38208bf0a3c6, 0x6796a7b614534aed, 0x0d0f3b848358460f, - 0x0fa5fe7600b19524, 0x2b0cf38253faaedc, 0x10df9188233a9fd6, - 0x3a10033880138b59, 0x5fb0b0d23948e80f, 0x9e76f7b02fbf5350, - 0x0816052304b1a985, 0x30c9880db41fd218, 0x14aa399b65e20f28, - 0xe1454a8cace787b4, 0x325ac971b6c6f0f5, 0x716b1aa2784f3d36, - 0x3d5ce14accfd144f, 0x6c0c97710f651792, 0xbc5b0f59fb333532, - 0x2a90a7d2140470bc, 0x8da269f55c1e1c8d, 0xcfc37143895792ca, - 0xbe21eab1f30b238f, 0x8c47229dee4d65fd, 0x5743614ed1ed7d54, - 0x351372a99e9c476e, 0x2bd5ea15e5db085f, 0x6925fde46e0af4ca, - 0xed3eda2bdc1f45bd, 0xdef68c68d460fa6e, 0xe42a0de76253e2b5, - 0x4e5176dcbc29c305, 0xbfd85fba9f810f6e, 0x76a5a2a9beb815c6, - 0x01edc4ddceaf414c, 0xa4e98904b4bb3b4b, 0x00bd63ac7d2f1ddd, - 0xb8491fe6e998ddbb, 0xb386a3463dda6800, 0x0081887688871619, - 0x33d394b3344e9a38, 0x815dba65a3a8baf9, 0x4232f6ec02c2fd1a, - 0xb5cff603edd20834, 0x580189243f687663, 0xa8d5a2cbdc27fe99, - 0x725d881693fa0131, 0xa2be2c13db2c7ac5, 0x7b6a9614b509fd78, - 0xb6b136d71e717636, 0x660f1a71aff046ea, 0x0ba10ae346c8ec9e, - 0xe66dde53e3145b41, 0x3b18288c88c26be6, 0x4d9d9d2ff02db933, - 0x4167da8c70f46e8a, 0xf183beef8c6318b4, 0x4d889e1e71eeeef1, - 0x7175c71ad6689b6b, 0xfb9e42beacd1b7dd, 0xc33d0e91b29b5e0d, - 0xd39b83291ce47922, 0xc4d570fb8493d12e, 0x23d5a5724f424ae6, - 0x5245f161876b6616, 0x38d77dbd21ab578d, 0x9c3423311f4ecbfe, - 0x76fe31389bacd9d5, - }; - - ExplicitSeedSeq seed_sequence{12, 34, 56}; - randen_u64 engine(seed_sequence); -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%016lx, ", engine()); - if (i % 3 == 2) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(seed_sequence); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(RandenTest, VerifyGoldenRanden32Default) { - constexpr uint64_t kGolden[2 * kNumGoldenOutputs] = { - 0x4e433977, 0xc3c14f13, 0xd90410ee, 0xdda9f47c, 0x7fd8ca10, 0x887bf308, - 0x45c72912, 0xf0b780f5, 0x7696599f, 0x15dbb1d3, 0xff3c6d59, 0x30ec63ba, - 0x6f7f20a6, 0xb29f7360, 0x6f49a54c, 0x02808a31, 0xd5c8e50e, 0x3b8feaf9, - 0x3fd9de8a, 0x9cbf605e, 0x78183bbb, 0xc970ae1a, 0x56301ed5, 0xd8b2ffd3, - 0x0fc73c37, 0xf4b327fe, 0xeb8f9a19, 0xcdfd8d76, 0x91420c9d, 0xc3a506eb, - 0x3eff9556, 0xd5af05dd, 0x8f83c4a1, 0x48db1bb7, 0x0d6bfe8c, 0x7023920e, - 0x34956d42, 0x58d35758, 0x6b87b840, 0xed1ef4c2, 0x3e0b2df3, 0x8eef32a2, - 0x431154fc, 0x497cabf3, 0x70029a8b, 0x4e243705, 0xf090e5ea, 0xd88b5749, - 0xa970692f, 0xc651a582, 0xbb6342f5, 0x78fcec2c, 0x612f55db, 0x463cb745, - 0x1816afe3, 0x352ee4ad, 0xc101da7e, 0x026ff374, 0x1c3de851, 0x811ef082, - 0x04c4fa59, 0x6f7e6167, 0x992d58fc, 0xa0660379, 0xa3b795c7, 0x04b0a374, - 0x685da798, 0x915f3445, 0xc76571ce, 0x26802a8a, 0x33ce1882, 0x46633525, - 0xa24dc738, 0xb9fdefb4, 0x4d6e6c51, 0x5588ba3a, 0xd35f1956, 0xa2101a42, - 0xe200f5fd, 0x607195a5, 0xf3290764, 0x7e100308, 0x759c0709, 0xe1e5e03c, - 0x5da6606f, 0x082572cc, 0x99e432f1, 0xcbcf5853, 0x8335d8f1, 0xe8a2be4f, - 0xcbfee8f2, 0x0904469a, 0x6daecd51, 0xf08bd31b, 0xa69da69a, 0x08e8a1f1, - 0xad57bff5, 0x6542a20a, 0x053d6b46, 0x2e9705bb, 0x0713c391, 0xda2fc9db, - 0x213b6ffb, 0x78e3a810, 0xdd85f8a6, 0xdc16a59c, 0xcd55781f, 0xc0932718, - 0x2b20bfe5, 0xb9bfb29c, 0xbe0f2f9c, 0xb97289c1, 0x03a892d4, 0xc0a2a0e4, - 0x4771435b, 0x5524bb83, 0x39d1a750, 0x8265da3d, 0x8d1b78c5, 0xff4af3ab, - 0x4bcad77f, 0xf0ec5f42, 0x27495189, 0x66e455f6, 0xb57e3270, 0xc82d3120, - 0xc22596e3, 0x3424e47d, 0x9ccedcdd, 0xbc0c9512, 0xafc4dcbf, 0xc191c595, - 0x2bb70939, 0x120392bd, 0xa6cd6ab4, 0x7f90650e, 0x32695ad3, 0x72874918, - 0xa7917eb0, 0xa7c8fac5, 0x18be0361, 0xd088cb94, 0x9c7c1ce5, 0x7c1bf983, - 0x58e1e79e, 0xe2e991fa, 0xfd28c4ad, 0x78565cde, 0xf98bafad, 0x7351b9fe, - 0xb08c96bf, 0x2a9eac28, 0x96cb2225, 0x6c4f1796, 0x1bab87e0, 0x13a68586, - 0xa0501971, 0x64c6de5a, 0xcac70991, 0x30537425, 0xc6c532b7, 0x01590d9d, - 0x8ec720dc, 0x7e05e3aa, 0x54e3e63f, 0x74a07d9c, 0x8f3bc1d2, 0x73818438, - 0x67be3acb, 0x26ffdc50, 0x561f255f, 0x6bcdf185, 0xcf99b1c6, 0xa0eaf2e1, - 0x34f68604, 0x171df819, 0x65683e5a, 0x7ea5a216, 0x75ba1cea, 0x5d1cb020, - 0xd2123fdf, 0x957f38cb, 0xf80de02f, 0xba6364ef, 0x41d452ee, 0x606e0a0e, - 0xde82f7a2, 0x892d8317, 0x50f7b43e, 0xe707b1db, 0x766fcf5b, 0x4eb28826, - 0xe80a0951, 0x5a362d56, 0x16527d78, 0x6ee217df, 0xba6b23dd, 0xf6737962, - 0x7d4076ca, 0x443e6385, 0x048adfeb, 0x790d9a5f, 0x151ee94d, 0xd796b052, - 0x12b04a03, 0x033ed95c, 0x4893da5d, 0x8b833ff8, 0xbb15eab9, 0x3d6724b1, - 0x5061ca76, 0x9877c422, 0xadf74fb3, 0xd68d6810, 0xe30ce989, 0x42e5352f, - 0x7431fde7, 0x265b565a, 0x58df4b8b, 0x3cdbf7e3, 0x6d3e8779, 0x2922a47f, - 0x65b37f88, 0x52d2242f, 0x2958d6b5, 0x5d836d6e, 0x566d5e26, 0x29d40f00, - 0x124b14a0, 0x288db0e1, 0xb7d9c1b6, 0x6c056608, 0xb8f19d32, 0x0b9471bd, - 0x4faa6c9d, 0x8fb94650, 0x4540251c, 0x8943a946, 0x144a09e0, 0xfd1fe27d, - 0xda141bda, 0xea6ac458, 0x633fce36, 0x8048f217, 0xade74d31, 0xfeda1384, - 0x2ff7612f, 0x4334b8b0, 0x5227e216, 0xdbc8441f, 0x3605c85b, 0x096d119a, - 0x21b7d7d0, 0x2b72b31c}; - - randen_u32 engine; -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < 2 * kNumGoldenOutputs; ++i) { - printf("0x%08x, ", engine()); - if (i % 6 == 5) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(RandenTest, VerifyGoldenRanden32Seeded) { - constexpr uint64_t kGolden[2 * kNumGoldenOutputs] = { - 0x94d3dcd5, 0x83a9e58f, 0xd97949fb, 0x70bbdff3, 0x7471c1b4, 0x0438481f, - 0xe5fb5930, 0x34fdc58e, 0x2a937d17, 0xceee4f2d, 0xe432aea9, 0xb5a26a68, - 0x3fb51740, 0x8b64774a, 0x74249c74, 0xd89ac1fc, 0x23fc3fdf, 0x03910d1d, - 0x78aa897f, 0xd38f6308, 0x615f7e44, 0x0ee8f0f5, 0xf8279d52, 0x98f5a53d, - 0x25938d0e, 0xb403f52c, 0x6ea6e838, 0x24007299, 0x6190fa61, 0xd3a79124, - 0x7a7b4f80, 0xaaedd3df, 0x05deaf6e, 0xc6eacabe, 0x790edf4d, 0xb7967dd8, - 0xe049d279, 0x9a0a8e67, 0xaebc23e7, 0x0494f606, 0x7bc3e0ee, 0x598dcd68, - 0x02d452a1, 0x010ac818, 0x60aa2842, 0x6407c871, 0x486f93a0, 0x5a56e276, - 0xd46a8f02, 0xc887a399, 0xfe93b740, 0x9e1e6100, 0x0f8901f6, 0x12d02e33, - 0x47e790b7, 0xc39ca52b, 0x11e82e61, 0xb0b0a2fa, 0xa303806a, 0x1542d841, - 0x7d6e9d86, 0x1fe659fd, 0x746541ac, 0xb8c90d80, 0x669ddc94, 0x239d56a5, - 0x8123d13c, 0xd40db57c, 0x153a0db0, 0x3abc2414, 0x30cb8d61, 0x9bad6656, - 0xee3f4bbc, 0x0bd1fb90, 0x079b4e42, 0x8f0b4d7e, 0xee59e793, 0xfa0fb0e0, - 0x3e071100, 0x51080b28, 0x5081cc15, 0x2c4b9e71, 0xde4941df, 0xbe10ed49, - 0x4b1b0d37, 0xf8eaac9d, 0x4605e139, 0x4bcce4b5, 0x6765dda6, 0xa64722b7, - 0x8ca28ab5, 0xb9377d73, 0xa8ccc1af, 0x779fad81, 0x1ffd3ba7, 0x65cb3ee6, - 0x7862836f, 0xd74e7908, 0x4c3f25bf, 0xd05b9c58, 0x93579827, 0x2ba93a46, - 0xf05420ce, 0xd81530af, 0x15478621, 0xec06cea2, 0x796d65ad, 0x4b1798a6, - 0x3a6f6fa6, 0xf142f3fb, 0xe237b560, 0x002b7bf7, 0xef65b4f8, 0xf47f2605, - 0x17effc18, 0x9804ec55, 0xb7d481cd, 0xaed3d7f8, 0x1ce338d1, 0x5651c24c, - 0x8bf0a3c6, 0x3e7a3820, 0x14534aed, 0x6796a7b6, 0x8358460f, 0x0d0f3b84, - 0x00b19524, 0x0fa5fe76, 0x53faaedc, 0x2b0cf382, 0x233a9fd6, 0x10df9188, - 0x80138b59, 0x3a100338, 0x3948e80f, 0x5fb0b0d2, 0x2fbf5350, 0x9e76f7b0, - 0x04b1a985, 0x08160523, 0xb41fd218, 0x30c9880d, 0x65e20f28, 0x14aa399b, - 0xace787b4, 0xe1454a8c, 0xb6c6f0f5, 0x325ac971, 0x784f3d36, 0x716b1aa2, - 0xccfd144f, 0x3d5ce14a, 0x0f651792, 0x6c0c9771, 0xfb333532, 0xbc5b0f59, - 0x140470bc, 0x2a90a7d2, 0x5c1e1c8d, 0x8da269f5, 0x895792ca, 0xcfc37143, - 0xf30b238f, 0xbe21eab1, 0xee4d65fd, 0x8c47229d, 0xd1ed7d54, 0x5743614e, - 0x9e9c476e, 0x351372a9, 0xe5db085f, 0x2bd5ea15, 0x6e0af4ca, 0x6925fde4, - 0xdc1f45bd, 0xed3eda2b, 0xd460fa6e, 0xdef68c68, 0x6253e2b5, 0xe42a0de7, - 0xbc29c305, 0x4e5176dc, 0x9f810f6e, 0xbfd85fba, 0xbeb815c6, 0x76a5a2a9, - 0xceaf414c, 0x01edc4dd, 0xb4bb3b4b, 0xa4e98904, 0x7d2f1ddd, 0x00bd63ac, - 0xe998ddbb, 0xb8491fe6, 0x3dda6800, 0xb386a346, 0x88871619, 0x00818876, - 0x344e9a38, 0x33d394b3, 0xa3a8baf9, 0x815dba65, 0x02c2fd1a, 0x4232f6ec, - 0xedd20834, 0xb5cff603, 0x3f687663, 0x58018924, 0xdc27fe99, 0xa8d5a2cb, - 0x93fa0131, 0x725d8816, 0xdb2c7ac5, 0xa2be2c13, 0xb509fd78, 0x7b6a9614, - 0x1e717636, 0xb6b136d7, 0xaff046ea, 0x660f1a71, 0x46c8ec9e, 0x0ba10ae3, - 0xe3145b41, 0xe66dde53, 0x88c26be6, 0x3b18288c, 0xf02db933, 0x4d9d9d2f, - 0x70f46e8a, 0x4167da8c, 0x8c6318b4, 0xf183beef, 0x71eeeef1, 0x4d889e1e, - 0xd6689b6b, 0x7175c71a, 0xacd1b7dd, 0xfb9e42be, 0xb29b5e0d, 0xc33d0e91, - 0x1ce47922, 0xd39b8329, 0x8493d12e, 0xc4d570fb, 0x4f424ae6, 0x23d5a572, - 0x876b6616, 0x5245f161, 0x21ab578d, 0x38d77dbd, 0x1f4ecbfe, 0x9c342331, - 0x9bacd9d5, 0x76fe3138, - }; - - ExplicitSeedSeq seed_sequence{12, 34, 56}; - randen_u32 engine(seed_sequence); -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - for (size_t i = 0; i < 2 * kNumGoldenOutputs; ++i) { - printf("0x%08x, ", engine()); - if (i % 6 == 5) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } - engine.seed(seed_sequence); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(RandenTest, VerifyGoldenFromDeserializedEngine) { - constexpr uint64_t kGolden[kNumGoldenOutputs] = { - 0x067f9f9ab919657a, 0x0534605912988583, 0x8a303f72feaa673f, - 0x77b7fd747909185c, 0xd9af90403c56d891, 0xd939c6cb204d14b5, - 0x7fbe6b954a47b483, 0x8b31a47cc34c768d, 0x3a9e546da2701a9c, - 0x5246539046253e71, 0x417191ffb2a848a1, 0x7b1c7bf5a5001d09, - 0x9489b15d194f2361, 0xfcebdeea3bcd2461, 0xd643027c854cec97, - 0x5885397f91e0d21c, 0x53173b0efae30d58, 0x1c9c71168449fac1, - 0xe358202b711ed8aa, 0x94e3918ed1d8227c, 0x5bb4e251450144cf, - 0xb5c7a519b489af3b, 0x6f8b560b1f7b3469, 0xfde11dd4a1c74eef, - 0x33383d2f76457dcf, 0x3060c0ec6db9fce1, 0x18f451fcddeec766, - 0xe73c5d6b9f26da2a, 0x8d4cc566671b32a4, 0xb8189b73776bc9ff, - 0x497a70f9caf0bc23, 0x23afcc509791dcea, 0x18af70dc4b27d306, - 0xd3853f955a0ce5b9, 0x441db6c01a0afb17, 0xd0136c3fb8e1f13f, - 0x5e4fd6fc2f33783c, 0xe0d24548adb5da51, 0x0f4d8362a7d3485a, - 0x9f572d68270fa563, 0x6351fbc823024393, 0xa66dbfc61810e9ab, - 0x0ff17fc14b651af8, 0xd74c55dafb99e623, 0x36303bc1ad85c6c2, - 0x4920cd6a2af7e897, 0x0b8848addc30fecd, 0x9e1562eda6488e93, - 0x197553807d607828, 0xbef5eaeda5e21235, 0x18d91d2616aca527, - 0xb7821937f5c873cd, 0x2cd4ae5650dbeefc, 0xb35a64376f75ffdf, - 0x9226d414d647fe07, 0x663f3db455bbb35e, 0xa829eead6ae93247, - 0x7fd69c204dd0d25f, 0xbe1411f891c9acb1, 0xd476f34a506d5f11, - 0xf423d2831649c5ca, 0x1e503962951abd75, 0xeccc9e8b1e34b537, - 0xb11a147294044854, 0xc4cf27f0abf4929d, 0xe9193abf6fa24c8c, - 0xa94a259e3aba8808, 0x21dc414197deffa3, 0xa2ae211d1ff622ae, - 0xfe3995c46be5a4f4, 0xe9984c284bf11128, 0xcb1ce9d2f0851a80, - 0x42fee17971d87cd8, 0xac76a98d177adc88, 0xa0973b3dedc4af6f, - 0xdf56d6bbcb1b8e86, 0xf1e6485f407b11c9, 0x2c63de4deccb15c0, - 0x6fe69db32ed4fad7, 0xaa51a65f84bca1f1, 0x242f2ee81d608afc, - 0x8eb88b2b69fc153b, 0x22c20098baf73fd1, 0x57759466f576488c, - 0x075ca562cea1be9d, 0x9a74814d73d28891, 0x73d1555fc02f4d3d, - 0xc17f8f210ee89337, 0x46cca7999eaeafd4, 0x5db8d6a327a0d8ac, - 0xb79b4f93c738d7a1, 0x9994512f0036ded1, 0xd3883026f38747f4, - 0xf31f7458078d097c, 0x736ce4d480680669, 0x7a496f4c7e1033e3, - 0xecf85bf297fbc68c, 0x9e37e1d0f24f3c4e, 0x15b6e067ca0746fc, - 0xdd4a39905c5db81c, 0xb5dfafa7bcfdf7da, 0xca6646fb6f92a276, - 0x1c6b35f363ef0efd, 0x6a33d06037ad9f76, 0x45544241afd8f80f, - 0x83f8d83f859c90c5, 0x22aea9c5365e8c19, 0xfac35b11f20b6a6a, - 0xd1acf49d1a27dd2f, 0xf281cd09c4fed405, 0x076000a42cd38e4f, - 0x6ace300565070445, 0x463a62781bddc4db, 0x1477126b46b569ac, - 0x127f2bb15035fbb8, 0xdfa30946049c04a8, 0x89072a586ba8dd3e, - 0x62c809582bb7e74d, 0x22c0c3641406c28b, 0x9b66e36c47ff004d, - 0xb9cd2c7519653330, 0x18608d79cd7a598d, 0x92c0bd1323e53e32, - 0x887ff00de8524aa5, 0xa074410b787abd10, 0x18ab41b8057a2063, - 0x1560abf26bc5f987}; - -#if UPDATE_GOLDEN - (void)kGolden; // Silence warning. - std::seed_seq seed_sequence{1, 2, 3, 4, 5}; - randen_u64 engine(seed_sequence); - std::ostringstream stream; - stream << engine; - auto str = stream.str(); - printf("%s\n\n", str.c_str()); - for (size_t i = 0; i < kNumGoldenOutputs; ++i) { - printf("0x%016lx, ", engine()); - if (i % 3 == 2) { - printf("\n"); - } - } - printf("\n\n\n"); -#else - randen_u64 engine; - std::istringstream stream( - "0 0 9824501439887287479 3242284395352394785 243836530774933777 " - "4047941804708365596 17165468127298385802 949276103645889255 " - "10659970394998657921 1657570836810929787 11697746266668051452 " - "9967209969299905230 14140390331161524430 7383014124183271684 " - "13146719127702337852 13983155220295807171 11121125587542359264 " - "195757810993252695 17138580243103178492 11326030747260920501 " - "8585097322474965590 18342582839328350995 15052982824209724634 " - "7321861343874683609 1806786911778767826 10100850842665572955 " - "9249328950653985078 13600624835326909759 11137960060943860251 " - "10208781341792329629 9282723971471525577 16373271619486811032 32"); - stream >> engine; - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, engine()); - } -#endif -} - -TEST(RandenTest, IsFastOrSlow) { - // randen_engine typically costs ~5ns per value for the optimized code paths, - // and the ~1000ns per value for slow code paths. However when running under - // msan, asan, etc. it can take much longer. - // - // The estimated operation time is something like: - // - // linux, optimized ~5ns - // ppc, optimized ~7ns - // nacl (slow), ~1100ns - // - // `kCount` is chosen below so that, in debug builds and without hardware - // acceleration, the test (assuming ~1us per call) should finish in ~0.1s - static constexpr size_t kCount = 100000; - randen_u64 engine; - randen_u64::result_type sum = 0; - auto start = absl::GetCurrentTimeNanos(); - for (int i = 0; i < kCount; i++) { - sum += engine(); - } - auto duration = absl::GetCurrentTimeNanos() - start; - - ABSL_INTERNAL_LOG(INFO, absl::StrCat(static_cast<double>(duration) / - static_cast<double>(kCount), - "ns")); - - EXPECT_GT(sum, 0); - EXPECT_GE(duration, kCount); // Should be slower than 1ns per call. -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/randen_hwaes.cc b/third_party/abseil_cpp/absl/random/internal/randen_hwaes.cc deleted file mode 100644 index b5a3f90aee63..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_hwaes.cc +++ /dev/null @@ -1,573 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate -// symbols from arbitrary system and other headers, since it may be built -// with different flags from other targets, using different levels of -// optimization, potentially introducing ODR violations. - -#include "absl/random/internal/randen_hwaes.h" - -#include <cstdint> -#include <cstring> - -#include "absl/base/attributes.h" -#include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_traits.h" - -// ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain -// a hardware accelerated implementation of randen, or whether it -// will contain stubs that exit the process. -#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) -// The platform.h directives are sufficient to indicate whether -// we should build accelerated implementations for x86. -#if (ABSL_HAVE_ACCELERATED_AES || ABSL_RANDOM_INTERNAL_AES_DISPATCH) -#define ABSL_RANDEN_HWAES_IMPL 1 -#endif -#elif defined(ABSL_ARCH_PPC) -// The platform.h directives are sufficient to indicate whether -// we should build accelerated implementations for PPC. -// -// NOTE: This has mostly been tested on 64-bit Power variants, -// and not embedded cpus such as powerpc32-8540 -#if ABSL_HAVE_ACCELERATED_AES -#define ABSL_RANDEN_HWAES_IMPL 1 -#endif -#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64) -// ARM is somewhat more complicated. We might support crypto natively... -#if ABSL_HAVE_ACCELERATED_AES || \ - (defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO)) -#define ABSL_RANDEN_HWAES_IMPL 1 - -#elif ABSL_RANDOM_INTERNAL_AES_DISPATCH && !defined(__APPLE__) && \ - (defined(__GNUC__) && __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 9) -// ...or, on GCC, we can use an ASM directive to -// instruct the assember to allow crypto instructions. -#define ABSL_RANDEN_HWAES_IMPL 1 -#define ABSL_RANDEN_HWAES_IMPL_CRYPTO_DIRECTIVE 1 -#endif -#else -// HWAES is unsupported by these architectures / platforms: -// __myriad2__ -// __mips__ -// -// Other architectures / platforms are unknown. -// -// See the Abseil documentation on supported macros at: -// https://abseil.io/docs/cpp/platforms/macros -#endif - -#if !defined(ABSL_RANDEN_HWAES_IMPL) -// No accelerated implementation is supported. -// The RandenHwAes functions are stubs that print an error and exit. - -#include <cstdio> -#include <cstdlib> - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// No accelerated implementation. -bool HasRandenHwAesImplementation() { return false; } - -// NOLINTNEXTLINE -const void* RandenHwAes::GetKeys() { - // Attempted to dispatch to an unsupported dispatch target. - const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH; - fprintf(stderr, "AES Hardware detection failed (%d).\n", d); - exit(1); - return nullptr; -} - -// NOLINTNEXTLINE -void RandenHwAes::Absorb(const void*, void*) { - // Attempted to dispatch to an unsupported dispatch target. - const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH; - fprintf(stderr, "AES Hardware detection failed (%d).\n", d); - exit(1); -} - -// NOLINTNEXTLINE -void RandenHwAes::Generate(const void*, void*) { - // Attempted to dispatch to an unsupported dispatch target. - const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH; - fprintf(stderr, "AES Hardware detection failed (%d).\n", d); - exit(1); -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#else // defined(ABSL_RANDEN_HWAES_IMPL) -// -// Accelerated implementations are supported. -// We need the per-architecture includes and defines. -// -namespace { - -using absl::random_internal::RandenTraits; - -// Randen operates on 128-bit vectors. -struct alignas(16) u64x2 { - uint64_t data[2]; -}; - -} // namespace - -// TARGET_CRYPTO defines a crypto attribute for each architecture. -// -// NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO. -#if (defined(__clang__) || defined(__GNUC__)) -#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) -#define ABSL_TARGET_CRYPTO __attribute__((target("aes"))) -#elif defined(ABSL_ARCH_PPC) -#define ABSL_TARGET_CRYPTO __attribute__((target("crypto"))) -#else -#define ABSL_TARGET_CRYPTO -#endif -#else -#define ABSL_TARGET_CRYPTO -#endif - -#if defined(ABSL_ARCH_PPC) -// NOTE: Keep in mind that PPC can operate in little-endian or big-endian mode, -// however the PPC altivec vector registers (and thus the AES instructions) -// always operate in big-endian mode. - -#include <altivec.h> -// <altivec.h> #defines vector __vector; in C++, this is bad form. -#undef vector -#undef bool - -// Rely on the PowerPC AltiVec vector operations for accelerated AES -// instructions. GCC support of the PPC vector types is described in: -// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/PowerPC-AltiVec_002fVSX-Built-in-Functions.html -// -// Already provides operator^=. -using Vector128 = __vector unsigned long long; // NOLINT(runtime/int) - -namespace { -inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) { - // Reverses the bytes of the vector. - const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8, - 7, 6, 5, 4, 3, 2, 1, 0}; - return vec_perm(v, v, perm); -} - -// WARNING: these load/store in native byte order. It is OK to load and then -// store an unchanged vector, but interpreting the bits as a number or input -// to AES will have undefined results. -inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) { - return vec_vsx_ld(0, reinterpret_cast<const Vector128*>(from)); -} - -inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) { - vec_vsx_st(v, 0, reinterpret_cast<Vector128*>(to)); -} - -// One round of AES. "round_key" is a public constant for breaking the -// symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, - const Vector128& round_key) { - return Vector128(__builtin_crypto_vcipher(state, round_key)); -} - -// Enables native loads in the round loop by pre-swapping. -inline ABSL_TARGET_CRYPTO void SwapEndian(u64x2* state) { - for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { - Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block); - } -} - -} // namespace - -#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64) - -// This asm directive will cause the file to be compiled with crypto extensions -// whether or not the cpu-architecture supports it. -#if ABSL_RANDEN_HWAES_IMPL_CRYPTO_DIRECTIVE -asm(".arch_extension crypto\n"); - -// Override missing defines. -#if !defined(__ARM_NEON) -#define __ARM_NEON 1 -#endif - -#if !defined(__ARM_FEATURE_CRYPTO) -#define __ARM_FEATURE_CRYPTO 1 -#endif - -#endif - -// Rely on the ARM NEON+Crypto advanced simd types, defined in <arm_neon.h>. -// uint8x16_t is the user alias for underlying __simd128_uint8_t type. -// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf -// -// <arm_neon> defines the following -// -// typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t; -// typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t; -// typedef __attribute__((neon_polyvector_type(16))) int8_t poly8x16_t; -// -// vld1q_v -// vst1q_v -// vaeseq_v -// vaesmcq_v -#include <arm_neon.h> - -// Already provides operator^=. -using Vector128 = uint8x16_t; - -namespace { - -inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) { - return vld1q_u8(reinterpret_cast<const uint8_t*>(from)); -} - -inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) { - vst1q_u8(reinterpret_cast<uint8_t*>(to), v); -} - -// One round of AES. "round_key" is a public constant for breaking the -// symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, - const Vector128& round_key) { - // It is important to always use the full round function - omitting the - // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf] - // and does not help because we never decrypt. - // - // Note that ARM divides AES instructions differently than x86 / PPC, - // And we need to skip the first AddRoundKey step and add an extra - // AddRoundKey step to the end. Lucky for us this is just XOR. - return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key; -} - -inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} - -} // namespace - -#elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) -// On x86 we rely on the aesni instructions -#include <wmmintrin.h> - -namespace { - -// Vector128 class is only wrapper for __m128i, benchmark indicates that it's -// faster than using __m128i directly. -class Vector128 { - public: - // Convert from/to intrinsics. - inline explicit Vector128(const __m128i& Vector128) : data_(Vector128) {} - - inline __m128i data() const { return data_; } - - inline Vector128& operator^=(const Vector128& other) { - data_ = _mm_xor_si128(data_, other.data()); - return *this; - } - - private: - __m128i data_; -}; - -inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) { - return Vector128(_mm_load_si128(reinterpret_cast<const __m128i*>(from))); -} - -inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) { - _mm_store_si128(reinterpret_cast<__m128i*>(to), v.data()); -} - -// One round of AES. "round_key" is a public constant for breaking the -// symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, - const Vector128& round_key) { - // It is important to always use the full round function - omitting the - // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf] - // and does not help because we never decrypt. - return Vector128(_mm_aesenc_si128(state.data(), round_key.data())); -} - -inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} - -} // namespace - -#endif - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunknown-pragmas" -#endif - -// At this point, all of the platform-specific features have been defined / -// implemented. -// -// REQUIRES: using Vector128 = ... -// REQUIRES: Vector128 Vector128Load(void*) {...} -// REQUIRES: void Vector128Store(Vector128, void*) {...} -// REQUIRES: Vector128 AesRound(Vector128, Vector128) {...} -// REQUIRES: void SwapEndian(uint64_t*) {...} -// -// PROVIDES: absl::random_internal::RandenHwAes::Absorb -// PROVIDES: absl::random_internal::RandenHwAes::Generate -namespace { - -// Block shuffles applies a shuffle to the entire state between AES rounds. -// Improved odd-even shuffle from "New criterion for diffusion property". -inline ABSL_TARGET_CRYPTO void BlockShuffle(u64x2* state) { - static_assert(RandenTraits::kFeistelBlocks == 16, - "Expecting 16 FeistelBlocks."); - - constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { - 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; - - const Vector128 v0 = Vector128Load(state + shuffle[0]); - const Vector128 v1 = Vector128Load(state + shuffle[1]); - const Vector128 v2 = Vector128Load(state + shuffle[2]); - const Vector128 v3 = Vector128Load(state + shuffle[3]); - const Vector128 v4 = Vector128Load(state + shuffle[4]); - const Vector128 v5 = Vector128Load(state + shuffle[5]); - const Vector128 v6 = Vector128Load(state + shuffle[6]); - const Vector128 v7 = Vector128Load(state + shuffle[7]); - const Vector128 w0 = Vector128Load(state + shuffle[8]); - const Vector128 w1 = Vector128Load(state + shuffle[9]); - const Vector128 w2 = Vector128Load(state + shuffle[10]); - const Vector128 w3 = Vector128Load(state + shuffle[11]); - const Vector128 w4 = Vector128Load(state + shuffle[12]); - const Vector128 w5 = Vector128Load(state + shuffle[13]); - const Vector128 w6 = Vector128Load(state + shuffle[14]); - const Vector128 w7 = Vector128Load(state + shuffle[15]); - - Vector128Store(v0, state + 0); - Vector128Store(v1, state + 1); - Vector128Store(v2, state + 2); - Vector128Store(v3, state + 3); - Vector128Store(v4, state + 4); - Vector128Store(v5, state + 5); - Vector128Store(v6, state + 6); - Vector128Store(v7, state + 7); - Vector128Store(w0, state + 8); - Vector128Store(w1, state + 9); - Vector128Store(w2, state + 10); - Vector128Store(w3, state + 11); - Vector128Store(w4, state + 12); - Vector128Store(w5, state + 13); - Vector128Store(w6, state + 14); - Vector128Store(w7, state + 15); -} - -// Feistel round function using two AES subrounds. Very similar to F() -// from Simpira v2, but with independent subround keys. Uses 17 AES rounds -// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in -// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel -// XORs are 'free' (included in the second AES instruction). -inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( - u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - static_assert(RandenTraits::kFeistelBlocks == 16, - "Expecting 16 FeistelBlocks."); - - // MSVC does a horrible job at unrolling loops. - // So we unroll the loop by hand to improve the performance. - const Vector128 s0 = Vector128Load(state + 0); - const Vector128 s1 = Vector128Load(state + 1); - const Vector128 s2 = Vector128Load(state + 2); - const Vector128 s3 = Vector128Load(state + 3); - const Vector128 s4 = Vector128Load(state + 4); - const Vector128 s5 = Vector128Load(state + 5); - const Vector128 s6 = Vector128Load(state + 6); - const Vector128 s7 = Vector128Load(state + 7); - const Vector128 s8 = Vector128Load(state + 8); - const Vector128 s9 = Vector128Load(state + 9); - const Vector128 s10 = Vector128Load(state + 10); - const Vector128 s11 = Vector128Load(state + 11); - const Vector128 s12 = Vector128Load(state + 12); - const Vector128 s13 = Vector128Load(state + 13); - const Vector128 s14 = Vector128Load(state + 14); - const Vector128 s15 = Vector128Load(state + 15); - - // Encode even blocks with keys. - const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0)); - const Vector128 e2 = AesRound(s2, Vector128Load(keys + 1)); - const Vector128 e4 = AesRound(s4, Vector128Load(keys + 2)); - const Vector128 e6 = AesRound(s6, Vector128Load(keys + 3)); - const Vector128 e8 = AesRound(s8, Vector128Load(keys + 4)); - const Vector128 e10 = AesRound(s10, Vector128Load(keys + 5)); - const Vector128 e12 = AesRound(s12, Vector128Load(keys + 6)); - const Vector128 e14 = AesRound(s14, Vector128Load(keys + 7)); - - // Encode odd blocks with even output from above. - const Vector128 o1 = AesRound(e0, s1); - const Vector128 o3 = AesRound(e2, s3); - const Vector128 o5 = AesRound(e4, s5); - const Vector128 o7 = AesRound(e6, s7); - const Vector128 o9 = AesRound(e8, s9); - const Vector128 o11 = AesRound(e10, s11); - const Vector128 o13 = AesRound(e12, s13); - const Vector128 o15 = AesRound(e14, s15); - - // Store odd blocks. (These will be shuffled later). - Vector128Store(o1, state + 1); - Vector128Store(o3, state + 3); - Vector128Store(o5, state + 5); - Vector128Store(o7, state + 7); - Vector128Store(o9, state + 9); - Vector128Store(o11, state + 11); - Vector128Store(o13, state + 13); - Vector128Store(o15, state + 15); - - return keys + 8; -} - -// Cryptographic permutation based via type-2 Generalized Feistel Network. -// Indistinguishable from ideal by chosen-ciphertext adversaries using less than -// 2^64 queries if the round function is a PRF. This is similar to the b=8 case -// of Simpira v2, but more efficient than its generic construction for b=16. -inline ABSL_TARGET_CRYPTO void Permute( - u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - // (Successfully unrolled; the first iteration jumps into the second half) -#ifdef __clang__ -#pragma clang loop unroll_count(2) -#endif - for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { - keys = FeistelRound(state, keys); - BlockShuffle(state); - } -} - -} // namespace - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -bool HasRandenHwAesImplementation() { return true; } - -const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() { - // Round keys for one AES per Feistel round and branch. - // The canonical implementation uses first digits of Pi. -#if defined(ABSL_ARCH_PPC) - return kRandenRoundKeysBE; -#else - return kRandenRoundKeys; -#endif -} - -// NOLINTNEXTLINE -void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void, - void* state_void) { - static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1, - "Unexpected Randen kCapacityBlocks"); - static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16, - "Unexpected Randen kStateBlocks"); - - auto* state = - reinterpret_cast<u64x2 * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void); - const auto* seed = - reinterpret_cast<const u64x2 * ABSL_RANDOM_INTERNAL_RESTRICT>(seed_void); - - Vector128 b1 = Vector128Load(state + 1); - b1 ^= Vector128Load(seed + 0); - Vector128Store(b1, state + 1); - - Vector128 b2 = Vector128Load(state + 2); - b2 ^= Vector128Load(seed + 1); - Vector128Store(b2, state + 2); - - Vector128 b3 = Vector128Load(state + 3); - b3 ^= Vector128Load(seed + 2); - Vector128Store(b3, state + 3); - - Vector128 b4 = Vector128Load(state + 4); - b4 ^= Vector128Load(seed + 3); - Vector128Store(b4, state + 4); - - Vector128 b5 = Vector128Load(state + 5); - b5 ^= Vector128Load(seed + 4); - Vector128Store(b5, state + 5); - - Vector128 b6 = Vector128Load(state + 6); - b6 ^= Vector128Load(seed + 5); - Vector128Store(b6, state + 6); - - Vector128 b7 = Vector128Load(state + 7); - b7 ^= Vector128Load(seed + 6); - Vector128Store(b7, state + 7); - - Vector128 b8 = Vector128Load(state + 8); - b8 ^= Vector128Load(seed + 7); - Vector128Store(b8, state + 8); - - Vector128 b9 = Vector128Load(state + 9); - b9 ^= Vector128Load(seed + 8); - Vector128Store(b9, state + 9); - - Vector128 b10 = Vector128Load(state + 10); - b10 ^= Vector128Load(seed + 9); - Vector128Store(b10, state + 10); - - Vector128 b11 = Vector128Load(state + 11); - b11 ^= Vector128Load(seed + 10); - Vector128Store(b11, state + 11); - - Vector128 b12 = Vector128Load(state + 12); - b12 ^= Vector128Load(seed + 11); - Vector128Store(b12, state + 12); - - Vector128 b13 = Vector128Load(state + 13); - b13 ^= Vector128Load(seed + 12); - Vector128Store(b13, state + 13); - - Vector128 b14 = Vector128Load(state + 14); - b14 ^= Vector128Load(seed + 13); - Vector128Store(b14, state + 14); - - Vector128 b15 = Vector128Load(state + 15); - b15 ^= Vector128Load(seed + 14); - Vector128Store(b15, state + 15); -} - -// NOLINTNEXTLINE -void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, - void* state_void) { - static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128), - "Capacity mismatch"); - - auto* state = reinterpret_cast<u64x2*>(state_void); - const auto* keys = reinterpret_cast<const u64x2*>(keys_void); - - const Vector128 prev_inner = Vector128Load(state); - - SwapEndian(state); - - Permute(state, keys); - - SwapEndian(state); - - // Ensure backtracking resistance. - Vector128 inner = Vector128Load(state); - inner ^= prev_inner; - Vector128Store(inner, state); -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // (ABSL_RANDEN_HWAES_IMPL) diff --git a/third_party/abseil_cpp/absl/random/internal/randen_hwaes.h b/third_party/abseil_cpp/absl/random/internal/randen_hwaes.h deleted file mode 100644 index bce36b522609..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_hwaes.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ -#define ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ - -#include "absl/base/config.h" - -// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate -// symbols from arbitrary system and other headers, since it may be built -// with different flags from other targets, using different levels of -// optimization, potentially introducing ODR violations. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// RANDen = RANDom generator or beetroots in Swiss German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -// -// RandenHwAes implements the basic state manipulation methods. -class RandenHwAes { - public: - static void Generate(const void* keys, void* state_void); - static void Absorb(const void* seed_void, void* state_void); - static const void* GetKeys(); -}; - -// HasRandenHwAesImplementation returns true when there is an accelerated -// implementation, and false otherwise. If there is no implementation, -// then attempting to use it will abort the program. -bool HasRandenHwAesImplementation(); - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/randen_hwaes_test.cc b/third_party/abseil_cpp/absl/random/internal/randen_hwaes_test.cc deleted file mode 100644 index 66ddb43fd6a7..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_hwaes_test.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen_hwaes.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_detect.h" -#include "absl/random/internal/randen_traits.h" -#include "absl/strings/str_format.h" - -namespace { - -using absl::random_internal::RandenHwAes; -using absl::random_internal::RandenTraits; - -// Local state parameters. -constexpr size_t kSeedBytes = - RandenTraits::kStateBytes - RandenTraits::kCapacityBytes; -constexpr size_t kStateSizeT = RandenTraits::kStateBytes / sizeof(uint64_t); -constexpr size_t kSeedSizeT = kSeedBytes / sizeof(uint32_t); - -struct alignas(16) randen { - uint64_t state[kStateSizeT]; - uint32_t seed[kSeedSizeT]; -}; - -TEST(RandenHwAesTest, Default) { - EXPECT_TRUE(absl::random_internal::CPUSupportsRandenHwAes()); - - constexpr uint64_t kGolden[] = { - 0x6c6534090ee6d3ee, 0x044e2b9b9d5333c6, 0xc3c14f134e433977, - 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, 0xf0b780f545c72912, - 0x15dbb1d37696599f, 0x30ec63baff3c6d59, 0xb29f73606f7f20a6, - 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, 0x9cbf605e3fd9de8a, - 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, 0xf4b327fe0fc73c37, - 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, 0xd5af05dd3eff9556, - 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, 0x58d3575834956d42, - 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, 0x497cabf3431154fc, - 0x4e24370570029a8b, 0xd88b5749f090e5ea, 0xc651a582a970692f, - 0x78fcec2cbb6342f5, 0x463cb745612f55db, 0x352ee4ad1816afe3, - 0x026ff374c101da7e, 0x811ef0821c3de851, - }; - - alignas(16) randen d; - memset(d.state, 0, sizeof(d.state)); - RandenHwAes::Generate(RandenHwAes::GetKeys(), d.state); - - uint64_t* id = d.state; - for (const auto& elem : kGolden) { - auto a = absl::StrFormat("%#x", elem); - auto b = absl::StrFormat("%#x", *id++); - EXPECT_EQ(a, b); - } -} - -} // namespace - -int main(int argc, char* argv[]) { - testing::InitGoogleTest(&argc, argv); - - ABSL_RAW_LOG(INFO, "ABSL_HAVE_ACCELERATED_AES=%d", ABSL_HAVE_ACCELERATED_AES); - ABSL_RAW_LOG(INFO, "ABSL_RANDOM_INTERNAL_AES_DISPATCH=%d", - ABSL_RANDOM_INTERNAL_AES_DISPATCH); - -#if defined(ABSL_ARCH_X86_64) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_X86_64"); -#elif defined(ABSL_ARCH_X86_32) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_X86_32"); -#elif defined(ABSL_ARCH_AARCH64) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_AARCH64"); -#elif defined(ABSL_ARCH_ARM) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_ARM"); -#elif defined(ABSL_ARCH_PPC) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_PPC"); -#else - ABSL_RAW_LOG(INFO, "ARCH Unknown"); -#endif - - int x = absl::random_internal::HasRandenHwAesImplementation(); - ABSL_RAW_LOG(INFO, "HasRandenHwAesImplementation = %d", x); - - int y = absl::random_internal::CPUSupportsRandenHwAes(); - ABSL_RAW_LOG(INFO, "CPUSupportsRandenHwAes = %d", x); - - if (!x || !y) { - ABSL_RAW_LOG(INFO, "Skipping Randen HWAES tests."); - return 0; - } - return RUN_ALL_TESTS(); -} diff --git a/third_party/abseil_cpp/absl/random/internal/randen_round_keys.cc b/third_party/abseil_cpp/absl/random/internal/randen_round_keys.cc deleted file mode 100644 index 5fb3ca556db6..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_round_keys.cc +++ /dev/null @@ -1,462 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen_traits.h" - -// This file contains only the round keys for randen. -// -// "Nothing up my sleeve" numbers from the first hex digits of Pi, obtained -// from http://hexpi.sourceforge.net/. The array was generated by following -// Python script: - -/* -python >tmp.cc << EOF -"""Generates Randen round keys array from pi-hex.62500.txt file.""" -import binascii - -KEYS = 17 * 8 - -def chunks(l, n): - """Yield successive n-sized chunks from l.""" - for i in range(0, len(l), n): - yield l[i:i + n] - -def pairwise(t): - """Transforms sequence into sequence of pairs.""" - it = iter(t) - return zip(it,it) - -def digits_from_pi(): - """Reads digits from hexpi.sourceforge.net file.""" - with open("pi-hex.62500.txt") as file: - return file.read() - -def digits_from_urandom(): - """Reads digits from /dev/urandom.""" - with open("/dev/urandom") as file: - return binascii.hexlify(file.read(KEYS * 16)) - -def print_row(b) - print(" 0x{0}, 0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, -0x{10}, 0x{11}, 0x{12}, 0x{13}, 0x{14}, 0x{15},".format(*b)) - - -digits = digits_from_pi() -#digits = digits_from_urandom() - -print("namespace {") -print("static constexpr size_t kKeyBytes = {0};\n".format(KEYS * 16)) -print("}") - -print("alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = {") - -for i, u16 in zip(range(KEYS), chunks(digits, 32)): - b = list(chunks(u16, 2)) - print_row(b) - -print("};") - -print("alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = {") - -for i, u16 in zip(range(KEYS), chunks(digits, 32)): - b = list(chunks(u16, 2)) - b.reverse() - print_row(b) - -print("};") - -EOF - -*/ - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { -static constexpr size_t kKeyBytes = 2176; -} - -alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = { - 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, 0x13, 0x19, 0x8A, 0x2E, - 0x03, 0x70, 0x73, 0x44, 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, - 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89, 0x45, 0x28, 0x21, 0xE6, - 0x38, 0xD0, 0x13, 0x77, 0xBE, 0x54, 0x66, 0xCF, 0x34, 0xE9, 0x0C, 0x6C, - 0xC0, 0xAC, 0x29, 0xB7, 0xC9, 0x7C, 0x50, 0xDD, 0x3F, 0x84, 0xD5, 0xB5, - 0xB5, 0x47, 0x09, 0x17, 0x92, 0x16, 0xD5, 0xD9, 0x89, 0x79, 0xFB, 0x1B, - 0xD1, 0x31, 0x0B, 0xA6, 0x98, 0xDF, 0xB5, 0xAC, 0x2F, 0xFD, 0x72, 0xDB, - 0xD0, 0x1A, 0xDF, 0xB7, 0xB8, 0xE1, 0xAF, 0xED, 0x6A, 0x26, 0x7E, 0x96, - 0xBA, 0x7C, 0x90, 0x45, 0xF1, 0x2C, 0x7F, 0x99, 0x24, 0xA1, 0x99, 0x47, - 0xB3, 0x91, 0x6C, 0xF7, 0x08, 0x01, 0xF2, 0xE2, 0x85, 0x8E, 0xFC, 0x16, - 0x63, 0x69, 0x20, 0xD8, 0x71, 0x57, 0x4E, 0x69, 0xA4, 0x58, 0xFE, 0xA3, - 0xF4, 0x93, 0x3D, 0x7E, 0x0D, 0x95, 0x74, 0x8F, 0x72, 0x8E, 0xB6, 0x58, - 0x71, 0x8B, 0xCD, 0x58, 0x82, 0x15, 0x4A, 0xEE, 0x7B, 0x54, 0xA4, 0x1D, - 0xC2, 0x5A, 0x59, 0xB5, 0x9C, 0x30, 0xD5, 0x39, 0x2A, 0xF2, 0x60, 0x13, - 0xC5, 0xD1, 0xB0, 0x23, 0x28, 0x60, 0x85, 0xF0, 0xCA, 0x41, 0x79, 0x18, - 0xB8, 0xDB, 0x38, 0xEF, 0x8E, 0x79, 0xDC, 0xB0, 0x60, 0x3A, 0x18, 0x0E, - 0x6C, 0x9E, 0x0E, 0x8B, 0xB0, 0x1E, 0x8A, 0x3E, 0xD7, 0x15, 0x77, 0xC1, - 0xBD, 0x31, 0x4B, 0x27, 0x78, 0xAF, 0x2F, 0xDA, 0x55, 0x60, 0x5C, 0x60, - 0xE6, 0x55, 0x25, 0xF3, 0xAA, 0x55, 0xAB, 0x94, 0x57, 0x48, 0x98, 0x62, - 0x63, 0xE8, 0x14, 0x40, 0x55, 0xCA, 0x39, 0x6A, 0x2A, 0xAB, 0x10, 0xB6, - 0xB4, 0xCC, 0x5C, 0x34, 0x11, 0x41, 0xE8, 0xCE, 0xA1, 0x54, 0x86, 0xAF, - 0x7C, 0x72, 0xE9, 0x93, 0xB3, 0xEE, 0x14, 0x11, 0x63, 0x6F, 0xBC, 0x2A, - 0x2B, 0xA9, 0xC5, 0x5D, 0x74, 0x18, 0x31, 0xF6, 0xCE, 0x5C, 0x3E, 0x16, - 0x9B, 0x87, 0x93, 0x1E, 0xAF, 0xD6, 0xBA, 0x33, 0x6C, 0x24, 0xCF, 0x5C, - 0x7A, 0x32, 0x53, 0x81, 0x28, 0x95, 0x86, 0x77, 0x3B, 0x8F, 0x48, 0x98, - 0x6B, 0x4B, 0xB9, 0xAF, 0xC4, 0xBF, 0xE8, 0x1B, 0x66, 0x28, 0x21, 0x93, - 0x61, 0xD8, 0x09, 0xCC, 0xFB, 0x21, 0xA9, 0x91, 0x48, 0x7C, 0xAC, 0x60, - 0x5D, 0xEC, 0x80, 0x32, 0xEF, 0x84, 0x5D, 0x5D, 0xE9, 0x85, 0x75, 0xB1, - 0xDC, 0x26, 0x23, 0x02, 0xEB, 0x65, 0x1B, 0x88, 0x23, 0x89, 0x3E, 0x81, - 0xD3, 0x96, 0xAC, 0xC5, 0x0F, 0x6D, 0x6F, 0xF3, 0x83, 0xF4, 0x42, 0x39, - 0x2E, 0x0B, 0x44, 0x82, 0xA4, 0x84, 0x20, 0x04, 0x69, 0xC8, 0xF0, 0x4A, - 0x9E, 0x1F, 0x9B, 0x5E, 0x21, 0xC6, 0x68, 0x42, 0xF6, 0xE9, 0x6C, 0x9A, - 0x67, 0x0C, 0x9C, 0x61, 0xAB, 0xD3, 0x88, 0xF0, 0x6A, 0x51, 0xA0, 0xD2, - 0xD8, 0x54, 0x2F, 0x68, 0x96, 0x0F, 0xA7, 0x28, 0xAB, 0x51, 0x33, 0xA3, - 0x6E, 0xEF, 0x0B, 0x6C, 0x13, 0x7A, 0x3B, 0xE4, 0xBA, 0x3B, 0xF0, 0x50, - 0x7E, 0xFB, 0x2A, 0x98, 0xA1, 0xF1, 0x65, 0x1D, 0x39, 0xAF, 0x01, 0x76, - 0x66, 0xCA, 0x59, 0x3E, 0x82, 0x43, 0x0E, 0x88, 0x8C, 0xEE, 0x86, 0x19, - 0x45, 0x6F, 0x9F, 0xB4, 0x7D, 0x84, 0xA5, 0xC3, 0x3B, 0x8B, 0x5E, 0xBE, - 0xE0, 0x6F, 0x75, 0xD8, 0x85, 0xC1, 0x20, 0x73, 0x40, 0x1A, 0x44, 0x9F, - 0x56, 0xC1, 0x6A, 0xA6, 0x4E, 0xD3, 0xAA, 0x62, 0x36, 0x3F, 0x77, 0x06, - 0x1B, 0xFE, 0xDF, 0x72, 0x42, 0x9B, 0x02, 0x3D, 0x37, 0xD0, 0xD7, 0x24, - 0xD0, 0x0A, 0x12, 0x48, 0xDB, 0x0F, 0xEA, 0xD3, 0x49, 0xF1, 0xC0, 0x9B, - 0x07, 0x53, 0x72, 0xC9, 0x80, 0x99, 0x1B, 0x7B, 0x25, 0xD4, 0x79, 0xD8, - 0xF6, 0xE8, 0xDE, 0xF7, 0xE3, 0xFE, 0x50, 0x1A, 0xB6, 0x79, 0x4C, 0x3B, - 0x97, 0x6C, 0xE0, 0xBD, 0x04, 0xC0, 0x06, 0xBA, 0xC1, 0xA9, 0x4F, 0xB6, - 0x40, 0x9F, 0x60, 0xC4, 0x5E, 0x5C, 0x9E, 0xC2, 0x19, 0x6A, 0x24, 0x63, - 0x68, 0xFB, 0x6F, 0xAF, 0x3E, 0x6C, 0x53, 0xB5, 0x13, 0x39, 0xB2, 0xEB, - 0x3B, 0x52, 0xEC, 0x6F, 0x6D, 0xFC, 0x51, 0x1F, 0x9B, 0x30, 0x95, 0x2C, - 0xCC, 0x81, 0x45, 0x44, 0xAF, 0x5E, 0xBD, 0x09, 0xBE, 0xE3, 0xD0, 0x04, - 0xDE, 0x33, 0x4A, 0xFD, 0x66, 0x0F, 0x28, 0x07, 0x19, 0x2E, 0x4B, 0xB3, - 0xC0, 0xCB, 0xA8, 0x57, 0x45, 0xC8, 0x74, 0x0F, 0xD2, 0x0B, 0x5F, 0x39, - 0xB9, 0xD3, 0xFB, 0xDB, 0x55, 0x79, 0xC0, 0xBD, 0x1A, 0x60, 0x32, 0x0A, - 0xD6, 0xA1, 0x00, 0xC6, 0x40, 0x2C, 0x72, 0x79, 0x67, 0x9F, 0x25, 0xFE, - 0xFB, 0x1F, 0xA3, 0xCC, 0x8E, 0xA5, 0xE9, 0xF8, 0xDB, 0x32, 0x22, 0xF8, - 0x3C, 0x75, 0x16, 0xDF, 0xFD, 0x61, 0x6B, 0x15, 0x2F, 0x50, 0x1E, 0xC8, - 0xAD, 0x05, 0x52, 0xAB, 0x32, 0x3D, 0xB5, 0xFA, 0xFD, 0x23, 0x87, 0x60, - 0x53, 0x31, 0x7B, 0x48, 0x3E, 0x00, 0xDF, 0x82, 0x9E, 0x5C, 0x57, 0xBB, - 0xCA, 0x6F, 0x8C, 0xA0, 0x1A, 0x87, 0x56, 0x2E, 0xDF, 0x17, 0x69, 0xDB, - 0xD5, 0x42, 0xA8, 0xF6, 0x28, 0x7E, 0xFF, 0xC3, 0xAC, 0x67, 0x32, 0xC6, - 0x8C, 0x4F, 0x55, 0x73, 0x69, 0x5B, 0x27, 0xB0, 0xBB, 0xCA, 0x58, 0xC8, - 0xE1, 0xFF, 0xA3, 0x5D, 0xB8, 0xF0, 0x11, 0xA0, 0x10, 0xFA, 0x3D, 0x98, - 0xFD, 0x21, 0x83, 0xB8, 0x4A, 0xFC, 0xB5, 0x6C, 0x2D, 0xD1, 0xD3, 0x5B, - 0x9A, 0x53, 0xE4, 0x79, 0xB6, 0xF8, 0x45, 0x65, 0xD2, 0x8E, 0x49, 0xBC, - 0x4B, 0xFB, 0x97, 0x90, 0xE1, 0xDD, 0xF2, 0xDA, 0xA4, 0xCB, 0x7E, 0x33, - 0x62, 0xFB, 0x13, 0x41, 0xCE, 0xE4, 0xC6, 0xE8, 0xEF, 0x20, 0xCA, 0xDA, - 0x36, 0x77, 0x4C, 0x01, 0xD0, 0x7E, 0x9E, 0xFE, 0x2B, 0xF1, 0x1F, 0xB4, - 0x95, 0xDB, 0xDA, 0x4D, 0xAE, 0x90, 0x91, 0x98, 0xEA, 0xAD, 0x8E, 0x71, - 0x6B, 0x93, 0xD5, 0xA0, 0xD0, 0x8E, 0xD1, 0xD0, 0xAF, 0xC7, 0x25, 0xE0, - 0x8E, 0x3C, 0x5B, 0x2F, 0x8E, 0x75, 0x94, 0xB7, 0x8F, 0xF6, 0xE2, 0xFB, - 0xF2, 0x12, 0x2B, 0x64, 0x88, 0x88, 0xB8, 0x12, 0x90, 0x0D, 0xF0, 0x1C, - 0x4F, 0xAD, 0x5E, 0xA0, 0x68, 0x8F, 0xC3, 0x1C, 0xD1, 0xCF, 0xF1, 0x91, - 0xB3, 0xA8, 0xC1, 0xAD, 0x2F, 0x2F, 0x22, 0x18, 0xBE, 0x0E, 0x17, 0x77, - 0xEA, 0x75, 0x2D, 0xFE, 0x8B, 0x02, 0x1F, 0xA1, 0xE5, 0xA0, 0xCC, 0x0F, - 0xB5, 0x6F, 0x74, 0xE8, 0x18, 0xAC, 0xF3, 0xD6, 0xCE, 0x89, 0xE2, 0x99, - 0xB4, 0xA8, 0x4F, 0xE0, 0xFD, 0x13, 0xE0, 0xB7, 0x7C, 0xC4, 0x3B, 0x81, - 0xD2, 0xAD, 0xA8, 0xD9, 0x16, 0x5F, 0xA2, 0x66, 0x80, 0x95, 0x77, 0x05, - 0x93, 0xCC, 0x73, 0x14, 0x21, 0x1A, 0x14, 0x77, 0xE6, 0xAD, 0x20, 0x65, - 0x77, 0xB5, 0xFA, 0x86, 0xC7, 0x54, 0x42, 0xF5, 0xFB, 0x9D, 0x35, 0xCF, - 0xEB, 0xCD, 0xAF, 0x0C, 0x7B, 0x3E, 0x89, 0xA0, 0xD6, 0x41, 0x1B, 0xD3, - 0xAE, 0x1E, 0x7E, 0x49, 0x00, 0x25, 0x0E, 0x2D, 0x20, 0x71, 0xB3, 0x5E, - 0x22, 0x68, 0x00, 0xBB, 0x57, 0xB8, 0xE0, 0xAF, 0x24, 0x64, 0x36, 0x9B, - 0xF0, 0x09, 0xB9, 0x1E, 0x55, 0x63, 0x91, 0x1D, 0x59, 0xDF, 0xA6, 0xAA, - 0x78, 0xC1, 0x43, 0x89, 0xD9, 0x5A, 0x53, 0x7F, 0x20, 0x7D, 0x5B, 0xA2, - 0x02, 0xE5, 0xB9, 0xC5, 0x83, 0x26, 0x03, 0x76, 0x62, 0x95, 0xCF, 0xA9, - 0x11, 0xC8, 0x19, 0x68, 0x4E, 0x73, 0x4A, 0x41, 0xB3, 0x47, 0x2D, 0xCA, - 0x7B, 0x14, 0xA9, 0x4A, 0x1B, 0x51, 0x00, 0x52, 0x9A, 0x53, 0x29, 0x15, - 0xD6, 0x0F, 0x57, 0x3F, 0xBC, 0x9B, 0xC6, 0xE4, 0x2B, 0x60, 0xA4, 0x76, - 0x81, 0xE6, 0x74, 0x00, 0x08, 0xBA, 0x6F, 0xB5, 0x57, 0x1B, 0xE9, 0x1F, - 0xF2, 0x96, 0xEC, 0x6B, 0x2A, 0x0D, 0xD9, 0x15, 0xB6, 0x63, 0x65, 0x21, - 0xE7, 0xB9, 0xF9, 0xB6, 0xFF, 0x34, 0x05, 0x2E, 0xC5, 0x85, 0x56, 0x64, - 0x53, 0xB0, 0x2D, 0x5D, 0xA9, 0x9F, 0x8F, 0xA1, 0x08, 0xBA, 0x47, 0x99, - 0x6E, 0x85, 0x07, 0x6A, 0x4B, 0x7A, 0x70, 0xE9, 0xB5, 0xB3, 0x29, 0x44, - 0xDB, 0x75, 0x09, 0x2E, 0xC4, 0x19, 0x26, 0x23, 0xAD, 0x6E, 0xA6, 0xB0, - 0x49, 0xA7, 0xDF, 0x7D, 0x9C, 0xEE, 0x60, 0xB8, 0x8F, 0xED, 0xB2, 0x66, - 0xEC, 0xAA, 0x8C, 0x71, 0x69, 0x9A, 0x18, 0xFF, 0x56, 0x64, 0x52, 0x6C, - 0xC2, 0xB1, 0x9E, 0xE1, 0x19, 0x36, 0x02, 0xA5, 0x75, 0x09, 0x4C, 0x29, - 0xA0, 0x59, 0x13, 0x40, 0xE4, 0x18, 0x3A, 0x3E, 0x3F, 0x54, 0x98, 0x9A, - 0x5B, 0x42, 0x9D, 0x65, 0x6B, 0x8F, 0xE4, 0xD6, 0x99, 0xF7, 0x3F, 0xD6, - 0xA1, 0xD2, 0x9C, 0x07, 0xEF, 0xE8, 0x30, 0xF5, 0x4D, 0x2D, 0x38, 0xE6, - 0xF0, 0x25, 0x5D, 0xC1, 0x4C, 0xDD, 0x20, 0x86, 0x84, 0x70, 0xEB, 0x26, - 0x63, 0x82, 0xE9, 0xC6, 0x02, 0x1E, 0xCC, 0x5E, 0x09, 0x68, 0x6B, 0x3F, - 0x3E, 0xBA, 0xEF, 0xC9, 0x3C, 0x97, 0x18, 0x14, 0x6B, 0x6A, 0x70, 0xA1, - 0x68, 0x7F, 0x35, 0x84, 0x52, 0xA0, 0xE2, 0x86, 0xB7, 0x9C, 0x53, 0x05, - 0xAA, 0x50, 0x07, 0x37, 0x3E, 0x07, 0x84, 0x1C, 0x7F, 0xDE, 0xAE, 0x5C, - 0x8E, 0x7D, 0x44, 0xEC, 0x57, 0x16, 0xF2, 0xB8, 0xB0, 0x3A, 0xDA, 0x37, - 0xF0, 0x50, 0x0C, 0x0D, 0xF0, 0x1C, 0x1F, 0x04, 0x02, 0x00, 0xB3, 0xFF, - 0xAE, 0x0C, 0xF5, 0x1A, 0x3C, 0xB5, 0x74, 0xB2, 0x25, 0x83, 0x7A, 0x58, - 0xDC, 0x09, 0x21, 0xBD, 0xD1, 0x91, 0x13, 0xF9, 0x7C, 0xA9, 0x2F, 0xF6, - 0x94, 0x32, 0x47, 0x73, 0x22, 0xF5, 0x47, 0x01, 0x3A, 0xE5, 0xE5, 0x81, - 0x37, 0xC2, 0xDA, 0xDC, 0xC8, 0xB5, 0x76, 0x34, 0x9A, 0xF3, 0xDD, 0xA7, - 0xA9, 0x44, 0x61, 0x46, 0x0F, 0xD0, 0x03, 0x0E, 0xEC, 0xC8, 0xC7, 0x3E, - 0xA4, 0x75, 0x1E, 0x41, 0xE2, 0x38, 0xCD, 0x99, 0x3B, 0xEA, 0x0E, 0x2F, - 0x32, 0x80, 0xBB, 0xA1, 0x18, 0x3E, 0xB3, 0x31, 0x4E, 0x54, 0x8B, 0x38, - 0x4F, 0x6D, 0xB9, 0x08, 0x6F, 0x42, 0x0D, 0x03, 0xF6, 0x0A, 0x04, 0xBF, - 0x2C, 0xB8, 0x12, 0x90, 0x24, 0x97, 0x7C, 0x79, 0x56, 0x79, 0xB0, 0x72, - 0xBC, 0xAF, 0x89, 0xAF, 0xDE, 0x9A, 0x77, 0x1F, 0xD9, 0x93, 0x08, 0x10, - 0xB3, 0x8B, 0xAE, 0x12, 0xDC, 0xCF, 0x3F, 0x2E, 0x55, 0x12, 0x72, 0x1F, - 0x2E, 0x6B, 0x71, 0x24, 0x50, 0x1A, 0xDD, 0xE6, 0x9F, 0x84, 0xCD, 0x87, - 0x7A, 0x58, 0x47, 0x18, 0x74, 0x08, 0xDA, 0x17, 0xBC, 0x9F, 0x9A, 0xBC, - 0xE9, 0x4B, 0x7D, 0x8C, 0xEC, 0x7A, 0xEC, 0x3A, 0xDB, 0x85, 0x1D, 0xFA, - 0x63, 0x09, 0x43, 0x66, 0xC4, 0x64, 0xC3, 0xD2, 0xEF, 0x1C, 0x18, 0x47, - 0x32, 0x15, 0xD8, 0x08, 0xDD, 0x43, 0x3B, 0x37, 0x24, 0xC2, 0xBA, 0x16, - 0x12, 0xA1, 0x4D, 0x43, 0x2A, 0x65, 0xC4, 0x51, 0x50, 0x94, 0x00, 0x02, - 0x13, 0x3A, 0xE4, 0xDD, 0x71, 0xDF, 0xF8, 0x9E, 0x10, 0x31, 0x4E, 0x55, - 0x81, 0xAC, 0x77, 0xD6, 0x5F, 0x11, 0x19, 0x9B, 0x04, 0x35, 0x56, 0xF1, - 0xD7, 0xA3, 0xC7, 0x6B, 0x3C, 0x11, 0x18, 0x3B, 0x59, 0x24, 0xA5, 0x09, - 0xF2, 0x8F, 0xE6, 0xED, 0x97, 0xF1, 0xFB, 0xFA, 0x9E, 0xBA, 0xBF, 0x2C, - 0x1E, 0x15, 0x3C, 0x6E, 0x86, 0xE3, 0x45, 0x70, 0xEA, 0xE9, 0x6F, 0xB1, - 0x86, 0x0E, 0x5E, 0x0A, 0x5A, 0x3E, 0x2A, 0xB3, 0x77, 0x1F, 0xE7, 0x1C, - 0x4E, 0x3D, 0x06, 0xFA, 0x29, 0x65, 0xDC, 0xB9, 0x99, 0xE7, 0x1D, 0x0F, - 0x80, 0x3E, 0x89, 0xD6, 0x52, 0x66, 0xC8, 0x25, 0x2E, 0x4C, 0xC9, 0x78, - 0x9C, 0x10, 0xB3, 0x6A, 0xC6, 0x15, 0x0E, 0xBA, 0x94, 0xE2, 0xEA, 0x78, - 0xA6, 0xFC, 0x3C, 0x53, 0x1E, 0x0A, 0x2D, 0xF4, 0xF2, 0xF7, 0x4E, 0xA7, - 0x36, 0x1D, 0x2B, 0x3D, 0x19, 0x39, 0x26, 0x0F, 0x19, 0xC2, 0x79, 0x60, - 0x52, 0x23, 0xA7, 0x08, 0xF7, 0x13, 0x12, 0xB6, 0xEB, 0xAD, 0xFE, 0x6E, - 0xEA, 0xC3, 0x1F, 0x66, 0xE3, 0xBC, 0x45, 0x95, 0xA6, 0x7B, 0xC8, 0x83, - 0xB1, 0x7F, 0x37, 0xD1, 0x01, 0x8C, 0xFF, 0x28, 0xC3, 0x32, 0xDD, 0xEF, - 0xBE, 0x6C, 0x5A, 0xA5, 0x65, 0x58, 0x21, 0x85, 0x68, 0xAB, 0x97, 0x02, - 0xEE, 0xCE, 0xA5, 0x0F, 0xDB, 0x2F, 0x95, 0x3B, 0x2A, 0xEF, 0x7D, 0xAD, - 0x5B, 0x6E, 0x2F, 0x84, 0x15, 0x21, 0xB6, 0x28, 0x29, 0x07, 0x61, 0x70, - 0xEC, 0xDD, 0x47, 0x75, 0x61, 0x9F, 0x15, 0x10, 0x13, 0xCC, 0xA8, 0x30, - 0xEB, 0x61, 0xBD, 0x96, 0x03, 0x34, 0xFE, 0x1E, 0xAA, 0x03, 0x63, 0xCF, - 0xB5, 0x73, 0x5C, 0x90, 0x4C, 0x70, 0xA2, 0x39, 0xD5, 0x9E, 0x9E, 0x0B, - 0xCB, 0xAA, 0xDE, 0x14, 0xEE, 0xCC, 0x86, 0xBC, 0x60, 0x62, 0x2C, 0xA7, - 0x9C, 0xAB, 0x5C, 0xAB, 0xB2, 0xF3, 0x84, 0x6E, 0x64, 0x8B, 0x1E, 0xAF, - 0x19, 0xBD, 0xF0, 0xCA, 0xA0, 0x23, 0x69, 0xB9, 0x65, 0x5A, 0xBB, 0x50, - 0x40, 0x68, 0x5A, 0x32, 0x3C, 0x2A, 0xB4, 0xB3, 0x31, 0x9E, 0xE9, 0xD5, - 0xC0, 0x21, 0xB8, 0xF7, 0x9B, 0x54, 0x0B, 0x19, 0x87, 0x5F, 0xA0, 0x99, - 0x95, 0xF7, 0x99, 0x7E, 0x62, 0x3D, 0x7D, 0xA8, 0xF8, 0x37, 0x88, 0x9A, - 0x97, 0xE3, 0x2D, 0x77, 0x11, 0xED, 0x93, 0x5F, 0x16, 0x68, 0x12, 0x81, - 0x0E, 0x35, 0x88, 0x29, 0xC7, 0xE6, 0x1F, 0xD6, 0x96, 0xDE, 0xDF, 0xA1, - 0x78, 0x58, 0xBA, 0x99, 0x57, 0xF5, 0x84, 0xA5, 0x1B, 0x22, 0x72, 0x63, - 0x9B, 0x83, 0xC3, 0xFF, 0x1A, 0xC2, 0x46, 0x96, 0xCD, 0xB3, 0x0A, 0xEB, - 0x53, 0x2E, 0x30, 0x54, 0x8F, 0xD9, 0x48, 0xE4, 0x6D, 0xBC, 0x31, 0x28, - 0x58, 0xEB, 0xF2, 0xEF, 0x34, 0xC6, 0xFF, 0xEA, 0xFE, 0x28, 0xED, 0x61, - 0xEE, 0x7C, 0x3C, 0x73, 0x5D, 0x4A, 0x14, 0xD9, 0xE8, 0x64, 0xB7, 0xE3, - 0x42, 0x10, 0x5D, 0x14, 0x20, 0x3E, 0x13, 0xE0, 0x45, 0xEE, 0xE2, 0xB6, - 0xA3, 0xAA, 0xAB, 0xEA, 0xDB, 0x6C, 0x4F, 0x15, 0xFA, 0xCB, 0x4F, 0xD0, - 0xC7, 0x42, 0xF4, 0x42, 0xEF, 0x6A, 0xBB, 0xB5, 0x65, 0x4F, 0x3B, 0x1D, - 0x41, 0xCD, 0x21, 0x05, 0xD8, 0x1E, 0x79, 0x9E, 0x86, 0x85, 0x4D, 0xC7, - 0xE4, 0x4B, 0x47, 0x6A, 0x3D, 0x81, 0x62, 0x50, 0xCF, 0x62, 0xA1, 0xF2, - 0x5B, 0x8D, 0x26, 0x46, 0xFC, 0x88, 0x83, 0xA0, 0xC1, 0xC7, 0xB6, 0xA3, - 0x7F, 0x15, 0x24, 0xC3, 0x69, 0xCB, 0x74, 0x92, 0x47, 0x84, 0x8A, 0x0B, - 0x56, 0x92, 0xB2, 0x85, 0x09, 0x5B, 0xBF, 0x00, 0xAD, 0x19, 0x48, 0x9D, - 0x14, 0x62, 0xB1, 0x74, 0x23, 0x82, 0x0D, 0x00, 0x58, 0x42, 0x8D, 0x2A, - 0x0C, 0x55, 0xF5, 0xEA, 0x1D, 0xAD, 0xF4, 0x3E, 0x23, 0x3F, 0x70, 0x61, - 0x33, 0x72, 0xF0, 0x92, 0x8D, 0x93, 0x7E, 0x41, 0xD6, 0x5F, 0xEC, 0xF1, - 0x6C, 0x22, 0x3B, 0xDB, 0x7C, 0xDE, 0x37, 0x59, 0xCB, 0xEE, 0x74, 0x60, - 0x40, 0x85, 0xF2, 0xA7, 0xCE, 0x77, 0x32, 0x6E, 0xA6, 0x07, 0x80, 0x84, - 0x19, 0xF8, 0x50, 0x9E, 0xE8, 0xEF, 0xD8, 0x55, 0x61, 0xD9, 0x97, 0x35, - 0xA9, 0x69, 0xA7, 0xAA, 0xC5, 0x0C, 0x06, 0xC2, 0x5A, 0x04, 0xAB, 0xFC, - 0x80, 0x0B, 0xCA, 0xDC, 0x9E, 0x44, 0x7A, 0x2E, 0xC3, 0x45, 0x34, 0x84, - 0xFD, 0xD5, 0x67, 0x05, 0x0E, 0x1E, 0x9E, 0xC9, 0xDB, 0x73, 0xDB, 0xD3, - 0x10, 0x55, 0x88, 0xCD, 0x67, 0x5F, 0xDA, 0x79, 0xE3, 0x67, 0x43, 0x40, - 0xC5, 0xC4, 0x34, 0x65, 0x71, 0x3E, 0x38, 0xD8, 0x3D, 0x28, 0xF8, 0x9E, - 0xF1, 0x6D, 0xFF, 0x20, 0x15, 0x3E, 0x21, 0xE7, 0x8F, 0xB0, 0x3D, 0x4A, - 0xE6, 0xE3, 0x9F, 0x2B, 0xDB, 0x83, 0xAD, 0xF7, 0xE9, 0x3D, 0x5A, 0x68, - 0x94, 0x81, 0x40, 0xF7, 0xF6, 0x4C, 0x26, 0x1C, 0x94, 0x69, 0x29, 0x34, - 0x41, 0x15, 0x20, 0xF7, 0x76, 0x02, 0xD4, 0xF7, 0xBC, 0xF4, 0x6B, 0x2E, - 0xD4, 0xA1, 0x00, 0x68, 0xD4, 0x08, 0x24, 0x71, 0x33, 0x20, 0xF4, 0x6A, - 0x43, 0xB7, 0xD4, 0xB7, 0x50, 0x00, 0x61, 0xAF, 0x1E, 0x39, 0xF6, 0x2E, - 0x97, 0x24, 0x45, 0x46, -}; - -alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = { - 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13, 0xD3, 0x08, 0xA3, 0x85, - 0x88, 0x6A, 0x3F, 0x24, 0x89, 0x6C, 0x4E, 0xEC, 0x98, 0xFA, 0x2E, 0x08, - 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38, 0x09, 0xA4, 0x6C, 0x0C, 0xE9, 0x34, - 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13, 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, - 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5, 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, - 0xB7, 0x29, 0xAC, 0xC0, 0xAC, 0xB5, 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, - 0x1B, 0xFB, 0x79, 0x89, 0xD9, 0xD5, 0x16, 0x92, 0x96, 0x7E, 0x26, 0x6A, - 0xED, 0xAF, 0xE1, 0xB8, 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, - 0xF7, 0x6C, 0x91, 0xB3, 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, - 0x45, 0x90, 0x7C, 0xBA, 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, - 0x16, 0xFC, 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0x58, 0xB6, 0x8E, 0x72, - 0x8F, 0x74, 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4, - 0xB5, 0x59, 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82, - 0x58, 0xCD, 0x8B, 0x71, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5, - 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0x0E, 0x18, 0x3A, 0x60, - 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79, 0x41, 0xCA, - 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A, 0x1E, 0xB0, - 0x8B, 0x0E, 0x9E, 0x6C, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25, 0x55, 0xE6, - 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78, 0xB6, 0x10, 0xAB, 0x2A, - 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63, 0x62, 0x98, 0x48, 0x57, - 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1, 0xCE, 0xE8, 0x41, 0x11, - 0x34, 0x5C, 0xCC, 0xB4, 0xF6, 0x31, 0x18, 0x74, 0x5D, 0xC5, 0xA9, 0x2B, - 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14, 0xEE, 0xB3, 0x5C, 0xCF, 0x24, 0x6C, - 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93, 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, - 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48, 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, - 0x81, 0x53, 0x32, 0x7A, 0x91, 0xA9, 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, - 0x93, 0x21, 0x28, 0x66, 0x1B, 0xE8, 0xBF, 0xC4, 0xB1, 0x75, 0x85, 0xE9, - 0x5D, 0x5D, 0x84, 0xEF, 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, - 0xC5, 0xAC, 0x96, 0xD3, 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, - 0x02, 0x23, 0x26, 0xDC, 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, - 0x39, 0x42, 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0x9A, 0x6C, 0xE9, 0xF6, - 0x42, 0x68, 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69, - 0x68, 0x2F, 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB, - 0x61, 0x9C, 0x0C, 0x67, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E, - 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x76, 0x01, 0xAF, 0x39, - 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0, 0x3B, 0xBA, - 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E, 0x43, 0x82, - 0x3E, 0x59, 0xCA, 0x66, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75, 0x6F, 0xE0, - 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D, 0x06, 0x77, 0x3F, 0x36, - 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56, 0x9F, 0x44, 0x1A, 0x40, - 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37, 0x3D, 0x02, 0x9B, 0x42, - 0x72, 0xDF, 0xFE, 0x1B, 0x7B, 0x1B, 0x99, 0x80, 0xC9, 0x72, 0x53, 0x07, - 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA, 0x0F, 0xDB, 0x3B, 0x4C, 0x79, 0xB6, - 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE, 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, - 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F, 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, - 0xBD, 0xE0, 0x6C, 0x97, 0xB5, 0x53, 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, - 0x63, 0x24, 0x6A, 0x19, 0xC2, 0x9E, 0x5C, 0x5E, 0x2C, 0x95, 0x30, 0x9B, - 0x1F, 0x51, 0xFC, 0x6D, 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, - 0xFD, 0x4A, 0x33, 0xDE, 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, - 0x44, 0x45, 0x81, 0xCC, 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, - 0xB3, 0x4B, 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0x0A, 0x32, 0x60, 0x1A, - 0xBD, 0xC0, 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2, - 0xCC, 0xA3, 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40, - 0xC6, 0x00, 0xA1, 0xD6, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C, - 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0x60, 0x87, 0x23, 0xFD, - 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E, 0x50, 0x2F, - 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF, 0x00, 0x3E, - 0x48, 0x7B, 0x31, 0x53, 0xC3, 0xFF, 0x7E, 0x28, 0xF6, 0xA8, 0x42, 0xD5, - 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A, 0xC8, 0x58, 0xCA, 0xBB, - 0xB0, 0x27, 0x5B, 0x69, 0x73, 0x55, 0x4F, 0x8C, 0xC6, 0x32, 0x67, 0xAC, - 0xB8, 0x83, 0x21, 0xFD, 0x98, 0x3D, 0xFA, 0x10, 0xA0, 0x11, 0xF0, 0xB8, - 0x5D, 0xA3, 0xFF, 0xE1, 0x65, 0x45, 0xF8, 0xB6, 0x79, 0xE4, 0x53, 0x9A, - 0x5B, 0xD3, 0xD1, 0x2D, 0x6C, 0xB5, 0xFC, 0x4A, 0x33, 0x7E, 0xCB, 0xA4, - 0xDA, 0xF2, 0xDD, 0xE1, 0x90, 0x97, 0xFB, 0x4B, 0xBC, 0x49, 0x8E, 0xD2, - 0x01, 0x4C, 0x77, 0x36, 0xDA, 0xCA, 0x20, 0xEF, 0xE8, 0xC6, 0xE4, 0xCE, - 0x41, 0x13, 0xFB, 0x62, 0x98, 0x91, 0x90, 0xAE, 0x4D, 0xDA, 0xDB, 0x95, - 0xB4, 0x1F, 0xF1, 0x2B, 0xFE, 0x9E, 0x7E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, - 0xD0, 0xD1, 0x8E, 0xD0, 0xA0, 0xD5, 0x93, 0x6B, 0x71, 0x8E, 0xAD, 0xEA, - 0x64, 0x2B, 0x12, 0xF2, 0xFB, 0xE2, 0xF6, 0x8F, 0xB7, 0x94, 0x75, 0x8E, - 0x2F, 0x5B, 0x3C, 0x8E, 0x1C, 0xC3, 0x8F, 0x68, 0xA0, 0x5E, 0xAD, 0x4F, - 0x1C, 0xF0, 0x0D, 0x90, 0x12, 0xB8, 0x88, 0x88, 0x77, 0x17, 0x0E, 0xBE, - 0x18, 0x22, 0x2F, 0x2F, 0xAD, 0xC1, 0xA8, 0xB3, 0x91, 0xF1, 0xCF, 0xD1, - 0xE8, 0x74, 0x6F, 0xB5, 0x0F, 0xCC, 0xA0, 0xE5, 0xA1, 0x1F, 0x02, 0x8B, - 0xFE, 0x2D, 0x75, 0xEA, 0xB7, 0xE0, 0x13, 0xFD, 0xE0, 0x4F, 0xA8, 0xB4, - 0x99, 0xE2, 0x89, 0xCE, 0xD6, 0xF3, 0xAC, 0x18, 0x05, 0x77, 0x95, 0x80, - 0x66, 0xA2, 0x5F, 0x16, 0xD9, 0xA8, 0xAD, 0xD2, 0x81, 0x3B, 0xC4, 0x7C, - 0x86, 0xFA, 0xB5, 0x77, 0x65, 0x20, 0xAD, 0xE6, 0x77, 0x14, 0x1A, 0x21, - 0x14, 0x73, 0xCC, 0x93, 0xA0, 0x89, 0x3E, 0x7B, 0x0C, 0xAF, 0xCD, 0xEB, - 0xCF, 0x35, 0x9D, 0xFB, 0xF5, 0x42, 0x54, 0xC7, 0x5E, 0xB3, 0x71, 0x20, - 0x2D, 0x0E, 0x25, 0x00, 0x49, 0x7E, 0x1E, 0xAE, 0xD3, 0x1B, 0x41, 0xD6, - 0x1E, 0xB9, 0x09, 0xF0, 0x9B, 0x36, 0x64, 0x24, 0xAF, 0xE0, 0xB8, 0x57, - 0xBB, 0x00, 0x68, 0x22, 0x7F, 0x53, 0x5A, 0xD9, 0x89, 0x43, 0xC1, 0x78, - 0xAA, 0xA6, 0xDF, 0x59, 0x1D, 0x91, 0x63, 0x55, 0xA9, 0xCF, 0x95, 0x62, - 0x76, 0x03, 0x26, 0x83, 0xC5, 0xB9, 0xE5, 0x02, 0xA2, 0x5B, 0x7D, 0x20, - 0x4A, 0xA9, 0x14, 0x7B, 0xCA, 0x2D, 0x47, 0xB3, 0x41, 0x4A, 0x73, 0x4E, - 0x68, 0x19, 0xC8, 0x11, 0xE4, 0xC6, 0x9B, 0xBC, 0x3F, 0x57, 0x0F, 0xD6, - 0x15, 0x29, 0x53, 0x9A, 0x52, 0x00, 0x51, 0x1B, 0x1F, 0xE9, 0x1B, 0x57, - 0xB5, 0x6F, 0xBA, 0x08, 0x00, 0x74, 0xE6, 0x81, 0x76, 0xA4, 0x60, 0x2B, - 0xB6, 0xF9, 0xB9, 0xE7, 0x21, 0x65, 0x63, 0xB6, 0x15, 0xD9, 0x0D, 0x2A, - 0x6B, 0xEC, 0x96, 0xF2, 0xA1, 0x8F, 0x9F, 0xA9, 0x5D, 0x2D, 0xB0, 0x53, - 0x64, 0x56, 0x85, 0xC5, 0x2E, 0x05, 0x34, 0xFF, 0x44, 0x29, 0xB3, 0xB5, - 0xE9, 0x70, 0x7A, 0x4B, 0x6A, 0x07, 0x85, 0x6E, 0x99, 0x47, 0xBA, 0x08, - 0x7D, 0xDF, 0xA7, 0x49, 0xB0, 0xA6, 0x6E, 0xAD, 0x23, 0x26, 0x19, 0xC4, - 0x2E, 0x09, 0x75, 0xDB, 0xFF, 0x18, 0x9A, 0x69, 0x71, 0x8C, 0xAA, 0xEC, - 0x66, 0xB2, 0xED, 0x8F, 0xB8, 0x60, 0xEE, 0x9C, 0x29, 0x4C, 0x09, 0x75, - 0xA5, 0x02, 0x36, 0x19, 0xE1, 0x9E, 0xB1, 0xC2, 0x6C, 0x52, 0x64, 0x56, - 0x65, 0x9D, 0x42, 0x5B, 0x9A, 0x98, 0x54, 0x3F, 0x3E, 0x3A, 0x18, 0xE4, - 0x40, 0x13, 0x59, 0xA0, 0xF5, 0x30, 0xE8, 0xEF, 0x07, 0x9C, 0xD2, 0xA1, - 0xD6, 0x3F, 0xF7, 0x99, 0xD6, 0xE4, 0x8F, 0x6B, 0x26, 0xEB, 0x70, 0x84, - 0x86, 0x20, 0xDD, 0x4C, 0xC1, 0x5D, 0x25, 0xF0, 0xE6, 0x38, 0x2D, 0x4D, - 0xC9, 0xEF, 0xBA, 0x3E, 0x3F, 0x6B, 0x68, 0x09, 0x5E, 0xCC, 0x1E, 0x02, - 0xC6, 0xE9, 0x82, 0x63, 0x86, 0xE2, 0xA0, 0x52, 0x84, 0x35, 0x7F, 0x68, - 0xA1, 0x70, 0x6A, 0x6B, 0x14, 0x18, 0x97, 0x3C, 0x5C, 0xAE, 0xDE, 0x7F, - 0x1C, 0x84, 0x07, 0x3E, 0x37, 0x07, 0x50, 0xAA, 0x05, 0x53, 0x9C, 0xB7, - 0x0D, 0x0C, 0x50, 0xF0, 0x37, 0xDA, 0x3A, 0xB0, 0xB8, 0xF2, 0x16, 0x57, - 0xEC, 0x44, 0x7D, 0x8E, 0xB2, 0x74, 0xB5, 0x3C, 0x1A, 0xF5, 0x0C, 0xAE, - 0xFF, 0xB3, 0x00, 0x02, 0x04, 0x1F, 0x1C, 0xF0, 0xF6, 0x2F, 0xA9, 0x7C, - 0xF9, 0x13, 0x91, 0xD1, 0xBD, 0x21, 0x09, 0xDC, 0x58, 0x7A, 0x83, 0x25, - 0xDC, 0xDA, 0xC2, 0x37, 0x81, 0xE5, 0xE5, 0x3A, 0x01, 0x47, 0xF5, 0x22, - 0x73, 0x47, 0x32, 0x94, 0x0E, 0x03, 0xD0, 0x0F, 0x46, 0x61, 0x44, 0xA9, - 0xA7, 0xDD, 0xF3, 0x9A, 0x34, 0x76, 0xB5, 0xC8, 0x2F, 0x0E, 0xEA, 0x3B, - 0x99, 0xCD, 0x38, 0xE2, 0x41, 0x1E, 0x75, 0xA4, 0x3E, 0xC7, 0xC8, 0xEC, - 0x08, 0xB9, 0x6D, 0x4F, 0x38, 0x8B, 0x54, 0x4E, 0x31, 0xB3, 0x3E, 0x18, - 0xA1, 0xBB, 0x80, 0x32, 0x79, 0x7C, 0x97, 0x24, 0x90, 0x12, 0xB8, 0x2C, - 0xBF, 0x04, 0x0A, 0xF6, 0x03, 0x0D, 0x42, 0x6F, 0x10, 0x08, 0x93, 0xD9, - 0x1F, 0x77, 0x9A, 0xDE, 0xAF, 0x89, 0xAF, 0xBC, 0x72, 0xB0, 0x79, 0x56, - 0x24, 0x71, 0x6B, 0x2E, 0x1F, 0x72, 0x12, 0x55, 0x2E, 0x3F, 0xCF, 0xDC, - 0x12, 0xAE, 0x8B, 0xB3, 0x17, 0xDA, 0x08, 0x74, 0x18, 0x47, 0x58, 0x7A, - 0x87, 0xCD, 0x84, 0x9F, 0xE6, 0xDD, 0x1A, 0x50, 0xFA, 0x1D, 0x85, 0xDB, - 0x3A, 0xEC, 0x7A, 0xEC, 0x8C, 0x7D, 0x4B, 0xE9, 0xBC, 0x9A, 0x9F, 0xBC, - 0x08, 0xD8, 0x15, 0x32, 0x47, 0x18, 0x1C, 0xEF, 0xD2, 0xC3, 0x64, 0xC4, - 0x66, 0x43, 0x09, 0x63, 0x51, 0xC4, 0x65, 0x2A, 0x43, 0x4D, 0xA1, 0x12, - 0x16, 0xBA, 0xC2, 0x24, 0x37, 0x3B, 0x43, 0xDD, 0x55, 0x4E, 0x31, 0x10, - 0x9E, 0xF8, 0xDF, 0x71, 0xDD, 0xE4, 0x3A, 0x13, 0x02, 0x00, 0x94, 0x50, - 0x6B, 0xC7, 0xA3, 0xD7, 0xF1, 0x56, 0x35, 0x04, 0x9B, 0x19, 0x11, 0x5F, - 0xD6, 0x77, 0xAC, 0x81, 0xFA, 0xFB, 0xF1, 0x97, 0xED, 0xE6, 0x8F, 0xF2, - 0x09, 0xA5, 0x24, 0x59, 0x3B, 0x18, 0x11, 0x3C, 0xB1, 0x6F, 0xE9, 0xEA, - 0x70, 0x45, 0xE3, 0x86, 0x6E, 0x3C, 0x15, 0x1E, 0x2C, 0xBF, 0xBA, 0x9E, - 0xFA, 0x06, 0x3D, 0x4E, 0x1C, 0xE7, 0x1F, 0x77, 0xB3, 0x2A, 0x3E, 0x5A, - 0x0A, 0x5E, 0x0E, 0x86, 0x25, 0xC8, 0x66, 0x52, 0xD6, 0x89, 0x3E, 0x80, - 0x0F, 0x1D, 0xE7, 0x99, 0xB9, 0xDC, 0x65, 0x29, 0x78, 0xEA, 0xE2, 0x94, - 0xBA, 0x0E, 0x15, 0xC6, 0x6A, 0xB3, 0x10, 0x9C, 0x78, 0xC9, 0x4C, 0x2E, - 0x3D, 0x2B, 0x1D, 0x36, 0xA7, 0x4E, 0xF7, 0xF2, 0xF4, 0x2D, 0x0A, 0x1E, - 0x53, 0x3C, 0xFC, 0xA6, 0xB6, 0x12, 0x13, 0xF7, 0x08, 0xA7, 0x23, 0x52, - 0x60, 0x79, 0xC2, 0x19, 0x0F, 0x26, 0x39, 0x19, 0x83, 0xC8, 0x7B, 0xA6, - 0x95, 0x45, 0xBC, 0xE3, 0x66, 0x1F, 0xC3, 0xEA, 0x6E, 0xFE, 0xAD, 0xEB, - 0xA5, 0x5A, 0x6C, 0xBE, 0xEF, 0xDD, 0x32, 0xC3, 0x28, 0xFF, 0x8C, 0x01, - 0xD1, 0x37, 0x7F, 0xB1, 0x3B, 0x95, 0x2F, 0xDB, 0x0F, 0xA5, 0xCE, 0xEE, - 0x02, 0x97, 0xAB, 0x68, 0x85, 0x21, 0x58, 0x65, 0x70, 0x61, 0x07, 0x29, - 0x28, 0xB6, 0x21, 0x15, 0x84, 0x2F, 0x6E, 0x5B, 0xAD, 0x7D, 0xEF, 0x2A, - 0x96, 0xBD, 0x61, 0xEB, 0x30, 0xA8, 0xCC, 0x13, 0x10, 0x15, 0x9F, 0x61, - 0x75, 0x47, 0xDD, 0xEC, 0x39, 0xA2, 0x70, 0x4C, 0x90, 0x5C, 0x73, 0xB5, - 0xCF, 0x63, 0x03, 0xAA, 0x1E, 0xFE, 0x34, 0x03, 0xA7, 0x2C, 0x62, 0x60, - 0xBC, 0x86, 0xCC, 0xEE, 0x14, 0xDE, 0xAA, 0xCB, 0x0B, 0x9E, 0x9E, 0xD5, - 0xCA, 0xF0, 0xBD, 0x19, 0xAF, 0x1E, 0x8B, 0x64, 0x6E, 0x84, 0xF3, 0xB2, - 0xAB, 0x5C, 0xAB, 0x9C, 0xB3, 0xB4, 0x2A, 0x3C, 0x32, 0x5A, 0x68, 0x40, - 0x50, 0xBB, 0x5A, 0x65, 0xB9, 0x69, 0x23, 0xA0, 0x99, 0xA0, 0x5F, 0x87, - 0x19, 0x0B, 0x54, 0x9B, 0xF7, 0xB8, 0x21, 0xC0, 0xD5, 0xE9, 0x9E, 0x31, - 0x77, 0x2D, 0xE3, 0x97, 0x9A, 0x88, 0x37, 0xF8, 0xA8, 0x7D, 0x3D, 0x62, - 0x7E, 0x99, 0xF7, 0x95, 0xD6, 0x1F, 0xE6, 0xC7, 0x29, 0x88, 0x35, 0x0E, - 0x81, 0x12, 0x68, 0x16, 0x5F, 0x93, 0xED, 0x11, 0x63, 0x72, 0x22, 0x1B, - 0xA5, 0x84, 0xF5, 0x57, 0x99, 0xBA, 0x58, 0x78, 0xA1, 0xDF, 0xDE, 0x96, - 0x54, 0x30, 0x2E, 0x53, 0xEB, 0x0A, 0xB3, 0xCD, 0x96, 0x46, 0xC2, 0x1A, - 0xFF, 0xC3, 0x83, 0x9B, 0xEA, 0xFF, 0xC6, 0x34, 0xEF, 0xF2, 0xEB, 0x58, - 0x28, 0x31, 0xBC, 0x6D, 0xE4, 0x48, 0xD9, 0x8F, 0xE3, 0xB7, 0x64, 0xE8, - 0xD9, 0x14, 0x4A, 0x5D, 0x73, 0x3C, 0x7C, 0xEE, 0x61, 0xED, 0x28, 0xFE, - 0xEA, 0xAB, 0xAA, 0xA3, 0xB6, 0xE2, 0xEE, 0x45, 0xE0, 0x13, 0x3E, 0x20, - 0x14, 0x5D, 0x10, 0x42, 0xB5, 0xBB, 0x6A, 0xEF, 0x42, 0xF4, 0x42, 0xC7, - 0xD0, 0x4F, 0xCB, 0xFA, 0x15, 0x4F, 0x6C, 0xDB, 0xC7, 0x4D, 0x85, 0x86, - 0x9E, 0x79, 0x1E, 0xD8, 0x05, 0x21, 0xCD, 0x41, 0x1D, 0x3B, 0x4F, 0x65, - 0x46, 0x26, 0x8D, 0x5B, 0xF2, 0xA1, 0x62, 0xCF, 0x50, 0x62, 0x81, 0x3D, - 0x6A, 0x47, 0x4B, 0xE4, 0x92, 0x74, 0xCB, 0x69, 0xC3, 0x24, 0x15, 0x7F, - 0xA3, 0xB6, 0xC7, 0xC1, 0xA0, 0x83, 0x88, 0xFC, 0x9D, 0x48, 0x19, 0xAD, - 0x00, 0xBF, 0x5B, 0x09, 0x85, 0xB2, 0x92, 0x56, 0x0B, 0x8A, 0x84, 0x47, - 0xEA, 0xF5, 0x55, 0x0C, 0x2A, 0x8D, 0x42, 0x58, 0x00, 0x0D, 0x82, 0x23, - 0x74, 0xB1, 0x62, 0x14, 0x41, 0x7E, 0x93, 0x8D, 0x92, 0xF0, 0x72, 0x33, - 0x61, 0x70, 0x3F, 0x23, 0x3E, 0xF4, 0xAD, 0x1D, 0x60, 0x74, 0xEE, 0xCB, - 0x59, 0x37, 0xDE, 0x7C, 0xDB, 0x3B, 0x22, 0x6C, 0xF1, 0xEC, 0x5F, 0xD6, - 0x9E, 0x50, 0xF8, 0x19, 0x84, 0x80, 0x07, 0xA6, 0x6E, 0x32, 0x77, 0xCE, - 0xA7, 0xF2, 0x85, 0x40, 0xC2, 0x06, 0x0C, 0xC5, 0xAA, 0xA7, 0x69, 0xA9, - 0x35, 0x97, 0xD9, 0x61, 0x55, 0xD8, 0xEF, 0xE8, 0x84, 0x34, 0x45, 0xC3, - 0x2E, 0x7A, 0x44, 0x9E, 0xDC, 0xCA, 0x0B, 0x80, 0xFC, 0xAB, 0x04, 0x5A, - 0xCD, 0x88, 0x55, 0x10, 0xD3, 0xDB, 0x73, 0xDB, 0xC9, 0x9E, 0x1E, 0x0E, - 0x05, 0x67, 0xD5, 0xFD, 0xD8, 0x38, 0x3E, 0x71, 0x65, 0x34, 0xC4, 0xC5, - 0x40, 0x43, 0x67, 0xE3, 0x79, 0xDA, 0x5F, 0x67, 0x4A, 0x3D, 0xB0, 0x8F, - 0xE7, 0x21, 0x3E, 0x15, 0x20, 0xFF, 0x6D, 0xF1, 0x9E, 0xF8, 0x28, 0x3D, - 0xF7, 0x40, 0x81, 0x94, 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0xAD, 0x83, 0xDB, - 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xD4, 0x02, 0x76, 0xF7, 0x20, 0x15, 0x41, - 0x34, 0x29, 0x69, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x6A, 0xF4, 0x20, 0x33, - 0x71, 0x24, 0x08, 0xD4, 0x68, 0x00, 0xA1, 0xD4, 0x2E, 0x6B, 0xF4, 0xBC, - 0x46, 0x45, 0x24, 0x97, 0x2E, 0xF6, 0x39, 0x1E, 0xAF, 0x61, 0x00, 0x50, - 0xB7, 0xD4, 0xB7, 0x43, -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/randen_slow.cc b/third_party/abseil_cpp/absl/random/internal/randen_slow.cc deleted file mode 100644 index 4e5f3dc1c7b7..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_slow.cc +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen_slow.h" - -#include <cstddef> -#include <cstdint> -#include <cstring> - -#include "absl/base/attributes.h" -#include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_traits.h" - -#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ - (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE \ - __attribute__((always_inline)) -#elif defined(_MSC_VER) -// We can achieve something similar to attribute((always_inline)) with MSVC by -// using the __forceinline keyword, however this is not perfect. MSVC is -// much less aggressive about inlining, and even with the __forceinline keyword. -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE __forceinline -#else -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE -#endif - -namespace { - -// AES portions based on rijndael-alg-fst.c, -// https://fastcrypto.org/front/misc/rijndael-alg-fst.c -// -// Implementation of -// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf -constexpr uint32_t te0[256] = { - 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, - 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, - 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, - 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, - 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, - 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, - 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, - 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, - 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, - 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, - 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e, - 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, - 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, - 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, - 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, - 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, - 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, - 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, - 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, - 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, - 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, - 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, - 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, - 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, - 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, - 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, - 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, - 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, - 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, - 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, - 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, - 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, - 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, - 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, - 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, - 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, - 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, - 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, - 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, - 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, - 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, - 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, - 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, -}; - -constexpr uint32_t te1[256] = { - 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, - 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, - 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282, - 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, - 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, - 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, - 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5, - 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, - 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, - 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, - 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383, - 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, - 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, - 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, - 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb, - 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, - 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, - 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, - 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3, - 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, - 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, - 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, - 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7, - 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, - 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, - 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, - 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232, - 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, - 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, - 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, - 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656, - 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, - 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, - 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, - 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e, - 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, - 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, - 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, - 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e, - 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, - 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, - 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, - 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, -}; - -constexpr uint32_t te2[256] = { - 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, - 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, - 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82, - 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, - 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, - 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, - 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5, - 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, - 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, - 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, - 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83, - 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, - 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, - 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, - 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb, - 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, - 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, - 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, - 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3, - 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, - 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, - 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, - 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7, - 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, - 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, - 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, - 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432, - 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, - 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, - 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, - 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56, - 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, - 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, - 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, - 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e, - 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, - 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, - 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, - 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e, - 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, - 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, - 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, - 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, -}; - -constexpr uint32_t te3[256] = { - 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, - 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, - 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f, - 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, - 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, - 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, - 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451, - 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, - 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, - 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, - 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d, - 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, - 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, - 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, - 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d, - 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, - 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, - 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, - 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d, - 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, - 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, - 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, - 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255, - 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, - 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, - 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, - 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664, - 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, - 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, - 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, - 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac, - 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, - 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, - 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, - 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c, - 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, - 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, - 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, - 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c, - 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, - 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, - 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, - 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, -}; - -// Software implementation of the Vector128 class, using uint32_t -// as an underlying vector register. -struct alignas(16) Vector128 { - uint32_t s[4]; -}; - -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -Vector128Load(const void* from) { - Vector128 result; - const uint8_t* src = reinterpret_cast<const uint8_t*>(from); - result.s[0] = static_cast<uint32_t>(src[0]) << 24 | - static_cast<uint32_t>(src[1]) << 16 | - static_cast<uint32_t>(src[2]) << 8 | - static_cast<uint32_t>(src[3]); - result.s[1] = static_cast<uint32_t>(src[4]) << 24 | - static_cast<uint32_t>(src[5]) << 16 | - static_cast<uint32_t>(src[6]) << 8 | - static_cast<uint32_t>(src[7]); - result.s[2] = static_cast<uint32_t>(src[8]) << 24 | - static_cast<uint32_t>(src[9]) << 16 | - static_cast<uint32_t>(src[10]) << 8 | - static_cast<uint32_t>(src[11]); - result.s[3] = static_cast<uint32_t>(src[12]) << 24 | - static_cast<uint32_t>(src[13]) << 16 | - static_cast<uint32_t>(src[14]) << 8 | - static_cast<uint32_t>(src[15]); - return result; -} - -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store( - const Vector128& v, void* to) { - uint8_t* dst = reinterpret_cast<uint8_t*>(to); - dst[0] = static_cast<uint8_t>(v.s[0] >> 24); - dst[1] = static_cast<uint8_t>(v.s[0] >> 16); - dst[2] = static_cast<uint8_t>(v.s[0] >> 8); - dst[3] = static_cast<uint8_t>(v.s[0]); - dst[4] = static_cast<uint8_t>(v.s[1] >> 24); - dst[5] = static_cast<uint8_t>(v.s[1] >> 16); - dst[6] = static_cast<uint8_t>(v.s[1] >> 8); - dst[7] = static_cast<uint8_t>(v.s[1]); - dst[8] = static_cast<uint8_t>(v.s[2] >> 24); - dst[9] = static_cast<uint8_t>(v.s[2] >> 16); - dst[10] = static_cast<uint8_t>(v.s[2] >> 8); - dst[11] = static_cast<uint8_t>(v.s[2]); - dst[12] = static_cast<uint8_t>(v.s[3] >> 24); - dst[13] = static_cast<uint8_t>(v.s[3] >> 16); - dst[14] = static_cast<uint8_t>(v.s[3] >> 8); - dst[15] = static_cast<uint8_t>(v.s[3]); -} - -// One round of AES. "round_key" is a public constant for breaking the -// symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -AesRound(const Vector128& state, const Vector128& round_key) { - Vector128 result; - result.s[0] = round_key.s[0] ^ // - te0[uint8_t(state.s[0] >> 24)] ^ // - te1[uint8_t(state.s[1] >> 16)] ^ // - te2[uint8_t(state.s[2] >> 8)] ^ // - te3[uint8_t(state.s[3])]; - result.s[1] = round_key.s[1] ^ // - te0[uint8_t(state.s[1] >> 24)] ^ // - te1[uint8_t(state.s[2] >> 16)] ^ // - te2[uint8_t(state.s[3] >> 8)] ^ // - te3[uint8_t(state.s[0])]; - result.s[2] = round_key.s[2] ^ // - te0[uint8_t(state.s[2] >> 24)] ^ // - te1[uint8_t(state.s[3] >> 16)] ^ // - te2[uint8_t(state.s[0] >> 8)] ^ // - te3[uint8_t(state.s[1])]; - result.s[3] = round_key.s[3] ^ // - te0[uint8_t(state.s[3] >> 24)] ^ // - te1[uint8_t(state.s[0] >> 16)] ^ // - te2[uint8_t(state.s[1] >> 8)] ^ // - te3[uint8_t(state.s[2])]; - return result; -} - -using ::absl::random_internal::RandenTraits; - -// Randen operates on 128-bit vectors. -struct alignas(16) u64x2 { - uint64_t data[2]; -}; - -// The improved Feistel block shuffle function for 16 blocks. -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( - u64x2* state) { - static_assert(RandenTraits::kFeistelBlocks == 16, - "Feistel block shuffle only works for 16 blocks."); - - constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { - 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; - - // The fully unrolled loop without the memcpy improves the speed by about - // 30% over the equivalent: -#if 0 - u64x2 source[RandenTraits::kFeistelBlocks]; - std::memcpy(source, state, sizeof(source)); - for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) { - const u64x2 v0 = source[shuffle[i]]; - state[i] = v0; - } - return; -#endif - - const u64x2 v0 = state[shuffle[0]]; - const u64x2 v1 = state[shuffle[1]]; - const u64x2 v2 = state[shuffle[2]]; - const u64x2 v3 = state[shuffle[3]]; - const u64x2 v4 = state[shuffle[4]]; - const u64x2 v5 = state[shuffle[5]]; - const u64x2 v6 = state[shuffle[6]]; - const u64x2 v7 = state[shuffle[7]]; - const u64x2 w0 = state[shuffle[8]]; - const u64x2 w1 = state[shuffle[9]]; - const u64x2 w2 = state[shuffle[10]]; - const u64x2 w3 = state[shuffle[11]]; - const u64x2 w4 = state[shuffle[12]]; - const u64x2 w5 = state[shuffle[13]]; - const u64x2 w6 = state[shuffle[14]]; - const u64x2 w7 = state[shuffle[15]]; - state[0] = v0; - state[1] = v1; - state[2] = v2; - state[3] = v3; - state[4] = v4; - state[5] = v5; - state[6] = v6; - state[7] = v7; - state[8] = w0; - state[9] = w1; - state[10] = w2; - state[11] = w3; - state[12] = w4; - state[13] = w5; - state[14] = w6; - state[15] = w7; -} - -// Feistel round function using two AES subrounds. Very similar to F() -// from Simpira v2, but with independent subround keys. Uses 17 AES rounds -// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in -// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel -// XORs are 'free' (included in the second AES instruction). -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const u64x2* FeistelRound( - u64x2* ABSL_RANDOM_INTERNAL_RESTRICT state, - const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) { - const Vector128 s0 = Vector128Load(state + branch); - const Vector128 s1 = Vector128Load(state + branch + 1); - const Vector128 f0 = AesRound(s0, Vector128Load(keys)); - keys++; - const Vector128 o1 = AesRound(f0, s1); - Vector128Store(o1, state + branch + 1); - - // Manually unroll this loop once. about 10% better than not unrolled. - const Vector128 s2 = Vector128Load(state + branch + 2); - const Vector128 s3 = Vector128Load(state + branch + 3); - const Vector128 f2 = AesRound(s2, Vector128Load(keys)); - keys++; - const Vector128 o3 = AesRound(f2, s3); - Vector128Store(o3, state + branch + 3); - } - return keys; -} - -// Cryptographic permutation based via type-2 Generalized Feistel Network. -// Indistinguishable from ideal by chosen-ciphertext adversaries using less than -// 2^64 queries if the round function is a PRF. This is similar to the b=8 case -// of Simpira v2, but more efficient than its generic construction for b=16. -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute( - u64x2* state, const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { - keys = FeistelRound(state, keys); - BlockShuffle(state); - } -} - -} // namespace - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -const void* RandenSlow::GetKeys() { - // Round keys for one AES per Feistel round and branch. - // The canonical implementation uses first digits of Pi. - return kRandenRoundKeys; -} - -void RandenSlow::Absorb(const void* seed_void, void* state_void) { - auto* state = - reinterpret_cast<uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void); - const auto* seed = - reinterpret_cast<const uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>( - seed_void); - - constexpr size_t kCapacityBlocks = - RandenTraits::kCapacityBytes / sizeof(uint64_t); - static_assert( - kCapacityBlocks * sizeof(uint64_t) == RandenTraits::kCapacityBytes, - "Not i*V"); - - for (size_t i = kCapacityBlocks; - i < RandenTraits::kStateBytes / sizeof(uint64_t); ++i) { - state[i] ^= seed[i - kCapacityBlocks]; - } -} - -void RandenSlow::Generate(const void* keys_void, void* state_void) { - static_assert(RandenTraits::kCapacityBytes == sizeof(u64x2), - "Capacity mismatch"); - - auto* state = reinterpret_cast<u64x2*>(state_void); - const auto* keys = reinterpret_cast<const u64x2*>(keys_void); - - const u64x2 prev_inner = state[0]; - - Permute(state, keys); - - // Ensure backtracking resistance. - state[0].data[0] ^= prev_inner.data[0]; - state[0].data[1] ^= prev_inner.data[1]; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/randen_slow.h b/third_party/abseil_cpp/absl/random/internal/randen_slow.h deleted file mode 100644 index b6f137eb94b1..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_slow.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_ -#define ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_ - -#include <cstddef> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// RANDen = RANDom generator or beetroots in Swiss German. -// RandenSlow implements the basic state manipulation methods for -// architectures lacking AES hardware acceleration intrinsics. -class RandenSlow { - public: - static void Generate(const void* keys, void* state_void); - static void Absorb(const void* seed_void, void* state_void); - static const void* GetKeys(); -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/randen_slow_test.cc b/third_party/abseil_cpp/absl/random/internal/randen_slow_test.cc deleted file mode 100644 index 4a5358370586..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_slow_test.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen_slow.h" - -#include <cstring> - -#include "gtest/gtest.h" -#include "absl/random/internal/randen_traits.h" - -namespace { - -using absl::random_internal::RandenSlow; -using absl::random_internal::RandenTraits; - -// Local state parameters. -constexpr size_t kSeedBytes = - RandenTraits::kStateBytes - RandenTraits::kCapacityBytes; -constexpr size_t kStateSizeT = RandenTraits::kStateBytes / sizeof(uint64_t); -constexpr size_t kSeedSizeT = kSeedBytes / sizeof(uint32_t); - -struct alignas(16) randen { - uint64_t state[kStateSizeT]; - uint32_t seed[kSeedSizeT]; -}; - -TEST(RandenSlowTest, Default) { - constexpr uint64_t kGolden[] = { - 0x6c6534090ee6d3ee, 0x044e2b9b9d5333c6, 0xc3c14f134e433977, - 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, 0xf0b780f545c72912, - 0x15dbb1d37696599f, 0x30ec63baff3c6d59, 0xb29f73606f7f20a6, - 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, 0x9cbf605e3fd9de8a, - 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, 0xf4b327fe0fc73c37, - 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, 0xd5af05dd3eff9556, - 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, 0x58d3575834956d42, - 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, 0x497cabf3431154fc, - 0x4e24370570029a8b, 0xd88b5749f090e5ea, 0xc651a582a970692f, - 0x78fcec2cbb6342f5, 0x463cb745612f55db, 0x352ee4ad1816afe3, - 0x026ff374c101da7e, 0x811ef0821c3de851, - }; - - alignas(16) randen d; - std::memset(d.state, 0, sizeof(d.state)); - RandenSlow::Generate(RandenSlow::GetKeys(), d.state); - - uint64_t* id = d.state; - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, *id++); - } -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/randen_test.cc b/third_party/abseil_cpp/absl/random/internal/randen_test.cc deleted file mode 100644 index c186fe0d686b..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_test.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/randen.h" - -#include <cstring> - -#include "gtest/gtest.h" -#include "absl/meta/type_traits.h" - -namespace { - -using absl::random_internal::Randen; - -// Local state parameters. -constexpr size_t kStateSizeT = Randen::kStateBytes / sizeof(uint64_t); - -TEST(RandenTest, CopyAndMove) { - static_assert(std::is_copy_constructible<Randen>::value, - "Randen must be copy constructible"); - - static_assert(absl::is_copy_assignable<Randen>::value, - "Randen must be copy assignable"); - - static_assert(std::is_move_constructible<Randen>::value, - "Randen must be move constructible"); - - static_assert(absl::is_move_assignable<Randen>::value, - "Randen must be move assignable"); -} - -TEST(RandenTest, Default) { - constexpr uint64_t kGolden[] = { - 0x6c6534090ee6d3ee, 0x044e2b9b9d5333c6, 0xc3c14f134e433977, - 0xdda9f47cd90410ee, 0x887bf3087fd8ca10, 0xf0b780f545c72912, - 0x15dbb1d37696599f, 0x30ec63baff3c6d59, 0xb29f73606f7f20a6, - 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e, 0x9cbf605e3fd9de8a, - 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5, 0xf4b327fe0fc73c37, - 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d, 0xd5af05dd3eff9556, - 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c, 0x58d3575834956d42, - 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3, 0x497cabf3431154fc, - 0x4e24370570029a8b, 0xd88b5749f090e5ea, 0xc651a582a970692f, - 0x78fcec2cbb6342f5, 0x463cb745612f55db, 0x352ee4ad1816afe3, - 0x026ff374c101da7e, 0x811ef0821c3de851, - }; - - alignas(16) uint64_t state[kStateSizeT]; - std::memset(state, 0, sizeof(state)); - - Randen r; - r.Generate(state); - - auto id = std::begin(state); - for (const auto& elem : kGolden) { - EXPECT_EQ(elem, *id++); - } -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/randen_traits.h b/third_party/abseil_cpp/absl/random/internal/randen_traits.h deleted file mode 100644 index 53caa936140a..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/randen_traits.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_ -#define ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_ - -// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate -// symbols from arbitrary system and other headers, since it may be built -// with different flags from other targets, using different levels of -// optimization, potentially introducing ODR violations. - -#include <cstddef> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// RANDen = RANDom generator or beetroots in Swiss German. -// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random -// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. -// -// High-level summary: -// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is -// a sponge-like random generator that requires a cryptographic permutation. -// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by -// achieving backtracking resistance with only one Permute() per buffer. -// -// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round -// Function" constructs up to 1024-bit permutations using an improved -// Generalized Feistel network with 2-round AES-128 functions. This Feistel -// block shuffle achieves diffusion faster and is less vulnerable to -// sliced-biclique attacks than the Type-2 cyclic shuffle. -// -// 3) "Improving the Generalized Feistel" and "New criterion for diffusion -// property" extends the same kind of improved Feistel block shuffle to 16 -// branches, which enables a 2048-bit permutation. -// -// Combine these three ideas and also change Simpira's subround keys from -// structured/low-entropy counters to digits of Pi (or other random source). - -// RandenTraits contains the basic algorithm traits, such as the size of the -// state, seed, sponge, etc. -struct RandenTraits { - // Size of the entire sponge / state for the randen PRNG. - static constexpr size_t kStateBytes = 256; // 2048-bit - - // Size of the 'inner' (inaccessible) part of the sponge. Larger values would - // require more frequent calls to RandenGenerate. - static constexpr size_t kCapacityBytes = 16; // 128-bit - - // Size of the default seed consumed by the sponge. - static constexpr size_t kSeedBytes = kStateBytes - kCapacityBytes; - - // Assuming 128-bit blocks, the number of blocks in the state. - // Largest size for which security proofs are known. - static constexpr size_t kFeistelBlocks = 16; - - // Ensures SPRP security and two full subblock diffusions. - // Must be > 4 * log2(kFeistelBlocks). - static constexpr size_t kFeistelRounds = 16 + 1; - - // Size of the key. A 128-bit key block is used for every-other - // feistel block (Type-2 generalized Feistel network) in each round. - static constexpr size_t kKeyBytes = 16 * kFeistelRounds * kFeistelBlocks / 2; -}; - -// Randen key arrays. In randen_round_keys.cc -extern const unsigned char kRandenRoundKeys[RandenTraits::kKeyBytes]; -extern const unsigned char kRandenRoundKeysBE[RandenTraits::kKeyBytes]; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/salted_seed_seq.h b/third_party/abseil_cpp/absl/random/internal/salted_seed_seq.h deleted file mode 100644 index 5953a090f80c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/salted_seed_seq.h +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_ -#define ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_ - -#include <cstdint> -#include <cstdlib> -#include <initializer_list> -#include <iterator> -#include <memory> -#include <type_traits> -#include <utility> - -#include "absl/container/inlined_vector.h" -#include "absl/meta/type_traits.h" -#include "absl/random/internal/seed_material.h" -#include "absl/types/optional.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// This class conforms to the C++ Standard "Seed Sequence" concept -// [rand.req.seedseq]. -// -// A `SaltedSeedSeq` is meant to wrap an existing seed sequence and modify -// generated sequence by mixing with extra entropy. This entropy may be -// build-dependent or process-dependent. The implementation may change to be -// have either or both kinds of entropy. If salt is not available sequence is -// not modified. -template <typename SSeq> -class SaltedSeedSeq { - public: - using inner_sequence_type = SSeq; - using result_type = typename SSeq::result_type; - - SaltedSeedSeq() : seq_(absl::make_unique<SSeq>()) {} - - template <typename Iterator> - SaltedSeedSeq(Iterator begin, Iterator end) - : seq_(absl::make_unique<SSeq>(begin, end)) {} - - template <typename T> - SaltedSeedSeq(std::initializer_list<T> il) - : SaltedSeedSeq(il.begin(), il.end()) {} - - SaltedSeedSeq(const SaltedSeedSeq&) = delete; - SaltedSeedSeq& operator=(const SaltedSeedSeq&) = delete; - - SaltedSeedSeq(SaltedSeedSeq&&) = default; - SaltedSeedSeq& operator=(SaltedSeedSeq&&) = default; - - template <typename RandomAccessIterator> - void generate(RandomAccessIterator begin, RandomAccessIterator end) { - // The common case is that generate is called with ContiguousIterators - // to uint arrays. Such contiguous memory regions may be optimized, - // which we detect here. - using tag = absl::conditional_t< - (std::is_pointer<RandomAccessIterator>::value && - std::is_same<absl::decay_t<decltype(*begin)>, uint32_t>::value), - ContiguousAndUint32Tag, DefaultTag>; - if (begin != end) { - generate_impl(begin, end, tag{}); - } - } - - template <typename OutIterator> - void param(OutIterator out) const { - seq_->param(out); - } - - size_t size() const { return seq_->size(); } - - private: - struct ContiguousAndUint32Tag {}; - struct DefaultTag {}; - - // Generate which requires the iterators are contiguous pointers to uint32_t. - void generate_impl(uint32_t* begin, uint32_t* end, ContiguousAndUint32Tag) { - generate_contiguous(absl::MakeSpan(begin, end)); - } - - // The uncommon case for generate is that it is called with iterators over - // some other buffer type which is assignable from a 32-bit value. In this - // case we allocate a temporary 32-bit buffer and then copy-assign back - // to the initial inputs. - template <typename RandomAccessIterator> - void generate_impl(RandomAccessIterator begin, RandomAccessIterator end, - DefaultTag) { - return generate_and_copy(std::distance(begin, end), begin); - } - - // Fills the initial seed buffer the underlying SSeq::generate() call, - // mixing in the salt material. - void generate_contiguous(absl::Span<uint32_t> buffer) { - seq_->generate(buffer.begin(), buffer.end()); - const uint32_t salt = absl::random_internal::GetSaltMaterial().value_or(0); - MixIntoSeedMaterial(absl::MakeConstSpan(&salt, 1), buffer); - } - - // Allocates a seed buffer of `n` elements, generates the seed, then - // copies the result into the `out` iterator. - template <typename Iterator> - void generate_and_copy(size_t n, Iterator out) { - // Allocate a temporary buffer, generate, and then copy. - absl::InlinedVector<uint32_t, 8> data(n, 0); - generate_contiguous(absl::MakeSpan(data.data(), data.size())); - std::copy(data.begin(), data.end(), out); - } - - // Because [rand.req.seedseq] is not required to be copy-constructible, - // copy-assignable nor movable, we wrap it with unique pointer to be able - // to move SaltedSeedSeq. - std::unique_ptr<SSeq> seq_; -}; - -// is_salted_seed_seq indicates whether the type is a SaltedSeedSeq. -template <typename T, typename = void> -struct is_salted_seed_seq : public std::false_type {}; - -template <typename T> -struct is_salted_seed_seq< - T, typename std::enable_if<std::is_same< - T, SaltedSeedSeq<typename T::inner_sequence_type>>::value>::type> - : public std::true_type {}; - -// MakeSaltedSeedSeq returns a salted variant of the seed sequence. -// When provided with an existing SaltedSeedSeq, returns the input parameter, -// otherwise constructs a new SaltedSeedSeq which embodies the original -// non-salted seed parameters. -template < - typename SSeq, // - typename EnableIf = absl::enable_if_t<is_salted_seed_seq<SSeq>::value>> -SSeq MakeSaltedSeedSeq(SSeq&& seq) { - return SSeq(std::forward<SSeq>(seq)); -} - -template < - typename SSeq, // - typename EnableIf = absl::enable_if_t<!is_salted_seed_seq<SSeq>::value>> -SaltedSeedSeq<typename std::decay<SSeq>::type> MakeSaltedSeedSeq(SSeq&& seq) { - using sseq_type = typename std::decay<SSeq>::type; - using result_type = typename sseq_type::result_type; - - absl::InlinedVector<result_type, 8> data; - seq.param(std::back_inserter(data)); - return SaltedSeedSeq<sseq_type>(data.begin(), data.end()); -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/salted_seed_seq_test.cc b/third_party/abseil_cpp/absl/random/internal/salted_seed_seq_test.cc deleted file mode 100644 index 0bf19a63ef8c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/salted_seed_seq_test.cc +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/salted_seed_seq.h" - -#include <iterator> -#include <random> -#include <utility> -#include <vector> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using absl::random_internal::GetSaltMaterial; -using absl::random_internal::MakeSaltedSeedSeq; -using absl::random_internal::SaltedSeedSeq; -using testing::Eq; -using testing::Pointwise; - -namespace { - -template <typename Sseq> -void ConformsToInterface() { - // Check that the SeedSequence can be default-constructed. - { Sseq default_constructed_seq; } - // Check that the SeedSequence can be constructed with two iterators. - { - uint32_t init_array[] = {1, 3, 5, 7, 9}; - Sseq iterator_constructed_seq(std::begin(init_array), std::end(init_array)); - } - // Check that the SeedSequence can be std::initializer_list-constructed. - { Sseq list_constructed_seq = {1, 3, 5, 7, 9, 11, 13}; } - // Check that param() and size() return state provided to constructor. - { - uint32_t init_array[] = {1, 2, 3, 4, 5}; - Sseq seq(std::begin(init_array), std::end(init_array)); - EXPECT_EQ(seq.size(), ABSL_ARRAYSIZE(init_array)); - - std::vector<uint32_t> state_vector; - seq.param(std::back_inserter(state_vector)); - - EXPECT_EQ(state_vector.size(), ABSL_ARRAYSIZE(init_array)); - for (int i = 0; i < state_vector.size(); i++) { - EXPECT_EQ(state_vector[i], i + 1); - } - } - // Check for presence of generate() method. - { - Sseq seq; - uint32_t seeds[5]; - - seq.generate(std::begin(seeds), std::end(seeds)); - } -} - -TEST(SaltedSeedSeq, CheckInterfaces) { - // Control case - ConformsToInterface<std::seed_seq>(); - - // Abseil classes - ConformsToInterface<SaltedSeedSeq<std::seed_seq>>(); -} - -TEST(SaltedSeedSeq, CheckConstructingFromOtherSequence) { - std::vector<uint32_t> seed_values(10, 1); - std::seed_seq seq(seed_values.begin(), seed_values.end()); - auto salted_seq = MakeSaltedSeedSeq(std::move(seq)); - - EXPECT_EQ(seq.size(), salted_seq.size()); - - std::vector<uint32_t> param_result; - seq.param(std::back_inserter(param_result)); - - EXPECT_EQ(seed_values, param_result); -} - -TEST(SaltedSeedSeq, SaltedSaltedSeedSeqIsNotDoubleSalted) { - uint32_t init[] = {1, 3, 5, 7, 9}; - - std::seed_seq seq(std::begin(init), std::end(init)); - - // The first salting. - SaltedSeedSeq<std::seed_seq> salted_seq = MakeSaltedSeedSeq(std::move(seq)); - uint32_t a[16]; - salted_seq.generate(std::begin(a), std::end(a)); - - // The second salting. - SaltedSeedSeq<std::seed_seq> salted_salted_seq = - MakeSaltedSeedSeq(std::move(salted_seq)); - uint32_t b[16]; - salted_salted_seq.generate(std::begin(b), std::end(b)); - - // ... both should be equal. - EXPECT_THAT(b, Pointwise(Eq(), a)) << "a[0] " << a[0]; -} - -TEST(SaltedSeedSeq, SeedMaterialIsSalted) { - const size_t kNumBlocks = 16; - - uint32_t seed_material[kNumBlocks]; - std::random_device urandom{"/dev/urandom"}; - for (uint32_t& seed : seed_material) { - seed = urandom(); - } - - std::seed_seq seq(std::begin(seed_material), std::end(seed_material)); - SaltedSeedSeq<std::seed_seq> salted_seq(std::begin(seed_material), - std::end(seed_material)); - - bool salt_is_available = GetSaltMaterial().has_value(); - - // If salt is available generated sequence should be different. - if (salt_is_available) { - uint32_t outputs[kNumBlocks]; - uint32_t salted_outputs[kNumBlocks]; - - seq.generate(std::begin(outputs), std::end(outputs)); - salted_seq.generate(std::begin(salted_outputs), std::end(salted_outputs)); - - EXPECT_THAT(outputs, Pointwise(testing::Ne(), salted_outputs)); - } -} - -TEST(SaltedSeedSeq, GenerateAcceptsDifferentTypes) { - const size_t kNumBlocks = 4; - - SaltedSeedSeq<std::seed_seq> seq({1, 2, 3}); - - uint32_t expected[kNumBlocks]; - seq.generate(std::begin(expected), std::end(expected)); - - // 32-bit outputs - { - unsigned long seed_material[kNumBlocks]; // NOLINT(runtime/int) - seq.generate(std::begin(seed_material), std::end(seed_material)); - EXPECT_THAT(seed_material, Pointwise(Eq(), expected)); - } - { - unsigned int seed_material[kNumBlocks]; // NOLINT(runtime/int) - seq.generate(std::begin(seed_material), std::end(seed_material)); - EXPECT_THAT(seed_material, Pointwise(Eq(), expected)); - } - - // 64-bit outputs. - { - uint64_t seed_material[kNumBlocks]; - seq.generate(std::begin(seed_material), std::end(seed_material)); - EXPECT_THAT(seed_material, Pointwise(Eq(), expected)); - } - { - int64_t seed_material[kNumBlocks]; - seq.generate(std::begin(seed_material), std::end(seed_material)); - EXPECT_THAT(seed_material, Pointwise(Eq(), expected)); - } -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/seed_material.cc b/third_party/abseil_cpp/absl/random/internal/seed_material.cc deleted file mode 100644 index 4d38a57419ec..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/seed_material.cc +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/seed_material.h" - -#include <fcntl.h> - -#ifndef _WIN32 -#include <unistd.h> -#else -#include <io.h> -#endif - -#include <algorithm> -#include <cerrno> -#include <cstdint> -#include <cstdlib> -#include <cstring> - -#include "absl/base/internal/raw_logging.h" -#include "absl/strings/ascii.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "absl/strings/strip.h" - -#if defined(__native_client__) - -#include <nacl/nacl_random.h> -#define ABSL_RANDOM_USE_NACL_SECURE_RANDOM 1 - -#elif defined(_WIN32) - -#include <windows.h> -#define ABSL_RANDOM_USE_BCRYPT 1 -#pragma comment(lib, "bcrypt.lib") - -#elif defined(__Fuchsia__) -#include <zircon/syscalls.h> - -#endif - -#if defined(ABSL_RANDOM_USE_BCRYPT) -#include <bcrypt.h> - -#ifndef BCRYPT_SUCCESS -#define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) -#endif -// Also link bcrypt; this can be done via linker options or: -// #pragma comment(lib, "bcrypt.lib") -#endif - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { - -// Read OS Entropy for random number seeds. -// TODO(absl-team): Possibly place a cap on how much entropy may be read at a -// time. - -#if defined(ABSL_RANDOM_USE_BCRYPT) - -// On Windows potentially use the BCRYPT CNG API to read available entropy. -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { - BCRYPT_ALG_HANDLE hProvider; - NTSTATUS ret; - ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RNG_ALGORITHM, - MS_PRIMITIVE_PROVIDER, 0); - if (!(BCRYPT_SUCCESS(ret))) { - ABSL_RAW_LOG(ERROR, "Failed to open crypto provider."); - return false; - } - ret = BCryptGenRandom( - hProvider, // provider - reinterpret_cast<UCHAR*>(values.data()), // buffer - static_cast<ULONG>(sizeof(uint32_t) * values.size()), // bytes - 0); // flags - BCryptCloseAlgorithmProvider(hProvider, 0); - return BCRYPT_SUCCESS(ret); -} - -#elif defined(ABSL_RANDOM_USE_NACL_SECURE_RANDOM) - -// On NaCL use nacl_secure_random to acquire bytes. -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { - auto buffer = reinterpret_cast<uint8_t*>(values.data()); - size_t buffer_size = sizeof(uint32_t) * values.size(); - - uint8_t* output_ptr = buffer; - while (buffer_size > 0) { - size_t nread = 0; - const int error = nacl_secure_random(output_ptr, buffer_size, &nread); - if (error != 0 || nread > buffer_size) { - ABSL_RAW_LOG(ERROR, "Failed to read secure_random seed data: %d", error); - return false; - } - output_ptr += nread; - buffer_size -= nread; - } - return true; -} - -#elif defined(__Fuchsia__) - -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { - auto buffer = reinterpret_cast<uint8_t*>(values.data()); - size_t buffer_size = sizeof(uint32_t) * values.size(); - zx_cprng_draw(buffer, buffer_size); - return true; -} - -#else - -// On *nix, read entropy from /dev/urandom. -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { - const char kEntropyFile[] = "/dev/urandom"; - - auto buffer = reinterpret_cast<uint8_t*>(values.data()); - size_t buffer_size = sizeof(uint32_t) * values.size(); - - int dev_urandom = open(kEntropyFile, O_RDONLY); - bool success = (-1 != dev_urandom); - if (!success) { - return false; - } - - while (success && buffer_size > 0) { - int bytes_read = read(dev_urandom, buffer, buffer_size); - int read_error = errno; - success = (bytes_read > 0); - if (success) { - buffer += bytes_read; - buffer_size -= bytes_read; - } else if (bytes_read == -1 && read_error == EINTR) { - success = true; // Need to try again. - } - } - close(dev_urandom); - return success; -} - -#endif - -} // namespace - -bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values) { - assert(values.data() != nullptr); - if (values.data() == nullptr) { - return false; - } - if (values.empty()) { - return true; - } - return ReadSeedMaterialFromOSEntropyImpl(values); -} - -void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence, - absl::Span<uint32_t> seed_material) { - // Algorithm is based on code available at - // https://gist.github.com/imneme/540829265469e673d045 - constexpr uint32_t kInitVal = 0x43b0d7e5; - constexpr uint32_t kHashMul = 0x931e8875; - constexpr uint32_t kMixMulL = 0xca01f9dd; - constexpr uint32_t kMixMulR = 0x4973f715; - constexpr uint32_t kShiftSize = sizeof(uint32_t) * 8 / 2; - - uint32_t hash_const = kInitVal; - auto hash = [&](uint32_t value) { - value ^= hash_const; - hash_const *= kHashMul; - value *= hash_const; - value ^= value >> kShiftSize; - return value; - }; - - auto mix = [&](uint32_t x, uint32_t y) { - uint32_t result = kMixMulL * x - kMixMulR * y; - result ^= result >> kShiftSize; - return result; - }; - - for (const auto& seq_val : sequence) { - for (auto& elem : seed_material) { - elem = mix(elem, hash(seq_val)); - } - } -} - -absl::optional<uint32_t> GetSaltMaterial() { - // Salt must be common for all generators within the same process so read it - // only once and store in static variable. - static const auto salt_material = []() -> absl::optional<uint32_t> { - uint32_t salt_value = 0; - - if (random_internal::ReadSeedMaterialFromOSEntropy( - MakeSpan(&salt_value, 1))) { - return salt_value; - } - - return absl::nullopt; - }(); - - return salt_material; -} - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/random/internal/seed_material.h b/third_party/abseil_cpp/absl/random/internal/seed_material.h deleted file mode 100644 index 4be10e925685..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/seed_material.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_ -#define ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_ - -#include <cassert> -#include <cstdint> -#include <cstdlib> -#include <string> -#include <vector> - -#include "absl/base/attributes.h" -#include "absl/random/internal/fast_uniform_bits.h" -#include "absl/types/optional.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Returns the number of 32-bit blocks needed to contain the given number of -// bits. -constexpr size_t SeedBitsToBlocks(size_t seed_size) { - return (seed_size + 31) / 32; -} - -// Amount of entropy (measured in bits) used to instantiate a Seed Sequence, -// with which to create a URBG. -constexpr size_t kEntropyBitsNeeded = 256; - -// Amount of entropy (measured in 32-bit blocks) used to instantiate a Seed -// Sequence, with which to create a URBG. -constexpr size_t kEntropyBlocksNeeded = - random_internal::SeedBitsToBlocks(kEntropyBitsNeeded); - -static_assert(kEntropyBlocksNeeded > 0, - "Entropy used to seed URBGs must be nonzero."); - -// Attempts to fill a span of uint32_t-values using an OS-provided source of -// true entropy (eg. /dev/urandom) into an array of uint32_t blocks of data. The -// resulting array may be used to initialize an instance of a class conforming -// to the C++ Standard "Seed Sequence" concept [rand.req.seedseq]. -// -// If values.data() == nullptr, the behavior is undefined. -ABSL_MUST_USE_RESULT -bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values); - -// Attempts to fill a span of uint32_t-values using variates generated by an -// existing instance of a class conforming to the C++ Standard "Uniform Random -// Bit Generator" concept [rand.req.urng]. The resulting data may be used to -// initialize an instance of a class conforming to the C++ Standard -// "Seed Sequence" concept [rand.req.seedseq]. -// -// If urbg == nullptr or values.data() == nullptr, the behavior is undefined. -template <typename URBG> -ABSL_MUST_USE_RESULT bool ReadSeedMaterialFromURBG( - URBG* urbg, absl::Span<uint32_t> values) { - random_internal::FastUniformBits<uint32_t> distr; - - assert(urbg != nullptr && values.data() != nullptr); - if (urbg == nullptr || values.data() == nullptr) { - return false; - } - - for (uint32_t& seed_value : values) { - seed_value = distr(*urbg); - } - return true; -} - -// Mixes given sequence of values with into given sequence of seed material. -// Time complexity of this function is O(sequence.size() * -// seed_material.size()). -// -// Algorithm is based on code available at -// https://gist.github.com/imneme/540829265469e673d045 -// by Melissa O'Neill. -void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence, - absl::Span<uint32_t> seed_material); - -// Returns salt value. -// -// Salt is obtained only once and stored in static variable. -// -// May return empty value if optaining the salt was not possible. -absl::optional<uint32_t> GetSaltMaterial(); - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/seed_material_test.cc b/third_party/abseil_cpp/absl/random/internal/seed_material_test.cc deleted file mode 100644 index 6db2820ec707..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/seed_material_test.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/seed_material.h" - -#include <bitset> -#include <cstdlib> -#include <cstring> -#include <random> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#ifdef __ANDROID__ -// Android assert messages only go to system log, so death tests cannot inspect -// the message for matching. -#define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - EXPECT_DEATH_IF_SUPPORTED(statement, ".*") -#else -#define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - EXPECT_DEATH_IF_SUPPORTED(statement, regex) -#endif - -namespace { - -using testing::Each; -using testing::ElementsAre; -using testing::Eq; -using testing::Ne; -using testing::Pointwise; - -TEST(SeedBitsToBlocks, VerifyCases) { - EXPECT_EQ(0, absl::random_internal::SeedBitsToBlocks(0)); - EXPECT_EQ(1, absl::random_internal::SeedBitsToBlocks(1)); - EXPECT_EQ(1, absl::random_internal::SeedBitsToBlocks(31)); - EXPECT_EQ(1, absl::random_internal::SeedBitsToBlocks(32)); - EXPECT_EQ(2, absl::random_internal::SeedBitsToBlocks(33)); - EXPECT_EQ(4, absl::random_internal::SeedBitsToBlocks(127)); - EXPECT_EQ(4, absl::random_internal::SeedBitsToBlocks(128)); - EXPECT_EQ(5, absl::random_internal::SeedBitsToBlocks(129)); -} - -TEST(ReadSeedMaterialFromOSEntropy, SuccessiveReadsAreDistinct) { - constexpr size_t kSeedMaterialSize = 64; - uint32_t seed_material_1[kSeedMaterialSize] = {}; - uint32_t seed_material_2[kSeedMaterialSize] = {}; - - EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromOSEntropy( - absl::Span<uint32_t>(seed_material_1, kSeedMaterialSize))); - EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromOSEntropy( - absl::Span<uint32_t>(seed_material_2, kSeedMaterialSize))); - - EXPECT_THAT(seed_material_1, Pointwise(Ne(), seed_material_2)); -} - -TEST(ReadSeedMaterialFromOSEntropy, ReadZeroBytesIsNoOp) { - uint32_t seed_material[32] = {}; - std::memset(seed_material, 0xAA, sizeof(seed_material)); - EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromOSEntropy( - absl::Span<uint32_t>(seed_material, 0))); - - EXPECT_THAT(seed_material, Each(Eq(0xAAAAAAAA))); -} - -TEST(ReadSeedMaterialFromOSEntropy, NullPtrVectorArgument) { -#ifdef NDEBUG - EXPECT_FALSE(absl::random_internal::ReadSeedMaterialFromOSEntropy( - absl::Span<uint32_t>(nullptr, 32))); -#else - bool result; - ABSL_EXPECT_DEATH_IF_SUPPORTED( - result = absl::random_internal::ReadSeedMaterialFromOSEntropy( - absl::Span<uint32_t>(nullptr, 32)), - "!= nullptr"); - (void)result; // suppress unused-variable warning -#endif -} - -TEST(ReadSeedMaterialFromURBG, SeedMaterialEqualsVariateSequence) { - // Two default-constructed instances of std::mt19937_64 are guaranteed to - // produce equal variate-sequences. - std::mt19937 urbg_1; - std::mt19937 urbg_2; - constexpr size_t kSeedMaterialSize = 1024; - uint32_t seed_material[kSeedMaterialSize] = {}; - - EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromURBG( - &urbg_1, absl::Span<uint32_t>(seed_material, kSeedMaterialSize))); - for (uint32_t seed : seed_material) { - EXPECT_EQ(seed, urbg_2()); - } -} - -TEST(ReadSeedMaterialFromURBG, ReadZeroBytesIsNoOp) { - std::mt19937_64 urbg; - uint32_t seed_material[32]; - std::memset(seed_material, 0xAA, sizeof(seed_material)); - EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromURBG( - &urbg, absl::Span<uint32_t>(seed_material, 0))); - - EXPECT_THAT(seed_material, Each(Eq(0xAAAAAAAA))); -} - -TEST(ReadSeedMaterialFromURBG, NullUrbgArgument) { - constexpr size_t kSeedMaterialSize = 32; - uint32_t seed_material[kSeedMaterialSize]; -#ifdef NDEBUG - EXPECT_FALSE(absl::random_internal::ReadSeedMaterialFromURBG<std::mt19937_64>( - nullptr, absl::Span<uint32_t>(seed_material, kSeedMaterialSize))); -#else - bool result; - ABSL_EXPECT_DEATH_IF_SUPPORTED( - result = absl::random_internal::ReadSeedMaterialFromURBG<std::mt19937_64>( - nullptr, absl::Span<uint32_t>(seed_material, kSeedMaterialSize)), - "!= nullptr"); - (void)result; // suppress unused-variable warning -#endif -} - -TEST(ReadSeedMaterialFromURBG, NullPtrVectorArgument) { - std::mt19937_64 urbg; -#ifdef NDEBUG - EXPECT_FALSE(absl::random_internal::ReadSeedMaterialFromURBG( - &urbg, absl::Span<uint32_t>(nullptr, 32))); -#else - bool result; - ABSL_EXPECT_DEATH_IF_SUPPORTED( - result = absl::random_internal::ReadSeedMaterialFromURBG( - &urbg, absl::Span<uint32_t>(nullptr, 32)), - "!= nullptr"); - (void)result; // suppress unused-variable warning -#endif -} - -// The avalanche effect is a desirable cryptographic property of hashes in which -// changing a single bit in the input causes each bit of the output to be -// changed with probability near 50%. -// -// https://en.wikipedia.org/wiki/Avalanche_effect - -TEST(MixSequenceIntoSeedMaterial, AvalancheEffectTestOneBitLong) { - std::vector<uint32_t> seed_material = {1, 2, 3, 4, 5, 6, 7, 8}; - - // For every 32-bit number with exactly one bit set, verify the avalanche - // effect holds. In order to reduce flakiness of tests, accept values - // anywhere in the range of 30%-70%. - for (uint32_t v = 1; v != 0; v <<= 1) { - std::vector<uint32_t> seed_material_copy = seed_material; - absl::random_internal::MixIntoSeedMaterial( - absl::Span<uint32_t>(&v, 1), - absl::Span<uint32_t>(seed_material_copy.data(), - seed_material_copy.size())); - - uint32_t changed_bits = 0; - for (size_t i = 0; i < seed_material.size(); i++) { - std::bitset<sizeof(uint32_t) * 8> bitset(seed_material[i] ^ - seed_material_copy[i]); - changed_bits += bitset.count(); - } - - EXPECT_LE(changed_bits, 0.7 * sizeof(uint32_t) * 8 * seed_material.size()); - EXPECT_GE(changed_bits, 0.3 * sizeof(uint32_t) * 8 * seed_material.size()); - } -} - -TEST(MixSequenceIntoSeedMaterial, AvalancheEffectTestOneBitShort) { - std::vector<uint32_t> seed_material = {1}; - - // For every 32-bit number with exactly one bit set, verify the avalanche - // effect holds. In order to reduce flakiness of tests, accept values - // anywhere in the range of 30%-70%. - for (uint32_t v = 1; v != 0; v <<= 1) { - std::vector<uint32_t> seed_material_copy = seed_material; - absl::random_internal::MixIntoSeedMaterial( - absl::Span<uint32_t>(&v, 1), - absl::Span<uint32_t>(seed_material_copy.data(), - seed_material_copy.size())); - - uint32_t changed_bits = 0; - for (size_t i = 0; i < seed_material.size(); i++) { - std::bitset<sizeof(uint32_t) * 8> bitset(seed_material[i] ^ - seed_material_copy[i]); - changed_bits += bitset.count(); - } - - EXPECT_LE(changed_bits, 0.7 * sizeof(uint32_t) * 8 * seed_material.size()); - EXPECT_GE(changed_bits, 0.3 * sizeof(uint32_t) * 8 * seed_material.size()); - } -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/sequence_urbg.h b/third_party/abseil_cpp/absl/random/internal/sequence_urbg.h deleted file mode 100644 index bc96a12cd29c..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/sequence_urbg.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_ -#define ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_ - -#include <cstdint> -#include <cstring> -#include <limits> -#include <type_traits> -#include <vector> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// `sequence_urbg` is a simple random number generator which meets the -// requirements of [rand.req.urbg], and is solely for testing absl -// distributions. -class sequence_urbg { - public: - using result_type = uint64_t; - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - sequence_urbg(std::initializer_list<result_type> data) : i_(0), data_(data) {} - void reset() { i_ = 0; } - - result_type operator()() { return data_[i_++ % data_.size()]; } - - size_t invocations() const { return i_; } - - private: - size_t i_; - std::vector<result_type> data_; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/traits.h b/third_party/abseil_cpp/absl/random/internal/traits.h deleted file mode 100644 index 75772bd9abb4..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/traits.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_TRAITS_H_ -#define ABSL_RANDOM_INTERNAL_TRAITS_H_ - -#include <cstdint> -#include <limits> -#include <type_traits> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// random_internal::is_widening_convertible<A, B> -// -// Returns whether a type A is widening-convertible to a type B. -// -// A is widening-convertible to B means: -// A a = <any number>; -// B b = a; -// A c = b; -// EXPECT_EQ(a, c); -template <typename A, typename B> -class is_widening_convertible { - // As long as there are enough bits in the exact part of a number: - // - unsigned can fit in float, signed, unsigned - // - signed can fit in float, signed - // - float can fit in float - // So we define rank to be: - // - rank(float) -> 2 - // - rank(signed) -> 1 - // - rank(unsigned) -> 0 - template <class T> - static constexpr int rank() { - return !std::numeric_limits<T>::is_integer + - std::numeric_limits<T>::is_signed; - } - - public: - // If an arithmetic-type B can represent at least as many digits as a type A, - // and B belongs to a rank no lower than A, then A can be safely represented - // by B through a widening-conversion. - static constexpr bool value = - std::numeric_limits<A>::digits <= std::numeric_limits<B>::digits && - rank<A>() <= rank<B>(); -}; - -// unsigned_bits<N>::type returns the unsigned int type with the indicated -// number of bits. -template <size_t N> -struct unsigned_bits; - -template <> -struct unsigned_bits<8> { - using type = uint8_t; -}; -template <> -struct unsigned_bits<16> { - using type = uint16_t; -}; -template <> -struct unsigned_bits<32> { - using type = uint32_t; -}; -template <> -struct unsigned_bits<64> { - using type = uint64_t; -}; - -#ifdef ABSL_HAVE_INTRINSIC_INT128 -template <> -struct unsigned_bits<128> { - using type = __uint128_t; -}; -#endif - -template <typename IntType> -struct make_unsigned_bits { - using type = typename unsigned_bits<std::numeric_limits< - typename std::make_unsigned<IntType>::type>::digits>::type; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_TRAITS_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/traits_test.cc b/third_party/abseil_cpp/absl/random/internal/traits_test.cc deleted file mode 100644 index a844887d3e44..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/traits_test.cc +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/traits.h" - -#include <cstdint> -#include <type_traits> - -#include "gtest/gtest.h" - -namespace { - -using absl::random_internal::is_widening_convertible; - -// CheckWideningConvertsToSelf<T1, T2, ...>() -// -// For each type T, checks: -// - T IS widening-convertible to itself. -// -template <typename T> -void CheckWideningConvertsToSelf() { - static_assert(is_widening_convertible<T, T>::value, - "Type is not convertible to self!"); -} - -template <typename T, typename Next, typename... Args> -void CheckWideningConvertsToSelf() { - CheckWideningConvertsToSelf<T>(); - CheckWideningConvertsToSelf<Next, Args...>(); -} - -// CheckNotWideningConvertibleWithSigned<T1, T2, ...>() -// -// For each unsigned-type T, checks that: -// - T is NOT widening-convertible to Signed(T) -// - Signed(T) is NOT widening-convertible to T -// -template <typename T> -void CheckNotWideningConvertibleWithSigned() { - using signed_t = typename std::make_signed<T>::type; - - static_assert(!is_widening_convertible<T, signed_t>::value, - "Unsigned type is convertible to same-sized signed-type!"); - static_assert(!is_widening_convertible<signed_t, T>::value, - "Signed type is convertible to same-sized unsigned-type!"); -} - -template <typename T, typename Next, typename... Args> -void CheckNotWideningConvertibleWithSigned() { - CheckNotWideningConvertibleWithSigned<T>(); - CheckWideningConvertsToSelf<Next, Args...>(); -} - -// CheckWideningConvertsToLargerType<T1, T2, ...>() -// -// For each successive unsigned-types {Ti, Ti+1}, checks that: -// - Ti IS widening-convertible to Ti+1 -// - Ti IS widening-convertible to Signed(Ti+1) -// - Signed(Ti) is NOT widening-convertible to Ti -// - Signed(Ti) IS widening-convertible to Ti+1 -template <typename T, typename Higher> -void CheckWideningConvertsToLargerTypes() { - using signed_t = typename std::make_signed<T>::type; - using higher_t = Higher; - using signed_higher_t = typename std::make_signed<Higher>::type; - - static_assert(is_widening_convertible<T, higher_t>::value, - "Type not embeddable into larger type!"); - static_assert(is_widening_convertible<T, signed_higher_t>::value, - "Type not embeddable into larger signed type!"); - static_assert(!is_widening_convertible<signed_t, higher_t>::value, - "Signed type is embeddable into larger unsigned type!"); - static_assert(is_widening_convertible<signed_t, signed_higher_t>::value, - "Signed type not embeddable into larger signed type!"); -} - -template <typename T, typename Higher, typename Next, typename... Args> -void CheckWideningConvertsToLargerTypes() { - CheckWideningConvertsToLargerTypes<T, Higher>(); - CheckWideningConvertsToLargerTypes<Higher, Next, Args...>(); -} - -// CheckWideningConvertsTo<T, U, [expect]> -// -// Checks that T DOES widening-convert to U. -// If "expect" is false, then asserts that T does NOT widening-convert to U. -template <typename T, typename U, bool expect = true> -void CheckWideningConvertsTo() { - static_assert(is_widening_convertible<T, U>::value == expect, - "Unexpected result for is_widening_convertible<T, U>!"); -} - -TEST(TraitsTest, IsWideningConvertibleTest) { - constexpr bool kInvalid = false; - - CheckWideningConvertsToSelf< - uint8_t, uint16_t, uint32_t, uint64_t, - int8_t, int16_t, int32_t, int64_t, - float, double>(); - CheckNotWideningConvertibleWithSigned< - uint8_t, uint16_t, uint32_t, uint64_t>(); - CheckWideningConvertsToLargerTypes< - uint8_t, uint16_t, uint32_t, uint64_t>(); - - CheckWideningConvertsTo<float, double>(); - CheckWideningConvertsTo<uint16_t, float>(); - CheckWideningConvertsTo<uint32_t, double>(); - CheckWideningConvertsTo<uint64_t, double, kInvalid>(); - CheckWideningConvertsTo<double, float, kInvalid>(); - - CheckWideningConvertsTo<bool, int>(); - CheckWideningConvertsTo<bool, float>(); -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/uniform_helper.h b/third_party/abseil_cpp/absl/random/internal/uniform_helper.h deleted file mode 100644 index 1243bc1c62ab..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/uniform_helper.h +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#ifndef ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_ -#define ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_ - -#include <cmath> -#include <limits> -#include <type_traits> - -#include "absl/base/config.h" -#include "absl/meta/type_traits.h" -#include "absl/random/internal/traits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -template <typename IntType> -class uniform_int_distribution; - -template <typename RealType> -class uniform_real_distribution; - -// Interval tag types which specify whether the interval is open or closed -// on either boundary. - -namespace random_internal { -template <typename T> -struct TagTypeCompare {}; - -template <typename T> -constexpr bool operator==(TagTypeCompare<T>, TagTypeCompare<T>) { - // Tags are mono-states. They always compare equal. - return true; -} -template <typename T> -constexpr bool operator!=(TagTypeCompare<T>, TagTypeCompare<T>) { - return false; -} - -} // namespace random_internal - -struct IntervalClosedClosedTag - : public random_internal::TagTypeCompare<IntervalClosedClosedTag> {}; -struct IntervalClosedOpenTag - : public random_internal::TagTypeCompare<IntervalClosedOpenTag> {}; -struct IntervalOpenClosedTag - : public random_internal::TagTypeCompare<IntervalOpenClosedTag> {}; -struct IntervalOpenOpenTag - : public random_internal::TagTypeCompare<IntervalOpenOpenTag> {}; - -namespace random_internal { - -// In the absence of an explicitly provided return-type, the template -// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on -// the data-types of the endpoint-arguments {A lo, B hi}. -// -// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the -// return-type, if one type can be implicitly converted into the other, in a -// lossless way. The template "is_widening_convertible" implements the -// compile-time logic for deciding if such a conversion is possible. -// -// If no such conversion between {A, B} exists, then the overload for -// absl::Uniform() will be discarded, and the call will be ill-formed. -// Return-type for absl::Uniform() when the return-type is inferred. -template <typename A, typename B> -using uniform_inferred_return_t = - absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>, - is_widening_convertible<B, A>>::value, - typename std::conditional< - is_widening_convertible<A, B>::value, B, A>::type>; - -// The functions -// uniform_lower_bound(tag, a, b) -// and -// uniform_upper_bound(tag, a, b) -// are used as implementation-details for absl::Uniform(). -// -// Conceptually, -// [a, b] == [uniform_lower_bound(IntervalClosedClosed, a, b), -// uniform_upper_bound(IntervalClosedClosed, a, b)] -// (a, b) == [uniform_lower_bound(IntervalOpenOpen, a, b), -// uniform_upper_bound(IntervalOpenOpen, a, b)] -// [a, b) == [uniform_lower_bound(IntervalClosedOpen, a, b), -// uniform_upper_bound(IntervalClosedOpen, a, b)] -// (a, b] == [uniform_lower_bound(IntervalOpenClosed, a, b), -// uniform_upper_bound(IntervalOpenClosed, a, b)] -// -template <typename IntType, typename Tag> -typename absl::enable_if_t< - absl::conjunction< - std::is_integral<IntType>, - absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>, - std::is_same<Tag, IntervalOpenOpenTag>>>::value, - IntType> -uniform_lower_bound(Tag, IntType a, IntType) { - return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a; -} - -template <typename FloatType, typename Tag> -typename absl::enable_if_t< - absl::conjunction< - std::is_floating_point<FloatType>, - absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>, - std::is_same<Tag, IntervalOpenOpenTag>>>::value, - FloatType> -uniform_lower_bound(Tag, FloatType a, FloatType b) { - return std::nextafter(a, b); -} - -template <typename NumType, typename Tag> -typename absl::enable_if_t< - absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>, - std::is_same<Tag, IntervalClosedOpenTag>>::value, - NumType> -uniform_lower_bound(Tag, NumType a, NumType) { - return a; -} - -template <typename IntType, typename Tag> -typename absl::enable_if_t< - absl::conjunction< - std::is_integral<IntType>, - absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>, - std::is_same<Tag, IntervalOpenOpenTag>>>::value, - IntType> -uniform_upper_bound(Tag, IntType, IntType b) { - return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b; -} - -template <typename FloatType, typename Tag> -typename absl::enable_if_t< - absl::conjunction< - std::is_floating_point<FloatType>, - absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>, - std::is_same<Tag, IntervalOpenOpenTag>>>::value, - FloatType> -uniform_upper_bound(Tag, FloatType, FloatType b) { - return b; -} - -template <typename IntType, typename Tag> -typename absl::enable_if_t< - absl::conjunction< - std::is_integral<IntType>, - absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>, - std::is_same<Tag, IntervalOpenClosedTag>>>::value, - IntType> -uniform_upper_bound(Tag, IntType, IntType b) { - return b; -} - -template <typename FloatType, typename Tag> -typename absl::enable_if_t< - absl::conjunction< - std::is_floating_point<FloatType>, - absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>, - std::is_same<Tag, IntervalOpenClosedTag>>>::value, - FloatType> -uniform_upper_bound(Tag, FloatType, FloatType b) { - return std::nextafter(b, (std::numeric_limits<FloatType>::max)()); -} - -// Returns whether the bounds are valid for the underlying distribution. -// Inputs must have already been resolved via uniform_*_bound calls. -// -// The c++ standard constraints in [rand.dist.uni.int] are listed as: -// requires: lo <= hi. -// -// In the uniform_int_distrubtion, {lo, hi} are closed, closed. Thus: -// [0, 0] is legal. -// [0, 0) is not legal, but [0, 1) is, which translates to [0, 0]. -// (0, 1) is not legal, but (0, 2) is, which translates to [1, 1]. -// (0, 0] is not legal, but (0, 1] is, which translates to [1, 1]. -// -// The c++ standard constraints in [rand.dist.uni.real] are listed as: -// requires: lo <= hi. -// requires: (hi - lo) <= numeric_limits<T>::max() -// -// In the uniform_real_distribution, {lo, hi} are closed, open, Thus: -// [0, 0] is legal, which is [0, 0+epsilon). -// [0, 0) is legal. -// (0, 0) is not legal, but (0-epsilon, 0+epsilon) is. -// (0, 0] is not legal, but (0, 0+epsilon] is. -// -template <typename FloatType> -absl::enable_if_t<std::is_floating_point<FloatType>::value, bool> -is_uniform_range_valid(FloatType a, FloatType b) { - return a <= b && std::isfinite(b - a); -} - -template <typename IntType> -absl::enable_if_t<std::is_integral<IntType>::value, bool> -is_uniform_range_valid(IntType a, IntType b) { - return a <= b; -} - -// UniformDistribution selects either absl::uniform_int_distribution -// or absl::uniform_real_distribution depending on the NumType parameter. -template <typename NumType> -using UniformDistribution = - typename std::conditional<std::is_integral<NumType>::value, - absl::uniform_int_distribution<NumType>, - absl::uniform_real_distribution<NumType>>::type; - -// UniformDistributionWrapper is used as the underlying distribution type -// by the absl::Uniform template function. It selects the proper Abseil -// uniform distribution and provides constructor overloads that match the -// expected parameter order as well as adjusting distribtuion bounds based -// on the tag. -template <typename NumType> -struct UniformDistributionWrapper : public UniformDistribution<NumType> { - template <typename TagType> - explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi) - : UniformDistribution<NumType>( - uniform_lower_bound<NumType>(TagType{}, lo, hi), - uniform_upper_bound<NumType>(TagType{}, lo, hi)) {} - - explicit UniformDistributionWrapper(NumType lo, NumType hi) - : UniformDistribution<NumType>( - uniform_lower_bound<NumType>(IntervalClosedOpenTag(), lo, hi), - uniform_upper_bound<NumType>(IntervalClosedOpenTag(), lo, hi)) {} - - explicit UniformDistributionWrapper() - : UniformDistribution<NumType>(std::numeric_limits<NumType>::lowest(), - (std::numeric_limits<NumType>::max)()) {} -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/uniform_helper_test.cc b/third_party/abseil_cpp/absl/random/internal/uniform_helper_test.cc deleted file mode 100644 index 173c49b0b7f8..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/uniform_helper_test.cc +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/uniform_helper.h" - -#include <cmath> -#include <cstdint> -#include <random> - -#include "gtest/gtest.h" - -namespace { - -using absl::IntervalClosedClosedTag; -using absl::IntervalClosedOpenTag; -using absl::IntervalOpenClosedTag; -using absl::IntervalOpenOpenTag; -using absl::random_internal::uniform_inferred_return_t; -using absl::random_internal::uniform_lower_bound; -using absl::random_internal::uniform_upper_bound; - -class UniformHelperTest : public testing::Test {}; - -TEST_F(UniformHelperTest, UniformBoundFunctionsGeneral) { - constexpr IntervalClosedClosedTag IntervalClosedClosed; - constexpr IntervalClosedOpenTag IntervalClosedOpen; - constexpr IntervalOpenClosedTag IntervalOpenClosed; - constexpr IntervalOpenOpenTag IntervalOpenOpen; - - // absl::uniform_int_distribution natively assumes IntervalClosedClosed - // absl::uniform_real_distribution natively assumes IntervalClosedOpen - - EXPECT_EQ(uniform_lower_bound(IntervalOpenClosed, 0, 100), 1); - EXPECT_EQ(uniform_lower_bound(IntervalOpenOpen, 0, 100), 1); - EXPECT_GT(uniform_lower_bound<float>(IntervalOpenClosed, 0, 1.0), 0); - EXPECT_GT(uniform_lower_bound<float>(IntervalOpenOpen, 0, 1.0), 0); - EXPECT_GT(uniform_lower_bound<double>(IntervalOpenClosed, 0, 1.0), 0); - EXPECT_GT(uniform_lower_bound<double>(IntervalOpenOpen, 0, 1.0), 0); - - EXPECT_EQ(uniform_lower_bound(IntervalClosedClosed, 0, 100), 0); - EXPECT_EQ(uniform_lower_bound(IntervalClosedOpen, 0, 100), 0); - EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedClosed, 0, 1.0), 0); - EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedOpen, 0, 1.0), 0); - EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedClosed, 0, 1.0), 0); - EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedOpen, 0, 1.0), 0); - - EXPECT_EQ(uniform_upper_bound(IntervalOpenOpen, 0, 100), 99); - EXPECT_EQ(uniform_upper_bound(IntervalClosedOpen, 0, 100), 99); - EXPECT_EQ(uniform_upper_bound<float>(IntervalOpenOpen, 0, 1.0), 1.0); - EXPECT_EQ(uniform_upper_bound<float>(IntervalClosedOpen, 0, 1.0), 1.0); - EXPECT_EQ(uniform_upper_bound<double>(IntervalOpenOpen, 0, 1.0), 1.0); - EXPECT_EQ(uniform_upper_bound<double>(IntervalClosedOpen, 0, 1.0), 1.0); - - EXPECT_EQ(uniform_upper_bound(IntervalOpenClosed, 0, 100), 100); - EXPECT_EQ(uniform_upper_bound(IntervalClosedClosed, 0, 100), 100); - EXPECT_GT(uniform_upper_bound<float>(IntervalOpenClosed, 0, 1.0), 1.0); - EXPECT_GT(uniform_upper_bound<float>(IntervalClosedClosed, 0, 1.0), 1.0); - EXPECT_GT(uniform_upper_bound<double>(IntervalOpenClosed, 0, 1.0), 1.0); - EXPECT_GT(uniform_upper_bound<double>(IntervalClosedClosed, 0, 1.0), 1.0); - - // Negative value tests - EXPECT_EQ(uniform_lower_bound(IntervalOpenClosed, -100, -1), -99); - EXPECT_EQ(uniform_lower_bound(IntervalOpenOpen, -100, -1), -99); - EXPECT_GT(uniform_lower_bound<float>(IntervalOpenClosed, -2.0, -1.0), -2.0); - EXPECT_GT(uniform_lower_bound<float>(IntervalOpenOpen, -2.0, -1.0), -2.0); - EXPECT_GT(uniform_lower_bound<double>(IntervalOpenClosed, -2.0, -1.0), -2.0); - EXPECT_GT(uniform_lower_bound<double>(IntervalOpenOpen, -2.0, -1.0), -2.0); - - EXPECT_EQ(uniform_lower_bound(IntervalClosedClosed, -100, -1), -100); - EXPECT_EQ(uniform_lower_bound(IntervalClosedOpen, -100, -1), -100); - EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedClosed, -2.0, -1.0), -2.0); - EXPECT_EQ(uniform_lower_bound<float>(IntervalClosedOpen, -2.0, -1.0), -2.0); - EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedClosed, -2.0, -1.0), - -2.0); - EXPECT_EQ(uniform_lower_bound<double>(IntervalClosedOpen, -2.0, -1.0), -2.0); - - EXPECT_EQ(uniform_upper_bound(IntervalOpenOpen, -100, -1), -2); - EXPECT_EQ(uniform_upper_bound(IntervalClosedOpen, -100, -1), -2); - EXPECT_EQ(uniform_upper_bound<float>(IntervalOpenOpen, -2.0, -1.0), -1.0); - EXPECT_EQ(uniform_upper_bound<float>(IntervalClosedOpen, -2.0, -1.0), -1.0); - EXPECT_EQ(uniform_upper_bound<double>(IntervalOpenOpen, -2.0, -1.0), -1.0); - EXPECT_EQ(uniform_upper_bound<double>(IntervalClosedOpen, -2.0, -1.0), -1.0); - - EXPECT_EQ(uniform_upper_bound(IntervalOpenClosed, -100, -1), -1); - EXPECT_EQ(uniform_upper_bound(IntervalClosedClosed, -100, -1), -1); - EXPECT_GT(uniform_upper_bound<float>(IntervalOpenClosed, -2.0, -1.0), -1.0); - EXPECT_GT(uniform_upper_bound<float>(IntervalClosedClosed, -2.0, -1.0), -1.0); - EXPECT_GT(uniform_upper_bound<double>(IntervalOpenClosed, -2.0, -1.0), -1.0); - EXPECT_GT(uniform_upper_bound<double>(IntervalClosedClosed, -2.0, -1.0), - -1.0); - - EXPECT_GT(uniform_lower_bound(IntervalOpenClosed, 1.0, 2.0), 1.0); - EXPECT_LT(uniform_lower_bound(IntervalOpenClosed, 1.0, +0.0), 1.0); - EXPECT_LT(uniform_lower_bound(IntervalOpenClosed, 1.0, -0.0), 1.0); - EXPECT_LT(uniform_lower_bound(IntervalOpenClosed, 1.0, -1.0), 1.0); -} - -TEST_F(UniformHelperTest, UniformBoundFunctionsIntBounds) { - // Verifies the saturating nature of uniform_lower_bound and - // uniform_upper_bound - constexpr IntervalOpenOpenTag IntervalOpenOpen; - - // uint max. - constexpr auto m = (std::numeric_limits<uint64_t>::max)(); - - EXPECT_EQ(1, uniform_lower_bound(IntervalOpenOpen, 0u, 0u)); - EXPECT_EQ(m, uniform_lower_bound(IntervalOpenOpen, m, m)); - EXPECT_EQ(m, uniform_lower_bound(IntervalOpenOpen, m - 1, m - 1)); - EXPECT_EQ(0, uniform_upper_bound(IntervalOpenOpen, 0u, 0u)); - EXPECT_EQ(m - 1, uniform_upper_bound(IntervalOpenOpen, m, m)); - - // int min/max - constexpr auto l = (std::numeric_limits<int64_t>::min)(); - constexpr auto r = (std::numeric_limits<int64_t>::max)(); - EXPECT_EQ(1, uniform_lower_bound(IntervalOpenOpen, 0, 0)); - EXPECT_EQ(l + 1, uniform_lower_bound(IntervalOpenOpen, l, l)); - EXPECT_EQ(r, uniform_lower_bound(IntervalOpenOpen, r - 1, r - 1)); - EXPECT_EQ(r, uniform_lower_bound(IntervalOpenOpen, r, r)); - EXPECT_EQ(-1, uniform_upper_bound(IntervalOpenOpen, 0, 0)); - EXPECT_EQ(l, uniform_upper_bound(IntervalOpenOpen, l, l)); - EXPECT_EQ(r - 1, uniform_upper_bound(IntervalOpenOpen, r, r)); -} - -TEST_F(UniformHelperTest, UniformBoundFunctionsRealBounds) { - // absl::uniform_real_distribution natively assumes IntervalClosedOpen; - // use the inverse here so each bound has to change. - constexpr IntervalOpenClosedTag IntervalOpenClosed; - - // Edge cases: the next value toward itself is itself. - EXPECT_EQ(1.0, uniform_lower_bound(IntervalOpenClosed, 1.0, 1.0)); - EXPECT_EQ(1.0f, uniform_lower_bound(IntervalOpenClosed, 1.0f, 1.0f)); - - // rightmost and leftmost finite values. - constexpr auto r = (std::numeric_limits<double>::max)(); - const auto re = std::nexttoward(r, 0.0); - constexpr auto l = -r; - const auto le = std::nexttoward(l, 0.0); - - EXPECT_EQ(l, uniform_lower_bound(IntervalOpenClosed, l, l)); // (l,l) - EXPECT_EQ(r, uniform_lower_bound(IntervalOpenClosed, r, r)); // (r,r) - EXPECT_EQ(le, uniform_lower_bound(IntervalOpenClosed, l, r)); // (l,r) - EXPECT_EQ(le, uniform_lower_bound(IntervalOpenClosed, l, 0.0)); // (l, 0) - EXPECT_EQ(le, uniform_lower_bound(IntervalOpenClosed, l, le)); // (l, le) - EXPECT_EQ(r, uniform_lower_bound(IntervalOpenClosed, re, r)); // (re, r) - - EXPECT_EQ(le, uniform_upper_bound(IntervalOpenClosed, l, l)); // (l,l) - EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, r, r)); // (r,r) - EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, l, r)); // (l,r) - EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, l, re)); // (l,re) - EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, 0.0, r)); // (0, r) - EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, re, r)); // (re, r) - EXPECT_EQ(r, uniform_upper_bound(IntervalOpenClosed, le, re)); // (le, re) - - const double e = std::nextafter(1.0, 2.0); // 1 + epsilon - const double f = std::nextafter(1.0, 0.0); // 1 - epsilon - - // (1.0, 1.0 + epsilon) - EXPECT_EQ(e, uniform_lower_bound(IntervalOpenClosed, 1.0, e)); - EXPECT_EQ(std::nextafter(e, 2.0), - uniform_upper_bound(IntervalOpenClosed, 1.0, e)); - - // (1.0-epsilon, 1.0) - EXPECT_EQ(1.0, uniform_lower_bound(IntervalOpenClosed, f, 1.0)); - EXPECT_EQ(e, uniform_upper_bound(IntervalOpenClosed, f, 1.0)); - - // denorm cases. - const double g = std::numeric_limits<double>::denorm_min(); - const double h = std::nextafter(g, 1.0); - - // (0, denorm_min) - EXPECT_EQ(g, uniform_lower_bound(IntervalOpenClosed, 0.0, g)); - EXPECT_EQ(h, uniform_upper_bound(IntervalOpenClosed, 0.0, g)); - - // (denorm_min, 1.0) - EXPECT_EQ(h, uniform_lower_bound(IntervalOpenClosed, g, 1.0)); - EXPECT_EQ(e, uniform_upper_bound(IntervalOpenClosed, g, 1.0)); - - // Edge cases: invalid bounds. - EXPECT_EQ(f, uniform_lower_bound(IntervalOpenClosed, 1.0, -1.0)); -} - -struct Invalid {}; - -template <typename A, typename B> -auto InferredUniformReturnT(int) -> uniform_inferred_return_t<A, B>; - -template <typename, typename> -Invalid InferredUniformReturnT(...); - -// Given types <A, B, Expect>, CheckArgsInferType() verifies that -// -// uniform_inferred_return_t<A, B> and -// uniform_inferred_return_t<B, A> -// -// returns the type "Expect". -// -// This interface can also be used to assert that a given inferred return types -// are invalid. Writing: -// -// CheckArgsInferType<float, int, Invalid>() -// -// will assert that this overload does not exist. -template <typename A, typename B, typename Expect> -void CheckArgsInferType() { - static_assert( - absl::conjunction< - std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>, - std::is_same<Expect, - decltype(InferredUniformReturnT<B, A>(0))>>::value, - ""); -} - -TEST_F(UniformHelperTest, UniformTypeInference) { - // Infers common types. - CheckArgsInferType<uint16_t, uint16_t, uint16_t>(); - CheckArgsInferType<uint32_t, uint32_t, uint32_t>(); - CheckArgsInferType<uint64_t, uint64_t, uint64_t>(); - CheckArgsInferType<int16_t, int16_t, int16_t>(); - CheckArgsInferType<int32_t, int32_t, int32_t>(); - CheckArgsInferType<int64_t, int64_t, int64_t>(); - CheckArgsInferType<float, float, float>(); - CheckArgsInferType<double, double, double>(); - - // Properly promotes uint16_t. - CheckArgsInferType<uint16_t, uint32_t, uint32_t>(); - CheckArgsInferType<uint16_t, uint64_t, uint64_t>(); - CheckArgsInferType<uint16_t, int32_t, int32_t>(); - CheckArgsInferType<uint16_t, int64_t, int64_t>(); - CheckArgsInferType<uint16_t, float, float>(); - CheckArgsInferType<uint16_t, double, double>(); - - // Properly promotes int16_t. - CheckArgsInferType<int16_t, int32_t, int32_t>(); - CheckArgsInferType<int16_t, int64_t, int64_t>(); - CheckArgsInferType<int16_t, float, float>(); - CheckArgsInferType<int16_t, double, double>(); - - // Invalid (u)int16_t-pairings do not compile. - // See "CheckArgsInferType" comments above, for how this is achieved. - CheckArgsInferType<uint16_t, int16_t, Invalid>(); - CheckArgsInferType<int16_t, uint32_t, Invalid>(); - CheckArgsInferType<int16_t, uint64_t, Invalid>(); - - // Properly promotes uint32_t. - CheckArgsInferType<uint32_t, uint64_t, uint64_t>(); - CheckArgsInferType<uint32_t, int64_t, int64_t>(); - CheckArgsInferType<uint32_t, double, double>(); - - // Properly promotes int32_t. - CheckArgsInferType<int32_t, int64_t, int64_t>(); - CheckArgsInferType<int32_t, double, double>(); - - // Invalid (u)int32_t-pairings do not compile. - CheckArgsInferType<uint32_t, int32_t, Invalid>(); - CheckArgsInferType<int32_t, uint64_t, Invalid>(); - CheckArgsInferType<int32_t, float, Invalid>(); - CheckArgsInferType<uint32_t, float, Invalid>(); - - // Invalid (u)int64_t-pairings do not compile. - CheckArgsInferType<uint64_t, int64_t, Invalid>(); - CheckArgsInferType<int64_t, float, Invalid>(); - CheckArgsInferType<int64_t, double, Invalid>(); - - // Properly promotes float. - CheckArgsInferType<float, double, double>(); -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/random/internal/wide_multiply.h b/third_party/abseil_cpp/absl/random/internal/wide_multiply.h deleted file mode 100644 index 0afcbe08e229..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/wide_multiply.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ -#define ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ - -#include <cstdint> -#include <limits> -#include <type_traits> - -#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64) -#include <intrin.h> // NOLINT(build/include_order) -#pragma intrinsic(_umul128) -#define ABSL_INTERNAL_USE_UMUL128 1 -#endif - -#include "absl/base/config.h" -#include "absl/base/internal/bits.h" -#include "absl/numeric/int128.h" -#include "absl/random/internal/traits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// Helper object to multiply two 64-bit values to a 128-bit value. -// MultiplyU64ToU128 multiplies two 64-bit values to a 128-bit value. -// If an intrinsic is available, it is used, otherwise use native 32-bit -// multiplies to construct the result. -inline absl::uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) { -#if defined(ABSL_HAVE_INTRINSIC_INT128) - return absl::uint128(static_cast<__uint128_t>(a) * b); -#elif defined(ABSL_INTERNAL_USE_UMUL128) - // uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC. - uint64_t high = 0; - const uint64_t low = _umul128(a, b, &high); - return absl::MakeUint128(high, low); -#else - // uint128(a) * uint128(b) in emulated mode computes a full 128-bit x 128-bit - // multiply. However there are many cases where that is not necessary, and it - // is only necessary to support a 64-bit x 64-bit = 128-bit multiply. This is - // for those cases. - const uint64_t a00 = static_cast<uint32_t>(a); - const uint64_t a32 = a >> 32; - const uint64_t b00 = static_cast<uint32_t>(b); - const uint64_t b32 = b >> 32; - - const uint64_t c00 = a00 * b00; - const uint64_t c32a = a00 * b32; - const uint64_t c32b = a32 * b00; - const uint64_t c64 = a32 * b32; - - const uint32_t carry = - static_cast<uint32_t>(((c00 >> 32) + static_cast<uint32_t>(c32a) + - static_cast<uint32_t>(c32b)) >> - 32); - - return absl::MakeUint128(c64 + (c32a >> 32) + (c32b >> 32) + carry, - c00 + (c32a << 32) + (c32b << 32)); -#endif -} - -// wide_multiply<T> multiplies two N-bit values to a 2N-bit result. -template <typename UIntType> -struct wide_multiply { - static constexpr size_t kN = std::numeric_limits<UIntType>::digits; - using input_type = UIntType; - using result_type = typename random_internal::unsigned_bits<kN * 2>::type; - - static result_type multiply(input_type a, input_type b) { - return static_cast<result_type>(a) * b; - } - - static input_type hi(result_type r) { return r >> kN; } - static input_type lo(result_type r) { return r; } - - static_assert(std::is_unsigned<UIntType>::value, - "Class-template wide_multiply<> argument must be unsigned."); -}; - -#ifndef ABSL_HAVE_INTRINSIC_INT128 -template <> -struct wide_multiply<uint64_t> { - using input_type = uint64_t; - using result_type = absl::uint128; - - static result_type multiply(uint64_t a, uint64_t b) { - return MultiplyU64ToU128(a, b); - } - - static uint64_t hi(result_type r) { return absl::Uint128High64(r); } - static uint64_t lo(result_type r) { return absl::Uint128Low64(r); } -}; -#endif - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ diff --git a/third_party/abseil_cpp/absl/random/internal/wide_multiply_test.cc b/third_party/abseil_cpp/absl/random/internal/wide_multiply_test.cc deleted file mode 100644 index ca8ce923b710..000000000000 --- a/third_party/abseil_cpp/absl/random/internal/wide_multiply_test.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/random/internal/wide_multiply.h" - -#include "gtest/gtest.h" -#include "absl/base/internal/bits.h" -#include "absl/numeric/int128.h" - -using absl::random_internal::MultiplyU64ToU128; - -namespace { - -TEST(WideMultiplyTest, MultiplyU64ToU128Test) { - constexpr uint64_t k1 = 1; - constexpr uint64_t kMax = ~static_cast<uint64_t>(0); - - EXPECT_EQ(absl::uint128(0), MultiplyU64ToU128(0, 0)); - - // Max uint64_t - EXPECT_EQ(MultiplyU64ToU128(kMax, kMax), - absl::MakeUint128(0xfffffffffffffffe, 0x0000000000000001)); - EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(kMax, 1)); - EXPECT_EQ(absl::MakeUint128(0, kMax), MultiplyU64ToU128(1, kMax)); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(absl::MakeUint128(0, kMax) << i, - MultiplyU64ToU128(kMax, k1 << i)); - EXPECT_EQ(absl::MakeUint128(0, kMax) << i, - MultiplyU64ToU128(k1 << i, kMax)); - } - - // 1-bit x 1-bit. - for (int i = 0; i < 64; ++i) { - for (int j = 0; j < 64; ++j) { - EXPECT_EQ(absl::MakeUint128(0, 1) << (i + j), - MultiplyU64ToU128(k1 << i, k1 << j)); - EXPECT_EQ(absl::MakeUint128(0, 1) << (i + j), - MultiplyU64ToU128(k1 << i, k1 << j)); - } - } - - // Verified multiplies - EXPECT_EQ(MultiplyU64ToU128(0xffffeeeeddddcccc, 0xbbbbaaaa99998888), - absl::MakeUint128(0xbbbb9e2692c5dddc, 0xc28f7531048d2c60)); - EXPECT_EQ(MultiplyU64ToU128(0x0123456789abcdef, 0xfedcba9876543210), - absl::MakeUint128(0x0121fa00ad77d742, 0x2236d88fe5618cf0)); - EXPECT_EQ(MultiplyU64ToU128(0x0123456789abcdef, 0xfdb97531eca86420), - absl::MakeUint128(0x0120ae99d26725fc, 0xce197f0ecac319e0)); - EXPECT_EQ(MultiplyU64ToU128(0x97a87f4f261ba3f2, 0xfedcba9876543210), - absl::MakeUint128(0x96fbf1a8ae78d0ba, 0x5a6dd4b71f278320)); - EXPECT_EQ(MultiplyU64ToU128(0xfedcba9876543210, 0xfdb97531eca86420), - absl::MakeUint128(0xfc98c6981a413e22, 0x342d0bbf48948200)); -} - -} // namespace |