randen_engine_test.cc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/random/internal/randen_engine.h"
  15. #include <algorithm>
  16. #include <bitset>
  17. #include <random>
  18. #include <sstream>
  19. #include "gmock/gmock.h"
  20. #include "gtest/gtest.h"
  21. #include "absl/base/internal/raw_logging.h"
  22. #include "absl/random/internal/explicit_seed_seq.h"
  23. #include "absl/strings/str_cat.h"
  24. #include "absl/time/clock.h"
  25. #define UPDATE_GOLDEN 0
  26. using randen_u64 = absl::random_internal::randen_engine<uint64_t>;
  27. using randen_u32 = absl::random_internal::randen_engine<uint32_t>;
  28. using absl::random_internal::ExplicitSeedSeq;
  29. namespace {
  30. template <typename UIntType>
  31. class RandenEngineTypedTest : public ::testing::Test {};
  32. using UIntTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t>;
  33. TYPED_TEST_SUITE(RandenEngineTypedTest, UIntTypes);
  34. TYPED_TEST(RandenEngineTypedTest, VerifyReseedChangesAllValues) {
  35. using randen = typename absl::random_internal::randen_engine<TypeParam>;
  36. using result_type = typename randen::result_type;
  37. const size_t kNumOutputs = (sizeof(randen) * 2 / sizeof(TypeParam)) + 1;
  38. randen engine;
  39. // MSVC emits error 2719 without the use of std::ref below.
  40. // * formal parameter with __declspec(align('#')) won't be aligned
  41. {
  42. std::seed_seq seq1{1, 2, 3, 4, 5, 6, 7};
  43. engine.seed(seq1);
  44. }
  45. result_type a[kNumOutputs];
  46. std::generate(std::begin(a), std::end(a), std::ref(engine));
  47. {
  48. std::random_device rd;
  49. std::seed_seq seq2{rd(), rd(), rd()};
  50. engine.seed(seq2);
  51. }
  52. result_type b[kNumOutputs];
  53. std::generate(std::begin(b), std::end(b), std::ref(engine));
  54. // Test that generated sequence changed as sequence of bits, i.e. if about
  55. // half of the bites were flipped between two non-correlated values.
  56. size_t changed_bits = 0;
  57. size_t unchanged_bits = 0;
  58. size_t total_set = 0;
  59. size_t total_bits = 0;
  60. size_t equal_count = 0;
  61. for (size_t i = 0; i < kNumOutputs; ++i) {
  62. equal_count += (a[i] == b[i]) ? 1 : 0;
  63. std::bitset<sizeof(result_type) * 8> bitset(a[i] ^ b[i]);
  64. changed_bits += bitset.count();
  65. unchanged_bits += bitset.size() - bitset.count();
  66. std::bitset<sizeof(result_type) * 8> a_set(a[i]);
  67. std::bitset<sizeof(result_type) * 8> b_set(b[i]);
  68. total_set += a_set.count() + b_set.count();
  69. total_bits += 2 * 8 * sizeof(result_type);
  70. }
  71. // On average, half the bits are changed between two calls.
  72. EXPECT_LE(changed_bits, 0.60 * (changed_bits + unchanged_bits));
  73. EXPECT_GE(changed_bits, 0.40 * (changed_bits + unchanged_bits));
  74. // Verify using a quick normal-approximation to the binomial.
  75. EXPECT_NEAR(total_set, total_bits * 0.5, 4 * std::sqrt(total_bits))
  76. << "@" << total_set / static_cast<double>(total_bits);
  77. // Also, A[i] == B[i] with probability (1/range) * N.
  78. // Give this a pretty wide latitude, though.
  79. const double kExpected = kNumOutputs / (1.0 * sizeof(result_type) * 8);
  80. EXPECT_LE(equal_count, 1.0 + kExpected);
  81. }
  82. // Number of values that needs to be consumed to clean two sizes of buffer
  83. // and trigger third refresh. (slightly overestimates the actual state size).
  84. constexpr size_t kTwoBufferValues = sizeof(randen_u64) / sizeof(uint16_t) + 1;
  85. TYPED_TEST(RandenEngineTypedTest, VerifyDiscard) {
  86. using randen = typename absl::random_internal::randen_engine<TypeParam>;
  87. for (size_t num_used = 0; num_used < kTwoBufferValues; ++num_used) {
  88. randen engine_used;
  89. for (size_t i = 0; i < num_used; ++i) {
  90. engine_used();
  91. }
  92. for (size_t num_discard = 0; num_discard < kTwoBufferValues;
  93. ++num_discard) {
  94. randen engine1 = engine_used;
  95. randen engine2 = engine_used;
  96. for (size_t i = 0; i < num_discard; ++i) {
  97. engine1();
  98. }
  99. engine2.discard(num_discard);
  100. for (size_t i = 0; i < kTwoBufferValues; ++i) {
  101. const auto r1 = engine1();
  102. const auto r2 = engine2();
  103. ASSERT_EQ(r1, r2) << "used=" << num_used << " discard=" << num_discard;
  104. }
  105. }
  106. }
  107. }
  108. TYPED_TEST(RandenEngineTypedTest, StreamOperatorsResult) {
  109. using randen = typename absl::random_internal::randen_engine<TypeParam>;
  110. std::wostringstream os;
  111. std::wistringstream is;
  112. randen engine;
  113. EXPECT_EQ(&(os << engine), &os);
  114. EXPECT_EQ(&(is >> engine), &is);
  115. }
  116. TYPED_TEST(RandenEngineTypedTest, StreamSerialization) {
  117. using randen = typename absl::random_internal::randen_engine<TypeParam>;
  118. for (size_t discard = 0; discard < kTwoBufferValues; ++discard) {
  119. ExplicitSeedSeq seed_sequence{12, 34, 56};
  120. randen engine(seed_sequence);
  121. engine.discard(discard);
  122. std::stringstream stream;
  123. stream << engine;
  124. randen new_engine;
  125. stream >> new_engine;
  126. for (size_t i = 0; i < 64; ++i) {
  127. EXPECT_EQ(engine(), new_engine()) << " " << i;
  128. }
  129. }
  130. }
  131. constexpr size_t kNumGoldenOutputs = 127;
  132. // This test is checking if randen_engine is meets interface requirements
  133. // defined in [rand.req.urbg].
  134. TYPED_TEST(RandenEngineTypedTest, RandomNumberEngineInterface) {
  135. using randen = typename absl::random_internal::randen_engine<TypeParam>;
  136. using E = randen;
  137. using T = typename E::result_type;
  138. static_assert(std::is_copy_constructible<E>::value,
  139. "randen_engine must be copy constructible");
  140. static_assert(absl::is_copy_assignable<E>::value,
  141. "randen_engine must be copy assignable");
  142. static_assert(std::is_move_constructible<E>::value,
  143. "randen_engine must be move constructible");
  144. static_assert(absl::is_move_assignable<E>::value,
  145. "randen_engine must be move assignable");
  146. static_assert(std::is_same<decltype(std::declval<E>()()), T>::value,
  147. "return type of operator() must be result_type");
  148. // Names after definition of [rand.req.urbg] in C++ standard.
  149. // e us a value of E
  150. // v is a lvalue of E
  151. // x, y are possibly const values of E
  152. // s is a value of T
  153. // q is a value satisfying requirements of seed_sequence
  154. // z is a value of type unsigned long long
  155. // os is a some specialization of basic_ostream
  156. // is is a some specialization of basic_istream
  157. E e, v;
  158. const E x, y;
  159. T s = 1;
  160. std::seed_seq q{1, 2, 3};
  161. unsigned long long z = 1; // NOLINT(runtime/int)
  162. std::wostringstream os;
  163. std::wistringstream is;
  164. E{};
  165. E{x};
  166. E{s};
  167. E{q};
  168. e.seed();
  169. // MSVC emits error 2718 when using EXPECT_EQ(e, x)
  170. // * actual parameter with __declspec(align('#')) won't be aligned
  171. EXPECT_TRUE(e == x);
  172. e.seed(q);
  173. {
  174. E tmp(q);
  175. EXPECT_TRUE(e == tmp);
  176. }
  177. e();
  178. {
  179. E tmp(q);
  180. EXPECT_TRUE(e != tmp);
  181. }
  182. e.discard(z);
  183. static_assert(std::is_same<decltype(x == y), bool>::value,
  184. "return type of operator== must be bool");
  185. static_assert(std::is_same<decltype(x != y), bool>::value,
  186. "return type of operator== must be bool");
  187. }
  188. TYPED_TEST(RandenEngineTypedTest, RandenEngineSFINAETest) {
  189. using randen = typename absl::random_internal::randen_engine<TypeParam>;
  190. using result_type = typename randen::result_type;
  191. {
  192. randen engine(result_type(1));
  193. engine.seed(result_type(1));
  194. }
  195. {
  196. result_type n = 1;
  197. randen engine(n);
  198. engine.seed(n);
  199. }
  200. {
  201. randen engine(1);
  202. engine.seed(1);
  203. }
  204. {
  205. int n = 1;
  206. randen engine(n);
  207. engine.seed(n);
  208. }
  209. {
  210. std::seed_seq seed_seq;
  211. randen engine(seed_seq);
  212. engine.seed(seed_seq);
  213. }
  214. {
  215. randen engine{std::seed_seq()};
  216. engine.seed(std::seed_seq());
  217. }
  218. }
  219. TEST(RandenTest, VerifyGoldenRanden64Default) {
  220. constexpr uint64_t kGolden[kNumGoldenOutputs] = {
  221. 0xc3c14f134e433977, 0xdda9f47cd90410ee, 0x887bf3087fd8ca10,
  222. 0xf0b780f545c72912, 0x15dbb1d37696599f, 0x30ec63baff3c6d59,
  223. 0xb29f73606f7f20a6, 0x02808a316f49a54c, 0x3b8feaf9d5c8e50e,
  224. 0x9cbf605e3fd9de8a, 0xc970ae1a78183bbb, 0xd8b2ffd356301ed5,
  225. 0xf4b327fe0fc73c37, 0xcdfd8d76eb8f9a19, 0xc3a506eb91420c9d,
  226. 0xd5af05dd3eff9556, 0x48db1bb78f83c4a1, 0x7023920e0d6bfe8c,
  227. 0x58d3575834956d42, 0xed1ef4c26b87b840, 0x8eef32a23e0b2df3,
  228. 0x497cabf3431154fc, 0x4e24370570029a8b, 0xd88b5749f090e5ea,
  229. 0xc651a582a970692f, 0x78fcec2cbb6342f5, 0x463cb745612f55db,
  230. 0x352ee4ad1816afe3, 0x026ff374c101da7e, 0x811ef0821c3de851,
  231. 0x6f7e616704c4fa59, 0xa0660379992d58fc, 0x04b0a374a3b795c7,
  232. 0x915f3445685da798, 0x26802a8ac76571ce, 0x4663352533ce1882,
  233. 0xb9fdefb4a24dc738, 0x5588ba3a4d6e6c51, 0xa2101a42d35f1956,
  234. 0x607195a5e200f5fd, 0x7e100308f3290764, 0xe1e5e03c759c0709,
  235. 0x082572cc5da6606f, 0xcbcf585399e432f1, 0xe8a2be4f8335d8f1,
  236. 0x0904469acbfee8f2, 0xf08bd31b6daecd51, 0x08e8a1f1a69da69a,
  237. 0x6542a20aad57bff5, 0x2e9705bb053d6b46, 0xda2fc9db0713c391,
  238. 0x78e3a810213b6ffb, 0xdc16a59cdd85f8a6, 0xc0932718cd55781f,
  239. 0xb9bfb29c2b20bfe5, 0xb97289c1be0f2f9c, 0xc0a2a0e403a892d4,
  240. 0x5524bb834771435b, 0x8265da3d39d1a750, 0xff4af3ab8d1b78c5,
  241. 0xf0ec5f424bcad77f, 0x66e455f627495189, 0xc82d3120b57e3270,
  242. 0x3424e47dc22596e3, 0xbc0c95129ccedcdd, 0xc191c595afc4dcbf,
  243. 0x120392bd2bb70939, 0x7f90650ea6cd6ab4, 0x7287491832695ad3,
  244. 0xa7c8fac5a7917eb0, 0xd088cb9418be0361, 0x7c1bf9839c7c1ce5,
  245. 0xe2e991fa58e1e79e, 0x78565cdefd28c4ad, 0x7351b9fef98bafad,
  246. 0x2a9eac28b08c96bf, 0x6c4f179696cb2225, 0x13a685861bab87e0,
  247. 0x64c6de5aa0501971, 0x30537425cac70991, 0x01590d9dc6c532b7,
  248. 0x7e05e3aa8ec720dc, 0x74a07d9c54e3e63f, 0x738184388f3bc1d2,
  249. 0x26ffdc5067be3acb, 0x6bcdf185561f255f, 0xa0eaf2e1cf99b1c6,
  250. 0x171df81934f68604, 0x7ea5a21665683e5a, 0x5d1cb02075ba1cea,
  251. 0x957f38cbd2123fdf, 0xba6364eff80de02f, 0x606e0a0e41d452ee,
  252. 0x892d8317de82f7a2, 0xe707b1db50f7b43e, 0x4eb28826766fcf5b,
  253. 0x5a362d56e80a0951, 0x6ee217df16527d78, 0xf6737962ba6b23dd,
  254. 0x443e63857d4076ca, 0x790d9a5f048adfeb, 0xd796b052151ee94d,
  255. 0x033ed95c12b04a03, 0x8b833ff84893da5d, 0x3d6724b1bb15eab9,
  256. 0x9877c4225061ca76, 0xd68d6810adf74fb3, 0x42e5352fe30ce989,
  257. 0x265b565a7431fde7, 0x3cdbf7e358df4b8b, 0x2922a47f6d3e8779,
  258. 0x52d2242f65b37f88, 0x5d836d6e2958d6b5, 0x29d40f00566d5e26,
  259. 0x288db0e1124b14a0, 0x6c056608b7d9c1b6, 0x0b9471bdb8f19d32,
  260. 0x8fb946504faa6c9d, 0x8943a9464540251c, 0xfd1fe27d144a09e0,
  261. 0xea6ac458da141bda, 0x8048f217633fce36, 0xfeda1384ade74d31,
  262. 0x4334b8b02ff7612f, 0xdbc8441f5227e216, 0x096d119a3605c85b,
  263. 0x2b72b31c21b7d7d0};
  264. randen_u64 engine;
  265. #if UPDATE_GOLDEN
  266. (void)kGolden; // Silence warning.
  267. for (size_t i = 0; i < kNumGoldenOutputs; ++i) {
  268. printf("0x%016lx, ", engine());
  269. if (i % 3 == 2) {
  270. printf("\n");
  271. }
  272. }
  273. printf("\n\n\n");
  274. #else
  275. for (const auto& elem : kGolden) {
  276. EXPECT_EQ(elem, engine());
  277. }
  278. engine.seed();
  279. for (const auto& elem : kGolden) {
  280. EXPECT_EQ(elem, engine());
  281. }
  282. #endif
  283. }
  284. TEST(RandenTest, VerifyGoldenRanden64Seeded) {
  285. constexpr uint64_t kGolden[kNumGoldenOutputs] = {
  286. 0x83a9e58f94d3dcd5, 0x70bbdff3d97949fb, 0x0438481f7471c1b4,
  287. 0x34fdc58ee5fb5930, 0xceee4f2d2a937d17, 0xb5a26a68e432aea9,
  288. 0x8b64774a3fb51740, 0xd89ac1fc74249c74, 0x03910d1d23fc3fdf,
  289. 0xd38f630878aa897f, 0x0ee8f0f5615f7e44, 0x98f5a53df8279d52,
  290. 0xb403f52c25938d0e, 0x240072996ea6e838, 0xd3a791246190fa61,
  291. 0xaaedd3df7a7b4f80, 0xc6eacabe05deaf6e, 0xb7967dd8790edf4d,
  292. 0x9a0a8e67e049d279, 0x0494f606aebc23e7, 0x598dcd687bc3e0ee,
  293. 0x010ac81802d452a1, 0x6407c87160aa2842, 0x5a56e276486f93a0,
  294. 0xc887a399d46a8f02, 0x9e1e6100fe93b740, 0x12d02e330f8901f6,
  295. 0xc39ca52b47e790b7, 0xb0b0a2fa11e82e61, 0x1542d841a303806a,
  296. 0x1fe659fd7d6e9d86, 0xb8c90d80746541ac, 0x239d56a5669ddc94,
  297. 0xd40db57c8123d13c, 0x3abc2414153a0db0, 0x9bad665630cb8d61,
  298. 0x0bd1fb90ee3f4bbc, 0x8f0b4d7e079b4e42, 0xfa0fb0e0ee59e793,
  299. 0x51080b283e071100, 0x2c4b9e715081cc15, 0xbe10ed49de4941df,
  300. 0xf8eaac9d4b1b0d37, 0x4bcce4b54605e139, 0xa64722b76765dda6,
  301. 0xb9377d738ca28ab5, 0x779fad81a8ccc1af, 0x65cb3ee61ffd3ba7,
  302. 0xd74e79087862836f, 0xd05b9c584c3f25bf, 0x2ba93a4693579827,
  303. 0xd81530aff05420ce, 0xec06cea215478621, 0x4b1798a6796d65ad,
  304. 0xf142f3fb3a6f6fa6, 0x002b7bf7e237b560, 0xf47f2605ef65b4f8,
  305. 0x9804ec5517effc18, 0xaed3d7f8b7d481cd, 0x5651c24c1ce338d1,
  306. 0x3e7a38208bf0a3c6, 0x6796a7b614534aed, 0x0d0f3b848358460f,
  307. 0x0fa5fe7600b19524, 0x2b0cf38253faaedc, 0x10df9188233a9fd6,
  308. 0x3a10033880138b59, 0x5fb0b0d23948e80f, 0x9e76f7b02fbf5350,
  309. 0x0816052304b1a985, 0x30c9880db41fd218, 0x14aa399b65e20f28,
  310. 0xe1454a8cace787b4, 0x325ac971b6c6f0f5, 0x716b1aa2784f3d36,
  311. 0x3d5ce14accfd144f, 0x6c0c97710f651792, 0xbc5b0f59fb333532,
  312. 0x2a90a7d2140470bc, 0x8da269f55c1e1c8d, 0xcfc37143895792ca,
  313. 0xbe21eab1f30b238f, 0x8c47229dee4d65fd, 0x5743614ed1ed7d54,
  314. 0x351372a99e9c476e, 0x2bd5ea15e5db085f, 0x6925fde46e0af4ca,
  315. 0xed3eda2bdc1f45bd, 0xdef68c68d460fa6e, 0xe42a0de76253e2b5,
  316. 0x4e5176dcbc29c305, 0xbfd85fba9f810f6e, 0x76a5a2a9beb815c6,
  317. 0x01edc4ddceaf414c, 0xa4e98904b4bb3b4b, 0x00bd63ac7d2f1ddd,
  318. 0xb8491fe6e998ddbb, 0xb386a3463dda6800, 0x0081887688871619,
  319. 0x33d394b3344e9a38, 0x815dba65a3a8baf9, 0x4232f6ec02c2fd1a,
  320. 0xb5cff603edd20834, 0x580189243f687663, 0xa8d5a2cbdc27fe99,
  321. 0x725d881693fa0131, 0xa2be2c13db2c7ac5, 0x7b6a9614b509fd78,
  322. 0xb6b136d71e717636, 0x660f1a71aff046ea, 0x0ba10ae346c8ec9e,
  323. 0xe66dde53e3145b41, 0x3b18288c88c26be6, 0x4d9d9d2ff02db933,
  324. 0x4167da8c70f46e8a, 0xf183beef8c6318b4, 0x4d889e1e71eeeef1,
  325. 0x7175c71ad6689b6b, 0xfb9e42beacd1b7dd, 0xc33d0e91b29b5e0d,
  326. 0xd39b83291ce47922, 0xc4d570fb8493d12e, 0x23d5a5724f424ae6,
  327. 0x5245f161876b6616, 0x38d77dbd21ab578d, 0x9c3423311f4ecbfe,
  328. 0x76fe31389bacd9d5,
  329. };
  330. ExplicitSeedSeq seed_sequence{12, 34, 56};
  331. randen_u64 engine(seed_sequence);
  332. #if UPDATE_GOLDEN
  333. (void)kGolden; // Silence warning.
  334. for (size_t i = 0; i < kNumGoldenOutputs; ++i) {
  335. printf("0x%016lx, ", engine());
  336. if (i % 3 == 2) {
  337. printf("\n");
  338. }
  339. }
  340. printf("\n\n\n");
  341. #else
  342. for (const auto& elem : kGolden) {
  343. EXPECT_EQ(elem, engine());
  344. }
  345. engine.seed(seed_sequence);
  346. for (const auto& elem : kGolden) {
  347. EXPECT_EQ(elem, engine());
  348. }
  349. #endif
  350. }
  351. TEST(RandenTest, VerifyGoldenRanden32Default) {
  352. constexpr uint64_t kGolden[2 * kNumGoldenOutputs] = {
  353. 0x4e433977, 0xc3c14f13, 0xd90410ee, 0xdda9f47c, 0x7fd8ca10, 0x887bf308,
  354. 0x45c72912, 0xf0b780f5, 0x7696599f, 0x15dbb1d3, 0xff3c6d59, 0x30ec63ba,
  355. 0x6f7f20a6, 0xb29f7360, 0x6f49a54c, 0x02808a31, 0xd5c8e50e, 0x3b8feaf9,
  356. 0x3fd9de8a, 0x9cbf605e, 0x78183bbb, 0xc970ae1a, 0x56301ed5, 0xd8b2ffd3,
  357. 0x0fc73c37, 0xf4b327fe, 0xeb8f9a19, 0xcdfd8d76, 0x91420c9d, 0xc3a506eb,
  358. 0x3eff9556, 0xd5af05dd, 0x8f83c4a1, 0x48db1bb7, 0x0d6bfe8c, 0x7023920e,
  359. 0x34956d42, 0x58d35758, 0x6b87b840, 0xed1ef4c2, 0x3e0b2df3, 0x8eef32a2,
  360. 0x431154fc, 0x497cabf3, 0x70029a8b, 0x4e243705, 0xf090e5ea, 0xd88b5749,
  361. 0xa970692f, 0xc651a582, 0xbb6342f5, 0x78fcec2c, 0x612f55db, 0x463cb745,
  362. 0x1816afe3, 0x352ee4ad, 0xc101da7e, 0x026ff374, 0x1c3de851, 0x811ef082,
  363. 0x04c4fa59, 0x6f7e6167, 0x992d58fc, 0xa0660379, 0xa3b795c7, 0x04b0a374,
  364. 0x685da798, 0x915f3445, 0xc76571ce, 0x26802a8a, 0x33ce1882, 0x46633525,
  365. 0xa24dc738, 0xb9fdefb4, 0x4d6e6c51, 0x5588ba3a, 0xd35f1956, 0xa2101a42,
  366. 0xe200f5fd, 0x607195a5, 0xf3290764, 0x7e100308, 0x759c0709, 0xe1e5e03c,
  367. 0x5da6606f, 0x082572cc, 0x99e432f1, 0xcbcf5853, 0x8335d8f1, 0xe8a2be4f,
  368. 0xcbfee8f2, 0x0904469a, 0x6daecd51, 0xf08bd31b, 0xa69da69a, 0x08e8a1f1,
  369. 0xad57bff5, 0x6542a20a, 0x053d6b46, 0x2e9705bb, 0x0713c391, 0xda2fc9db,
  370. 0x213b6ffb, 0x78e3a810, 0xdd85f8a6, 0xdc16a59c, 0xcd55781f, 0xc0932718,
  371. 0x2b20bfe5, 0xb9bfb29c, 0xbe0f2f9c, 0xb97289c1, 0x03a892d4, 0xc0a2a0e4,
  372. 0x4771435b, 0x5524bb83, 0x39d1a750, 0x8265da3d, 0x8d1b78c5, 0xff4af3ab,
  373. 0x4bcad77f, 0xf0ec5f42, 0x27495189, 0x66e455f6, 0xb57e3270, 0xc82d3120,
  374. 0xc22596e3, 0x3424e47d, 0x9ccedcdd, 0xbc0c9512, 0xafc4dcbf, 0xc191c595,
  375. 0x2bb70939, 0x120392bd, 0xa6cd6ab4, 0x7f90650e, 0x32695ad3, 0x72874918,
  376. 0xa7917eb0, 0xa7c8fac5, 0x18be0361, 0xd088cb94, 0x9c7c1ce5, 0x7c1bf983,
  377. 0x58e1e79e, 0xe2e991fa, 0xfd28c4ad, 0x78565cde, 0xf98bafad, 0x7351b9fe,
  378. 0xb08c96bf, 0x2a9eac28, 0x96cb2225, 0x6c4f1796, 0x1bab87e0, 0x13a68586,
  379. 0xa0501971, 0x64c6de5a, 0xcac70991, 0x30537425, 0xc6c532b7, 0x01590d9d,
  380. 0x8ec720dc, 0x7e05e3aa, 0x54e3e63f, 0x74a07d9c, 0x8f3bc1d2, 0x73818438,
  381. 0x67be3acb, 0x26ffdc50, 0x561f255f, 0x6bcdf185, 0xcf99b1c6, 0xa0eaf2e1,
  382. 0x34f68604, 0x171df819, 0x65683e5a, 0x7ea5a216, 0x75ba1cea, 0x5d1cb020,
  383. 0xd2123fdf, 0x957f38cb, 0xf80de02f, 0xba6364ef, 0x41d452ee, 0x606e0a0e,
  384. 0xde82f7a2, 0x892d8317, 0x50f7b43e, 0xe707b1db, 0x766fcf5b, 0x4eb28826,
  385. 0xe80a0951, 0x5a362d56, 0x16527d78, 0x6ee217df, 0xba6b23dd, 0xf6737962,
  386. 0x7d4076ca, 0x443e6385, 0x048adfeb, 0x790d9a5f, 0x151ee94d, 0xd796b052,
  387. 0x12b04a03, 0x033ed95c, 0x4893da5d, 0x8b833ff8, 0xbb15eab9, 0x3d6724b1,
  388. 0x5061ca76, 0x9877c422, 0xadf74fb3, 0xd68d6810, 0xe30ce989, 0x42e5352f,
  389. 0x7431fde7, 0x265b565a, 0x58df4b8b, 0x3cdbf7e3, 0x6d3e8779, 0x2922a47f,
  390. 0x65b37f88, 0x52d2242f, 0x2958d6b5, 0x5d836d6e, 0x566d5e26, 0x29d40f00,
  391. 0x124b14a0, 0x288db0e1, 0xb7d9c1b6, 0x6c056608, 0xb8f19d32, 0x0b9471bd,
  392. 0x4faa6c9d, 0x8fb94650, 0x4540251c, 0x8943a946, 0x144a09e0, 0xfd1fe27d,
  393. 0xda141bda, 0xea6ac458, 0x633fce36, 0x8048f217, 0xade74d31, 0xfeda1384,
  394. 0x2ff7612f, 0x4334b8b0, 0x5227e216, 0xdbc8441f, 0x3605c85b, 0x096d119a,
  395. 0x21b7d7d0, 0x2b72b31c};
  396. randen_u32 engine;
  397. #if UPDATE_GOLDEN
  398. (void)kGolden; // Silence warning.
  399. for (size_t i = 0; i < 2 * kNumGoldenOutputs; ++i) {
  400. printf("0x%08x, ", engine());
  401. if (i % 6 == 5) {
  402. printf("\n");
  403. }
  404. }
  405. printf("\n\n\n");
  406. #else
  407. for (const auto& elem : kGolden) {
  408. EXPECT_EQ(elem, engine());
  409. }
  410. engine.seed();
  411. for (const auto& elem : kGolden) {
  412. EXPECT_EQ(elem, engine());
  413. }
  414. #endif
  415. }
  416. TEST(RandenTest, VerifyGoldenRanden32Seeded) {
  417. constexpr uint64_t kGolden[2 * kNumGoldenOutputs] = {
  418. 0x94d3dcd5, 0x83a9e58f, 0xd97949fb, 0x70bbdff3, 0x7471c1b4, 0x0438481f,
  419. 0xe5fb5930, 0x34fdc58e, 0x2a937d17, 0xceee4f2d, 0xe432aea9, 0xb5a26a68,
  420. 0x3fb51740, 0x8b64774a, 0x74249c74, 0xd89ac1fc, 0x23fc3fdf, 0x03910d1d,
  421. 0x78aa897f, 0xd38f6308, 0x615f7e44, 0x0ee8f0f5, 0xf8279d52, 0x98f5a53d,
  422. 0x25938d0e, 0xb403f52c, 0x6ea6e838, 0x24007299, 0x6190fa61, 0xd3a79124,
  423. 0x7a7b4f80, 0xaaedd3df, 0x05deaf6e, 0xc6eacabe, 0x790edf4d, 0xb7967dd8,
  424. 0xe049d279, 0x9a0a8e67, 0xaebc23e7, 0x0494f606, 0x7bc3e0ee, 0x598dcd68,
  425. 0x02d452a1, 0x010ac818, 0x60aa2842, 0x6407c871, 0x486f93a0, 0x5a56e276,
  426. 0xd46a8f02, 0xc887a399, 0xfe93b740, 0x9e1e6100, 0x0f8901f6, 0x12d02e33,
  427. 0x47e790b7, 0xc39ca52b, 0x11e82e61, 0xb0b0a2fa, 0xa303806a, 0x1542d841,
  428. 0x7d6e9d86, 0x1fe659fd, 0x746541ac, 0xb8c90d80, 0x669ddc94, 0x239d56a5,
  429. 0x8123d13c, 0xd40db57c, 0x153a0db0, 0x3abc2414, 0x30cb8d61, 0x9bad6656,
  430. 0xee3f4bbc, 0x0bd1fb90, 0x079b4e42, 0x8f0b4d7e, 0xee59e793, 0xfa0fb0e0,
  431. 0x3e071100, 0x51080b28, 0x5081cc15, 0x2c4b9e71, 0xde4941df, 0xbe10ed49,
  432. 0x4b1b0d37, 0xf8eaac9d, 0x4605e139, 0x4bcce4b5, 0x6765dda6, 0xa64722b7,
  433. 0x8ca28ab5, 0xb9377d73, 0xa8ccc1af, 0x779fad81, 0x1ffd3ba7, 0x65cb3ee6,
  434. 0x7862836f, 0xd74e7908, 0x4c3f25bf, 0xd05b9c58, 0x93579827, 0x2ba93a46,
  435. 0xf05420ce, 0xd81530af, 0x15478621, 0xec06cea2, 0x796d65ad, 0x4b1798a6,
  436. 0x3a6f6fa6, 0xf142f3fb, 0xe237b560, 0x002b7bf7, 0xef65b4f8, 0xf47f2605,
  437. 0x17effc18, 0x9804ec55, 0xb7d481cd, 0xaed3d7f8, 0x1ce338d1, 0x5651c24c,
  438. 0x8bf0a3c6, 0x3e7a3820, 0x14534aed, 0x6796a7b6, 0x8358460f, 0x0d0f3b84,
  439. 0x00b19524, 0x0fa5fe76, 0x53faaedc, 0x2b0cf382, 0x233a9fd6, 0x10df9188,
  440. 0x80138b59, 0x3a100338, 0x3948e80f, 0x5fb0b0d2, 0x2fbf5350, 0x9e76f7b0,
  441. 0x04b1a985, 0x08160523, 0xb41fd218, 0x30c9880d, 0x65e20f28, 0x14aa399b,
  442. 0xace787b4, 0xe1454a8c, 0xb6c6f0f5, 0x325ac971, 0x784f3d36, 0x716b1aa2,
  443. 0xccfd144f, 0x3d5ce14a, 0x0f651792, 0x6c0c9771, 0xfb333532, 0xbc5b0f59,
  444. 0x140470bc, 0x2a90a7d2, 0x5c1e1c8d, 0x8da269f5, 0x895792ca, 0xcfc37143,
  445. 0xf30b238f, 0xbe21eab1, 0xee4d65fd, 0x8c47229d, 0xd1ed7d54, 0x5743614e,
  446. 0x9e9c476e, 0x351372a9, 0xe5db085f, 0x2bd5ea15, 0x6e0af4ca, 0x6925fde4,
  447. 0xdc1f45bd, 0xed3eda2b, 0xd460fa6e, 0xdef68c68, 0x6253e2b5, 0xe42a0de7,
  448. 0xbc29c305, 0x4e5176dc, 0x9f810f6e, 0xbfd85fba, 0xbeb815c6, 0x76a5a2a9,
  449. 0xceaf414c, 0x01edc4dd, 0xb4bb3b4b, 0xa4e98904, 0x7d2f1ddd, 0x00bd63ac,
  450. 0xe998ddbb, 0xb8491fe6, 0x3dda6800, 0xb386a346, 0x88871619, 0x00818876,
  451. 0x344e9a38, 0x33d394b3, 0xa3a8baf9, 0x815dba65, 0x02c2fd1a, 0x4232f6ec,
  452. 0xedd20834, 0xb5cff603, 0x3f687663, 0x58018924, 0xdc27fe99, 0xa8d5a2cb,
  453. 0x93fa0131, 0x725d8816, 0xdb2c7ac5, 0xa2be2c13, 0xb509fd78, 0x7b6a9614,
  454. 0x1e717636, 0xb6b136d7, 0xaff046ea, 0x660f1a71, 0x46c8ec9e, 0x0ba10ae3,
  455. 0xe3145b41, 0xe66dde53, 0x88c26be6, 0x3b18288c, 0xf02db933, 0x4d9d9d2f,
  456. 0x70f46e8a, 0x4167da8c, 0x8c6318b4, 0xf183beef, 0x71eeeef1, 0x4d889e1e,
  457. 0xd6689b6b, 0x7175c71a, 0xacd1b7dd, 0xfb9e42be, 0xb29b5e0d, 0xc33d0e91,
  458. 0x1ce47922, 0xd39b8329, 0x8493d12e, 0xc4d570fb, 0x4f424ae6, 0x23d5a572,
  459. 0x876b6616, 0x5245f161, 0x21ab578d, 0x38d77dbd, 0x1f4ecbfe, 0x9c342331,
  460. 0x9bacd9d5, 0x76fe3138,
  461. };
  462. ExplicitSeedSeq seed_sequence{12, 34, 56};
  463. randen_u32 engine(seed_sequence);
  464. #if UPDATE_GOLDEN
  465. (void)kGolden; // Silence warning.
  466. for (size_t i = 0; i < 2 * kNumGoldenOutputs; ++i) {
  467. printf("0x%08x, ", engine());
  468. if (i % 6 == 5) {
  469. printf("\n");
  470. }
  471. }
  472. printf("\n\n\n");
  473. #else
  474. for (const auto& elem : kGolden) {
  475. EXPECT_EQ(elem, engine());
  476. }
  477. engine.seed(seed_sequence);
  478. for (const auto& elem : kGolden) {
  479. EXPECT_EQ(elem, engine());
  480. }
  481. #endif
  482. }
  483. TEST(RandenTest, VerifyGoldenFromDeserializedEngine) {
  484. constexpr uint64_t kGolden[kNumGoldenOutputs] = {
  485. 0x067f9f9ab919657a, 0x0534605912988583, 0x8a303f72feaa673f,
  486. 0x77b7fd747909185c, 0xd9af90403c56d891, 0xd939c6cb204d14b5,
  487. 0x7fbe6b954a47b483, 0x8b31a47cc34c768d, 0x3a9e546da2701a9c,
  488. 0x5246539046253e71, 0x417191ffb2a848a1, 0x7b1c7bf5a5001d09,
  489. 0x9489b15d194f2361, 0xfcebdeea3bcd2461, 0xd643027c854cec97,
  490. 0x5885397f91e0d21c, 0x53173b0efae30d58, 0x1c9c71168449fac1,
  491. 0xe358202b711ed8aa, 0x94e3918ed1d8227c, 0x5bb4e251450144cf,
  492. 0xb5c7a519b489af3b, 0x6f8b560b1f7b3469, 0xfde11dd4a1c74eef,
  493. 0x33383d2f76457dcf, 0x3060c0ec6db9fce1, 0x18f451fcddeec766,
  494. 0xe73c5d6b9f26da2a, 0x8d4cc566671b32a4, 0xb8189b73776bc9ff,
  495. 0x497a70f9caf0bc23, 0x23afcc509791dcea, 0x18af70dc4b27d306,
  496. 0xd3853f955a0ce5b9, 0x441db6c01a0afb17, 0xd0136c3fb8e1f13f,
  497. 0x5e4fd6fc2f33783c, 0xe0d24548adb5da51, 0x0f4d8362a7d3485a,
  498. 0x9f572d68270fa563, 0x6351fbc823024393, 0xa66dbfc61810e9ab,
  499. 0x0ff17fc14b651af8, 0xd74c55dafb99e623, 0x36303bc1ad85c6c2,
  500. 0x4920cd6a2af7e897, 0x0b8848addc30fecd, 0x9e1562eda6488e93,
  501. 0x197553807d607828, 0xbef5eaeda5e21235, 0x18d91d2616aca527,
  502. 0xb7821937f5c873cd, 0x2cd4ae5650dbeefc, 0xb35a64376f75ffdf,
  503. 0x9226d414d647fe07, 0x663f3db455bbb35e, 0xa829eead6ae93247,
  504. 0x7fd69c204dd0d25f, 0xbe1411f891c9acb1, 0xd476f34a506d5f11,
  505. 0xf423d2831649c5ca, 0x1e503962951abd75, 0xeccc9e8b1e34b537,
  506. 0xb11a147294044854, 0xc4cf27f0abf4929d, 0xe9193abf6fa24c8c,
  507. 0xa94a259e3aba8808, 0x21dc414197deffa3, 0xa2ae211d1ff622ae,
  508. 0xfe3995c46be5a4f4, 0xe9984c284bf11128, 0xcb1ce9d2f0851a80,
  509. 0x42fee17971d87cd8, 0xac76a98d177adc88, 0xa0973b3dedc4af6f,
  510. 0xdf56d6bbcb1b8e86, 0xf1e6485f407b11c9, 0x2c63de4deccb15c0,
  511. 0x6fe69db32ed4fad7, 0xaa51a65f84bca1f1, 0x242f2ee81d608afc,
  512. 0x8eb88b2b69fc153b, 0x22c20098baf73fd1, 0x57759466f576488c,
  513. 0x075ca562cea1be9d, 0x9a74814d73d28891, 0x73d1555fc02f4d3d,
  514. 0xc17f8f210ee89337, 0x46cca7999eaeafd4, 0x5db8d6a327a0d8ac,
  515. 0xb79b4f93c738d7a1, 0x9994512f0036ded1, 0xd3883026f38747f4,
  516. 0xf31f7458078d097c, 0x736ce4d480680669, 0x7a496f4c7e1033e3,
  517. 0xecf85bf297fbc68c, 0x9e37e1d0f24f3c4e, 0x15b6e067ca0746fc,
  518. 0xdd4a39905c5db81c, 0xb5dfafa7bcfdf7da, 0xca6646fb6f92a276,
  519. 0x1c6b35f363ef0efd, 0x6a33d06037ad9f76, 0x45544241afd8f80f,
  520. 0x83f8d83f859c90c5, 0x22aea9c5365e8c19, 0xfac35b11f20b6a6a,
  521. 0xd1acf49d1a27dd2f, 0xf281cd09c4fed405, 0x076000a42cd38e4f,
  522. 0x6ace300565070445, 0x463a62781bddc4db, 0x1477126b46b569ac,
  523. 0x127f2bb15035fbb8, 0xdfa30946049c04a8, 0x89072a586ba8dd3e,
  524. 0x62c809582bb7e74d, 0x22c0c3641406c28b, 0x9b66e36c47ff004d,
  525. 0xb9cd2c7519653330, 0x18608d79cd7a598d, 0x92c0bd1323e53e32,
  526. 0x887ff00de8524aa5, 0xa074410b787abd10, 0x18ab41b8057a2063,
  527. 0x1560abf26bc5f987};
  528. #if UPDATE_GOLDEN
  529. (void)kGolden; // Silence warning.
  530. std::seed_seq seed_sequence{1, 2, 3, 4, 5};
  531. randen_u64 engine(seed_sequence);
  532. std::ostringstream stream;
  533. stream << engine;
  534. auto str = stream.str();
  535. printf("%s\n\n", str.c_str());
  536. for (size_t i = 0; i < kNumGoldenOutputs; ++i) {
  537. printf("0x%016lx, ", engine());
  538. if (i % 3 == 2) {
  539. printf("\n");
  540. }
  541. }
  542. printf("\n\n\n");
  543. #else
  544. randen_u64 engine;
  545. std::istringstream stream(
  546. "0 0 9824501439887287479 3242284395352394785 243836530774933777 "
  547. "4047941804708365596 17165468127298385802 949276103645889255 "
  548. "10659970394998657921 1657570836810929787 11697746266668051452 "
  549. "9967209969299905230 14140390331161524430 7383014124183271684 "
  550. "13146719127702337852 13983155220295807171 11121125587542359264 "
  551. "195757810993252695 17138580243103178492 11326030747260920501 "
  552. "8585097322474965590 18342582839328350995 15052982824209724634 "
  553. "7321861343874683609 1806786911778767826 10100850842665572955 "
  554. "9249328950653985078 13600624835326909759 11137960060943860251 "
  555. "10208781341792329629 9282723971471525577 16373271619486811032 32");
  556. stream >> engine;
  557. for (const auto& elem : kGolden) {
  558. EXPECT_EQ(elem, engine());
  559. }
  560. #endif
  561. }
  562. TEST(RandenTest, IsFastOrSlow) {
  563. // randen_engine typically costs ~5ns per value for the optimized code paths,
  564. // and the ~1000ns per value for slow code paths. However when running under
  565. // msan, asan, etc. it can take much longer.
  566. //
  567. // The estimated operation time is something like:
  568. //
  569. // linux, optimized ~5ns
  570. // ppc, optimized ~7ns
  571. // nacl (slow), ~1100ns
  572. //
  573. // `kCount` is chosen below so that, in debug builds and without hardware
  574. // acceleration, the test (assuming ~1us per call) should finish in ~0.1s
  575. static constexpr size_t kCount = 100000;
  576. randen_u64 engine;
  577. randen_u64::result_type sum = 0;
  578. auto start = absl::GetCurrentTimeNanos();
  579. for (int i = 0; i < kCount; i++) {
  580. sum += engine();
  581. }
  582. auto duration = absl::GetCurrentTimeNanos() - start;
  583. ABSL_INTERNAL_LOG(INFO, absl::StrCat(static_cast<double>(duration) /
  584. static_cast<double>(kCount),
  585. "ns"));
  586. EXPECT_GT(sum, 0);
  587. EXPECT_GE(duration, kCount); // Should be slower than 1ns per call.
  588. }
  589. } // namespace