From 07c084b3a36881e70ff2731953be3c16cd4cc8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 9 Feb 2026 17:58:37 +0300 Subject: [PATCH 1/2] Move `rand_pcg` to the `rand/rngs` repository --- .github/workflows/release.yml | 8 +- Cargo.lock | 12 +- Cargo.toml | 7 +- benches/Cargo.toml | 2 +- rand_pcg/CHANGELOG.md | 66 -------- rand_pcg/COPYRIGHT | 12 -- rand_pcg/Cargo.toml | 32 ---- rand_pcg/LICENSE-APACHE | 187 --------------------- rand_pcg/LICENSE-MIT | 26 --- rand_pcg/README.md | 39 ----- rand_pcg/src/lib.rs | 98 ----------- rand_pcg/src/pcg128.rs | 272 ------------------------------- rand_pcg/src/pcg128cm.rs | 178 -------------------- rand_pcg/src/pcg64.rs | 166 ------------------- rand_pcg/tests/lcg128cmdxsm64.rs | 72 -------- rand_pcg/tests/lcg128xsl64.rs | 71 -------- rand_pcg/tests/lcg64xsh32.rs | 63 ------- rand_pcg/tests/mcg128xsl64.rs | 69 -------- 18 files changed, 10 insertions(+), 1370 deletions(-) delete mode 100644 rand_pcg/CHANGELOG.md delete mode 100644 rand_pcg/COPYRIGHT delete mode 100644 rand_pcg/Cargo.toml delete mode 100644 rand_pcg/LICENSE-APACHE delete mode 100644 rand_pcg/LICENSE-MIT delete mode 100644 rand_pcg/README.md delete mode 100644 rand_pcg/src/lib.rs delete mode 100644 rand_pcg/src/pcg128.rs delete mode 100644 rand_pcg/src/pcg128cm.rs delete mode 100644 rand_pcg/src/pcg64.rs delete mode 100644 rand_pcg/tests/lcg128cmdxsm64.rs delete mode 100644 rand_pcg/tests/lcg128xsl64.rs delete mode 100644 rand_pcg/tests/lcg64xsh32.rs delete mode 100644 rand_pcg/tests/mcg128xsl64.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9a23a394ab..7bd7960d14c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,12 +14,6 @@ jobs: - uses: actions/checkout@v6 - uses: rust-lang/crates-io-auth-action@v1 id: auth - - name: Publish rand_pcg - working-directory: ./rand_pcg - run: cargo publish - env: - CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} - - name: Publish rand - run: cargo publish + - run: cargo publish env: CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} diff --git a/Cargo.lock b/Cargo.lock index d42a9aeb152..de417a5d940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,10 +257,10 @@ checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" [[package]] name = "rand_pcg" version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f761b1fee8839c9bcde7d2b2c93fe1cde409986b2978c8b31849f350e3f372b5" dependencies = [ - "postcard", "rand_core", - "serde", ] [[package]] @@ -365,9 +365,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-xid" @@ -523,6 +523,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" +checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" diff --git a/Cargo.toml b/Cargo.toml index 9dfcd6dcb03..55a1f2d8537 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,10 +62,7 @@ unbiased = [] log = ["dep:log"] [workspace] -members = [ - "rand_pcg", -] -exclude = ["benches", "distr_test"] +exclude = ["benches"] [dependencies] rand_core = { version = "0.10.0", default-features = false } @@ -75,7 +72,7 @@ chacha20 = { version = "0.10.0", default-features = false, features = ["rng"], o getrandom = { version = "0.4.0", optional = true } [dev-dependencies] -rand_pcg = { path = "rand_pcg", version = "0.10.0" } +rand_pcg = "0.10" # Only to test serde postcard = {version = "1.1.3", default-features = false, features = ["alloc"]} rayon = "1.7" diff --git a/benches/Cargo.toml b/benches/Cargo.toml index bf24b395437..e8f3de6c269 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -12,7 +12,7 @@ simd_support = ["rand/simd_support"] [dev-dependencies] rand = { path = ".." } -rand_pcg = { path = "../rand_pcg" } +rand_pcg = "0.10" chacha20 = { version = "0.10.0", default-features = false, features = ["rng"] } criterion = "0.5" criterion-cycles-per-byte = "0.6" diff --git a/rand_pcg/CHANGELOG.md b/rand_pcg/CHANGELOG.md deleted file mode 100644 index 0728129a809..00000000000 --- a/rand_pcg/CHANGELOG.md +++ /dev/null @@ -1,66 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.10.0] - 2026-02-08 -### Changes -- Use Edition 2024 and MSRV 1.85 (#1653) -- Update to `rand_core` v0.10.0 (#1729) -- Remove feature `os_rng` (#1674) -- Use `postcard` instead of `bincode` to test the serde feature (#1693) - -## [0.9.0] - 2025-01-27 -### Dependencies and features -- Update to `rand_core` v0.9.0 (#1558) -- Rename feature `serde1` to `serde` (#1477) -- Rename feature `getrandom` to `os_rng` (#1537) - -### Other changes -- Add `Lcg128CmDxsm64` generator compatible with NumPy's `PCG64DXSM` (#1202) -- Add examples for initializing the RNGs (#1352) -- Revise crate docs (#1454) - -## [0.3.1] - 2021-06-15 -- Add `advance` methods to RNGs (#1111) -- Document dependencies between streams (#1122) - -## [0.3.0] - 2020-12-08 -- Bump `rand_core` version to 0.6.0 -- Bump MSRV to 1.36 (#1011) -- Derive PartialEq+Eq for Lcg64Xsh32, Lcg128Xsl64, and Mcg128Xsl64 (#979) - -## [0.2.1] - 2019-10-22 -- Bump `bincode` version to 1.1.4 to fix minimal-dependency builds -- Removed unused `autocfg` build dependency. - -## [0.2.0] - 2019-06-12 -- Add `Lcg128Xsl64` aka `Pcg64` -- Bump minor crate version since rand_core bump is a breaking change -- Switch to Edition 2018 - -## [0.1.2] - 2019-02-23 -- require `bincode` 1.1.2 for i128 auto-detection -- make `bincode` a dev-dependency again #663 -- clean up tests and Serde support - -## [0.1.1] - 2018-10-04 -- make `bincode` an explicit dependency when using Serde - -## [0.1.0] - 2018-10-04 -Initial release, including: - -- `Lcg64Xsh32` aka `Pcg32` -- `Mcg128Xsl64` aka `Pcg64Mcg` - -[Unreleased]: https://github.com/rust-random/rand/compare/0.10.0...HEAD -[0.9.0]: https://github.com/rust-random/rand/compare/0.9.0...0.10.0 -[0.9.0]: https://github.com/rust-random/rand/compare/rand_pcg-0.3.1...0.9.0 -[0.3.1]: https://github.com/rust-random/rand/compare/rand_pcg-0.3.0...rand_pcg-0.3.1 -[0.3.0]: https://github.com/rust-random/rand/compare/rand_pcg-0.2.1...rand_pcg-0.3.0 -[0.2.1]: https://github.com/rust-random/rand/compare/rand_pcg-0.2.0...rand_pcg-0.2.1 -[0.2.0]: https://github.com/rust-random/rand/compare/rand_pcg-0.1.2...rand_pcg-0.2.0 -[0.1.2]: https://github.com/rust-random/rand/compare/6d9e7ac9c6980897d190ede70607f18501d99f3b...rand_pcg-0.1.2 -[0.1.1]: https://github.com/rust-random/small-rngs/compare/rand_pcg-0.1.0...rand_pcg-0.1.1 -[0.1.0]: https://github.com/rust-random/small-rngs/compare/8ae22ced3f1cfdb888e639f93ca24ef1ea5811c2...rand_pcg-0.1.0 diff --git a/rand_pcg/COPYRIGHT b/rand_pcg/COPYRIGHT deleted file mode 100644 index 468d907caf9..00000000000 --- a/rand_pcg/COPYRIGHT +++ /dev/null @@ -1,12 +0,0 @@ -Copyrights in the Rand project are retained by their contributors. No -copyright assignment is required to contribute to the Rand project. - -For full authorship information, see the version control history. - -Except as otherwise noted (below and/or in individual files), Rand is -licensed under the Apache License, Version 2.0 or - or the MIT license - or , at your option. - -The Rand project includes code from the Rust project -published under these same licenses. diff --git a/rand_pcg/Cargo.toml b/rand_pcg/Cargo.toml deleted file mode 100644 index 2a1ff2a45cf..00000000000 --- a/rand_pcg/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "rand_pcg" -version = "0.10.0" -authors = ["The Rand Project Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" -repository = "https://github.com/rust-random/rand" -documentation = "https://docs.rs/rand_pcg" -homepage = "https://rust-random.github.io/book" -description = """ -Selected PCG random number generators -""" -keywords = ["random", "rng", "pcg"] -categories = ["algorithms", "no-std"] -edition = "2024" -rust-version = "1.85" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--generate-link-to-definition"] - -[features] -serde = ["dep:serde"] - -[dependencies] -rand_core = { version = "0.10.0" } -serde = { version = "1", features = ["derive"], optional = true } - -[dev-dependencies] -# This is for testing serde, unfortunately we can't specify feature-gated dev -# deps yet, see: https://github.com/rust-lang/cargo/issues/1596 -postcard = {version = "1.1.3", default-features = false, features = ["alloc"]} diff --git a/rand_pcg/LICENSE-APACHE b/rand_pcg/LICENSE-APACHE deleted file mode 100644 index 455787c2334..00000000000 --- a/rand_pcg/LICENSE-APACHE +++ /dev/null @@ -1,187 +0,0 @@ - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. diff --git a/rand_pcg/LICENSE-MIT b/rand_pcg/LICENSE-MIT deleted file mode 100644 index d46f058e98c..00000000000 --- a/rand_pcg/LICENSE-MIT +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors -Copyright 2018 Developers of the Rand project - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/rand_pcg/README.md b/rand_pcg/README.md deleted file mode 100644 index ab4909bd17b..00000000000 --- a/rand_pcg/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# rand_pcg - -[![Test Status](https://github.com/rust-random/rand/actions/workflows/test.yml/badge.svg?event=push)](https://github.com/rust-random/rand/actions) -[![Latest version](https://img.shields.io/crates/v/rand_pcg.svg)](https://crates.io/crates/rand_pcg) -[![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/) -[![API](https://docs.rs/rand_pcg/badge.svg)](https://docs.rs/rand_pcg) - -Implements a selection of PCG random number generators. - -> PCG is a family of simple fast space-efficient statistically good algorithms -> for random number generation. [Melissa O'Neill, Harvey Mudd College, 2014]. - -The PCG algorithms are not suitable for cryptographic uses, but perform well -in statistical tests, use little memory and are fairly fast. -See the [pcg-random website](http://www.pcg-random.org/). - -This crate depends on [rand_core](https://crates.io/crates/rand_core) and is -part of the [Rand project](https://github.com/rust-random/rand). - -Links: - -- [API documentation (docs.rs)](https://docs.rs/rand_pcg) -- [Changelog](https://github.com/rust-random/rand/blob/master/rand_pcg/CHANGELOG.md) - - -## Crate Features - -`rand_pcg` is `no_std` compatible by default. - -The `serde` feature includes implementations of `Serialize` and `Deserialize` -for the included RNGs. - -## License - -`rand_pcg` is distributed under the terms of both the MIT license and the -Apache License (Version 2.0). - -See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT), and -[COPYRIGHT](COPYRIGHT) for details. diff --git a/rand_pcg/src/lib.rs b/rand_pcg/src/lib.rs deleted file mode 100644 index 3449d3a5691..00000000000 --- a/rand_pcg/src/lib.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2018-2023 Developers of the Rand project. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The PCG random number generators. -//! -//! This is a native Rust implementation of a small selection of [PCG generators]. -//! The primary goal of this crate is simple, minimal, well-tested code; in -//! other words it is explicitly not a goal to re-implement all of PCG. -//! -//! ## Generators -//! -//! This crate provides: -//! -//! - [`Pcg32`] aka [`Lcg64Xsh32`], officially known as `pcg32`, a general -//! purpose RNG. This is a good choice on both 32-bit and 64-bit CPUs -//! (for 32-bit output). -//! - [`Pcg64`] aka [`Lcg128Xsl64`], officially known as `pcg64`, a general -//! purpose RNG. This is a good choice on 64-bit CPUs. -//! - [`Pcg64Mcg`] aka [`Mcg128Xsl64`], officially known as `pcg64_fast`, -//! a general purpose RNG using 128-bit multiplications. This has poor -//! performance on 32-bit CPUs but is a good choice on 64-bit CPUs for -//! both 32-bit and 64-bit output. -//! -//! These generators are all deterministic and portable (see [Reproducibility] -//! in the book), with testing against reference vectors. -//! -//! ## Seeding (construction) -//! -//! Generators implement the [`SeedableRng`] trait. All methods are suitable for -//! seeding. Some suggestions: -//! -//! 1. To automatically seed with a unique seed, use [`SeedableRng::from_rng`] -//! with a master generator (here [`rand::rng()`](https://docs.rs/rand/latest/rand/fn.rng.html)): -//! ```ignore -//! use rand_core::SeedableRng; -//! use rand_pcg::Pcg64Mcg; -//! let rng = Pcg64Mcg::from_rng(&mut rand::rng()); -//! # let _: Pcg64Mcg = rng; -//! ``` -//! 2. Seed **from an integer** via `seed_from_u64`. This uses a hash function -//! internally to yield a (typically) good seed from any input. -//! ``` -//! # use {rand_core::SeedableRng, rand_pcg::Pcg64Mcg}; -//! let rng = Pcg64Mcg::seed_from_u64(1); -//! # let _: Pcg64Mcg = rng; -//! ``` -//! -//! See also [Seeding RNGs] in the book. -//! -//! ## Generation -//! -//! Generators implement [`Rng`], whose methods may be used directly to -//! generate unbounded integer or byte values. -//! ``` -//! use rand_core::{SeedableRng, Rng}; -//! use rand_pcg::Pcg64Mcg; -//! -//! let mut rng = Pcg64Mcg::seed_from_u64(0); -//! let x = rng.next_u64(); -//! assert_eq!(x, 0x5603f242407deca2); -//! ``` -//! -//! It is often more convenient to use the [`rand::Rng`] trait, which provides -//! further functionality. See also the [Random Values] chapter in the book. -//! -//! [PCG generators]: https://www.pcg-random.org/ -//! [Reproducibility]: https://rust-random.github.io/book/crate-reprod.html -//! [Seeding RNGs]: https://rust-random.github.io/book/guide-seeding.html -//! [Random Values]: https://rust-random.github.io/book/guide-values.html -//! [`Rng`]: rand_core::Rng -//! [`SeedableRng`]: rand_core::SeedableRng -//! [`SeedableRng::from_rng`]: rand_core::SeedableRng#method.from_rng -//! [`rand::rng`]: https://docs.rs/rand/latest/rand/fn.rng.html -//! [`rand::Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html - -#![doc( - html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", - html_favicon_url = "https://www.rust-lang.org/favicon.ico" -)] -#![forbid(unsafe_code)] -#![deny(missing_docs)] -#![deny(missing_debug_implementations)] -#![no_std] - -mod pcg128; -mod pcg128cm; -mod pcg64; - -pub use rand_core; - -pub use self::pcg64::{Lcg64Xsh32, Pcg32}; -pub use self::pcg128::{Lcg128Xsl64, Mcg128Xsl64, Pcg64, Pcg64Mcg}; -pub use self::pcg128cm::{Lcg128CmDxsm64, Pcg64Dxsm}; diff --git a/rand_pcg/src/pcg128.rs b/rand_pcg/src/pcg128.rs deleted file mode 100644 index 1428a050c38..00000000000 --- a/rand_pcg/src/pcg128.rs +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// Copyright 2017 Paul Dicker. -// Copyright 2014-2017 Melissa O'Neill and PCG Project contributors -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! PCG random number generators - -// This is the default multiplier used by PCG for 128-bit state. -const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645; - -use core::fmt; -use rand_core::{Infallible, SeedableRng, TryRng, utils}; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -/// A PCG random number generator (XSL RR 128/64 (LCG) variant). -/// -/// Permuted Congruential Generator with 128-bit state, internal Linear -/// Congruential Generator, and 64-bit output via "xorshift low (bits), -/// random rotation" output function. -/// -/// This is a 128-bit LCG with explicitly chosen stream with the PCG-XSL-RR -/// output function. This combination is the standard `pcg64`. -/// -/// Despite the name, this implementation uses 32 bytes (256 bit) space -/// comprising 128 bits of state and 128 bits stream selector. These are both -/// set by `SeedableRng`, using a 256-bit seed. -/// -/// Note that two generators with different stream parameters may be closely -/// correlated. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Lcg128Xsl64 { - state: u128, - increment: u128, -} - -/// [`Lcg128Xsl64`] is also officially known as `pcg64`. -pub type Pcg64 = Lcg128Xsl64; - -impl Lcg128Xsl64 { - /// Multi-step advance functions (jump-ahead, jump-back) - /// - /// The method used here is based on Brown, "Random Number Generation - /// with Arbitrary Stride,", Transactions of the American Nuclear - /// Society (Nov. 1994). The algorithm is very similar to fast - /// exponentiation. - /// - /// Even though delta is an unsigned integer, we can pass a - /// signed integer to go backwards, it just goes "the long way round". - /// - /// Using this function is equivalent to calling `next_64()` `delta` - /// number of times. - #[inline] - pub fn advance(&mut self, delta: u128) { - let mut acc_mult: u128 = 1; - let mut acc_plus: u128 = 0; - let mut cur_mult = MULTIPLIER; - let mut cur_plus = self.increment; - let mut mdelta = delta; - - while mdelta > 0 { - if (mdelta & 1) != 0 { - acc_mult = acc_mult.wrapping_mul(cur_mult); - acc_plus = acc_plus.wrapping_mul(cur_mult).wrapping_add(cur_plus); - } - cur_plus = cur_mult.wrapping_add(1).wrapping_mul(cur_plus); - cur_mult = cur_mult.wrapping_mul(cur_mult); - mdelta /= 2; - } - self.state = acc_mult.wrapping_mul(self.state).wrapping_add(acc_plus); - } - - /// Construct an instance compatible with PCG seed and stream. - /// - /// Note that the highest bit of the `stream` parameter is discarded - /// to simplify upholding internal invariants. - /// - /// Note that two generators with different stream parameters may be closely - /// correlated. - /// - /// PCG specifies the following default values for both parameters: - /// - /// - `state = 0xcafef00dd15ea5e5` - /// - `stream = 0xa02bdbf7bb3c0a7ac28fa16a64abf96` - pub fn new(state: u128, stream: u128) -> Self { - // The increment must be odd, hence we discard one bit: - let increment = (stream << 1) | 1; - Lcg128Xsl64::from_state_incr(state, increment) - } - - #[inline] - fn from_state_incr(state: u128, increment: u128) -> Self { - let mut pcg = Lcg128Xsl64 { state, increment }; - // Move away from initial value: - pcg.state = pcg.state.wrapping_add(pcg.increment); - pcg.step(); - pcg - } - - #[inline] - fn step(&mut self) { - // prepare the LCG for the next round - self.state = self - .state - .wrapping_mul(MULTIPLIER) - .wrapping_add(self.increment); - } -} - -// Custom Debug implementation that does not expose the internal state -impl fmt::Debug for Lcg128Xsl64 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Lcg128Xsl64 {{}}") - } -} - -impl SeedableRng for Lcg128Xsl64 { - type Seed = [u8; 32]; - - /// We use a single 255-bit seed to initialise the state and select a stream. - /// One `seed` bit (lowest bit of `seed[8]`) is ignored. - fn from_seed(seed: Self::Seed) -> Self { - let seed_u64: [u64; 4] = utils::read_words(&seed); - let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); - let incr = u128::from(seed_u64[2]) | (u128::from(seed_u64[3]) << 64); - - // The increment must be odd, hence we discard one bit: - Lcg128Xsl64::from_state_incr(state, incr | 1) - } -} - -impl TryRng for Lcg128Xsl64 { - type Error = Infallible; - - #[inline] - fn try_next_u32(&mut self) -> Result { - self.try_next_u64().map(|result| result as u32) - } - - #[inline] - fn try_next_u64(&mut self) -> Result { - self.step(); - Ok(output_xsl_rr(self.state)) - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Infallible> { - utils::fill_bytes_via_next_word(dest, || self.try_next_u64()) - } -} - -/// A PCG random number generator (XSL 128/64 (MCG) variant). -/// -/// Permuted Congruential Generator with 128-bit state, internal Multiplicative -/// Congruential Generator, and 64-bit output via "xorshift low (bits), -/// random rotation" output function. -/// -/// This is a 128-bit MCG with the PCG-XSL-RR output function, also known as -/// `pcg64_fast`. -/// Note that compared to the standard `pcg64` (128-bit LCG with PCG-XSL-RR -/// output function), this RNG is faster, also has a long cycle, and still has -/// good performance on statistical tests. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Mcg128Xsl64 { - state: u128, -} - -/// A friendly name for [`Mcg128Xsl64`] (also known as `pcg64_fast`). -pub type Pcg64Mcg = Mcg128Xsl64; - -impl Mcg128Xsl64 { - /// Multi-step advance functions (jump-ahead, jump-back) - /// - /// The method used here is based on Brown, "Random Number Generation - /// with Arbitrary Stride,", Transactions of the American Nuclear - /// Society (Nov. 1994). The algorithm is very similar to fast - /// exponentiation. - /// - /// Even though delta is an unsigned integer, we can pass a - /// signed integer to go backwards, it just goes "the long way round". - /// - /// Using this function is equivalent to calling `next_64()` `delta` - /// number of times. - #[inline] - pub fn advance(&mut self, delta: u128) { - let mut acc_mult: u128 = 1; - let mut acc_plus: u128 = 0; - let mut cur_mult = MULTIPLIER; - let mut cur_plus: u128 = 0; - let mut mdelta = delta; - - while mdelta > 0 { - if (mdelta & 1) != 0 { - acc_mult = acc_mult.wrapping_mul(cur_mult); - acc_plus = acc_plus.wrapping_mul(cur_mult).wrapping_add(cur_plus); - } - cur_plus = cur_mult.wrapping_add(1).wrapping_mul(cur_plus); - cur_mult = cur_mult.wrapping_mul(cur_mult); - mdelta /= 2; - } - self.state = acc_mult.wrapping_mul(self.state).wrapping_add(acc_plus); - } - - /// Construct an instance compatible with PCG seed. - /// - /// Note that PCG specifies a default value for the parameter: - /// - /// - `state = 0xcafef00dd15ea5e5` - pub fn new(state: u128) -> Self { - // Force low bit to 1, as in C version (C++ uses `state | 3` instead). - Mcg128Xsl64 { state: state | 1 } - } -} - -// Custom Debug implementation that does not expose the internal state -impl fmt::Debug for Mcg128Xsl64 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Mcg128Xsl64 {{}}") - } -} - -/// We use a single 126-bit seed to initialise the state and select a stream. -/// Two `seed` bits (lowest order of last byte) are ignored. -impl SeedableRng for Mcg128Xsl64 { - type Seed = [u8; 16]; - - fn from_seed(seed: Self::Seed) -> Self { - // Read as if a little-endian u128 value: - let seed_u64: [u64; 2] = utils::read_words(&seed); - let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); - Mcg128Xsl64::new(state) - } -} - -impl TryRng for Mcg128Xsl64 { - type Error = Infallible; - - #[inline] - fn try_next_u32(&mut self) -> Result { - self.try_next_u64().map(|result| result as u32) - } - - #[inline] - fn try_next_u64(&mut self) -> Result { - self.state = self.state.wrapping_mul(MULTIPLIER); - Ok(output_xsl_rr(self.state)) - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Infallible> { - utils::fill_bytes_via_next_word(dest, || self.try_next_u64()) - } -} - -#[inline(always)] -fn output_xsl_rr(state: u128) -> u64 { - // Output function XSL RR ("xorshift low (bits), random rotation") - // Constants are for 128-bit state, 64-bit output - const XSHIFT: u32 = 64; // (128 - 64 + 64) / 2 - const ROTATE: u32 = 122; // 128 - 6 - - let rot = (state >> ROTATE) as u32; - let xsl = ((state >> XSHIFT) as u64) ^ (state as u64); - xsl.rotate_right(rot) -} diff --git a/rand_pcg/src/pcg128cm.rs b/rand_pcg/src/pcg128cm.rs deleted file mode 100644 index c7d5776c3d9..00000000000 --- a/rand_pcg/src/pcg128cm.rs +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2018-2021 Developers of the Rand project. -// Copyright 2017 Paul Dicker. -// Copyright 2014-2017, 2019 Melissa O'Neill and PCG Project contributors -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! PCG random number generators - -// This is the cheap multiplier used by PCG for 128-bit state. -const MULTIPLIER: u64 = 15750249268501108917; - -use core::{convert::Infallible, fmt}; -use rand_core::{SeedableRng, TryRng, utils}; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -/// A PCG random number generator (CM DXSM 128/64 (LCG) variant). -/// -/// Permuted Congruential Generator with 128-bit state, internal Linear -/// Congruential Generator, and 64-bit output via "double xorshift multiply" -/// output function. -/// -/// This is a 128-bit LCG with explicitly chosen stream with the PCG-DXSM -/// output function. This corresponds to `pcg_engines::cm_setseq_dxsm_128_64` -/// from pcg_cpp and `PCG64DXSM` from NumPy. -/// -/// Despite the name, this implementation uses 32 bytes (256 bit) space -/// comprising 128 bits of state and 128 bits stream selector. These are both -/// set by `SeedableRng`, using a 256-bit seed. -/// -/// Note that while two generators with different stream parameter may be -/// closely correlated, this is [mitigated][upgrading-pcg64] by the DXSM output function. -/// -/// [upgrading-pcg64]: https://numpy.org/doc/stable/reference/random/upgrading-pcg64.html -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Lcg128CmDxsm64 { - state: u128, - increment: u128, -} - -/// [`Lcg128CmDxsm64`] is also known as `PCG64DXSM`. -pub type Pcg64Dxsm = Lcg128CmDxsm64; - -impl Lcg128CmDxsm64 { - /// Multi-step advance functions (jump-ahead, jump-back) - /// - /// The method used here is based on Brown, "Random Number Generation - /// with Arbitrary Stride,", Transactions of the American Nuclear - /// Society (Nov. 1994). The algorithm is very similar to fast - /// exponentiation. - /// - /// Even though delta is an unsigned integer, we can pass a - /// signed integer to go backwards, it just goes "the long way round". - /// - /// Using this function is equivalent to calling `next_64()` `delta` - /// number of times. - #[inline] - pub fn advance(&mut self, delta: u128) { - let mut acc_mult: u128 = 1; - let mut acc_plus: u128 = 0; - let mut cur_mult = MULTIPLIER as u128; - let mut cur_plus = self.increment; - let mut mdelta = delta; - - while mdelta > 0 { - if (mdelta & 1) != 0 { - acc_mult = acc_mult.wrapping_mul(cur_mult); - acc_plus = acc_plus.wrapping_mul(cur_mult).wrapping_add(cur_plus); - } - cur_plus = cur_mult.wrapping_add(1).wrapping_mul(cur_plus); - cur_mult = cur_mult.wrapping_mul(cur_mult); - mdelta /= 2; - } - self.state = acc_mult.wrapping_mul(self.state).wrapping_add(acc_plus); - } - - /// Construct an instance compatible with PCG seed and stream. - /// - /// Note that the highest bit of the `stream` parameter is discarded - /// to simplify upholding internal invariants. - /// - /// Note that while two generators with different stream parameter may be - /// closely correlated, this is [mitigated][upgrading-pcg64] by the DXSM output function. - /// - /// PCG specifies the following default values for both parameters: - /// - /// - `state = 0xcafef00dd15ea5e5` - /// - `stream = 0xa02bdbf7bb3c0a7ac28fa16a64abf96` - /// - /// [upgrading-pcg64]: https://numpy.org/doc/stable/reference/random/upgrading-pcg64.html - pub fn new(state: u128, stream: u128) -> Self { - // The increment must be odd, hence we discard one bit: - let increment = (stream << 1) | 1; - Self::from_state_incr(state, increment) - } - - #[inline] - fn from_state_incr(state: u128, increment: u128) -> Self { - let mut pcg = Self { state, increment }; - // Move away from initial value: - pcg.state = pcg.state.wrapping_add(pcg.increment); - pcg.step(); - pcg - } - - #[inline(always)] - fn step(&mut self) { - // prepare the LCG for the next round - self.state = self - .state - .wrapping_mul(MULTIPLIER as u128) - .wrapping_add(self.increment); - } -} - -// Custom Debug implementation that does not expose the internal state -impl fmt::Debug for Lcg128CmDxsm64 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Lcg128CmDxsm64 {{}}") - } -} - -impl SeedableRng for Lcg128CmDxsm64 { - type Seed = [u8; 32]; - - /// We use a single 255-bit seed to initialise the state and select a stream. - /// One `seed` bit (lowest bit of `seed[8]`) is ignored. - fn from_seed(seed: Self::Seed) -> Self { - let seed_u64: [u64; 4] = utils::read_words(&seed); - let state = u128::from(seed_u64[0]) | (u128::from(seed_u64[1]) << 64); - let incr = u128::from(seed_u64[2]) | (u128::from(seed_u64[3]) << 64); - - // The increment must be odd, hence we discard one bit: - Self::from_state_incr(state, incr | 1) - } -} - -impl TryRng for Lcg128CmDxsm64 { - type Error = Infallible; - - #[inline] - fn try_next_u32(&mut self) -> Result { - self.try_next_u64().map(|result| result as u32) - } - - #[inline] - fn try_next_u64(&mut self) -> Result { - let res = output_dxsm(self.state); - self.step(); - Ok(res) - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Infallible> { - utils::fill_bytes_via_next_word(dest, || self.try_next_u64()) - } -} - -#[inline(always)] -fn output_dxsm(state: u128) -> u64 { - // See https://github.com/imneme/pcg-cpp/blob/ffd522e7188bef30a00c74dc7eb9de5faff90092/include/pcg_random.hpp#L1016 - // for a short discussion of the construction and its original implementation. - let mut hi = (state >> 64) as u64; - let mut lo = state as u64; - - lo |= 1; - hi ^= hi >> 32; - hi = hi.wrapping_mul(MULTIPLIER); - hi ^= hi >> 48; - hi = hi.wrapping_mul(lo); - - hi -} diff --git a/rand_pcg/src/pcg64.rs b/rand_pcg/src/pcg64.rs deleted file mode 100644 index 7a936c7195a..00000000000 --- a/rand_pcg/src/pcg64.rs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// Copyright 2017 Paul Dicker. -// Copyright 2014-2017 Melissa O'Neill and PCG Project contributors -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! PCG random number generators - -use core::{convert::Infallible, fmt}; -use rand_core::{SeedableRng, TryRng, utils}; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -// This is the default multiplier used by PCG for 64-bit state. -const MULTIPLIER: u64 = 6364136223846793005; - -/// A PCG random number generator (XSH RR 64/32 (LCG) variant). -/// -/// Permuted Congruential Generator with 64-bit state, internal Linear -/// Congruential Generator, and 32-bit output via "xorshift high (bits), -/// random rotation" output function. -/// -/// This is a 64-bit LCG with explicitly chosen stream with the PCG-XSH-RR -/// output function. This combination is the standard `pcg32`. -/// -/// Despite the name, this implementation uses 16 bytes (128 bit) space -/// comprising 64 bits of state and 64 bits stream selector. These are both set -/// by `SeedableRng`, using a 128-bit seed. -/// -/// Note that two generators with different stream parameter may be closely -/// correlated. -#[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct Lcg64Xsh32 { - state: u64, - increment: u64, -} - -/// [`Lcg64Xsh32`] is also officially known as `pcg32`. -pub type Pcg32 = Lcg64Xsh32; - -impl Lcg64Xsh32 { - /// Multi-step advance functions (jump-ahead, jump-back) - /// - /// The method used here is based on Brown, "Random Number Generation - /// with Arbitrary Stride,", Transactions of the American Nuclear - /// Society (Nov. 1994). The algorithm is very similar to fast - /// exponentiation. - /// - /// Even though delta is an unsigned integer, we can pass a - /// signed integer to go backwards, it just goes "the long way round". - /// - /// Using this function is equivalent to calling `next_32()` `delta` - /// number of times. - #[inline] - pub fn advance(&mut self, delta: u64) { - let mut acc_mult: u64 = 1; - let mut acc_plus: u64 = 0; - let mut cur_mult = MULTIPLIER; - let mut cur_plus = self.increment; - let mut mdelta = delta; - - while mdelta > 0 { - if (mdelta & 1) != 0 { - acc_mult = acc_mult.wrapping_mul(cur_mult); - acc_plus = acc_plus.wrapping_mul(cur_mult).wrapping_add(cur_plus); - } - cur_plus = cur_mult.wrapping_add(1).wrapping_mul(cur_plus); - cur_mult = cur_mult.wrapping_mul(cur_mult); - mdelta /= 2; - } - self.state = acc_mult.wrapping_mul(self.state).wrapping_add(acc_plus); - } - - /// Construct an instance compatible with PCG seed and stream. - /// - /// Note that the highest bit of the `stream` parameter is discarded - /// to simplify upholding internal invariants. - /// - /// Note that two generators with different stream parameters may be closely - /// correlated. - /// - /// PCG specifies the following default values for both parameters: - /// - /// - `state = 0xcafef00dd15ea5e5` - /// - `stream = 0xa02bdbf7bb3c0a7` - // Note: stream is 1442695040888963407u64 >> 1 - pub fn new(state: u64, stream: u64) -> Self { - // The increment must be odd, hence we discard one bit: - let increment = (stream << 1) | 1; - Lcg64Xsh32::from_state_incr(state, increment) - } - - #[inline] - fn from_state_incr(state: u64, increment: u64) -> Self { - let mut pcg = Lcg64Xsh32 { state, increment }; - // Move away from initial value: - pcg.state = pcg.state.wrapping_add(pcg.increment); - pcg.step(); - pcg - } - - #[inline] - fn step(&mut self) { - // prepare the LCG for the next round - self.state = self - .state - .wrapping_mul(MULTIPLIER) - .wrapping_add(self.increment); - } -} - -// Custom Debug implementation that does not expose the internal state -impl fmt::Debug for Lcg64Xsh32 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Lcg64Xsh32 {{}}") - } -} - -impl SeedableRng for Lcg64Xsh32 { - type Seed = [u8; 16]; - - /// We use a single 127-bit seed to initialise the state and select a stream. - /// One `seed` bit (lowest bit of `seed[8]`) is ignored. - fn from_seed(seed: Self::Seed) -> Self { - let seed_u64: [u64; 2] = utils::read_words(&seed); - - // The increment must be odd, hence we discard one bit: - Lcg64Xsh32::from_state_incr(seed_u64[0], seed_u64[1] | 1) - } -} - -impl TryRng for Lcg64Xsh32 { - type Error = Infallible; - - #[inline] - fn try_next_u32(&mut self) -> Result { - let state = self.state; - self.step(); - - // Output function XSH RR: xorshift high (bits), followed by a random rotate - // Constants are for 64-bit state, 32-bit output - const ROTATE: u32 = 59; // 64 - 5 - const XSHIFT: u32 = 18; // (5 + 32) / 2 - const SPARE: u32 = 27; // 64 - 32 - 5 - - let rot = (state >> ROTATE) as u32; - let xsh = (((state >> XSHIFT) ^ state) >> SPARE) as u32; - Ok(xsh.rotate_right(rot)) - } - - #[inline] - fn try_next_u64(&mut self) -> Result { - utils::next_u64_via_u32(self) - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Infallible> { - utils::fill_bytes_via_next_word(dest, || self.try_next_u32()); - Ok(()) - } -} diff --git a/rand_pcg/tests/lcg128cmdxsm64.rs b/rand_pcg/tests/lcg128cmdxsm64.rs deleted file mode 100644 index f642e41fb7a..00000000000 --- a/rand_pcg/tests/lcg128cmdxsm64.rs +++ /dev/null @@ -1,72 +0,0 @@ -use rand_core::{Rng, SeedableRng}; -use rand_pcg::{Lcg128CmDxsm64, Pcg64Dxsm}; - -#[test] -fn test_lcg128cmdxsm64_advancing() { - for seed in 0..20 { - let mut rng1 = Lcg128CmDxsm64::seed_from_u64(seed); - let mut rng2 = rng1.clone(); - for _ in 0..20 { - rng1.next_u64(); - } - rng2.advance(20); - assert_eq!(rng1, rng2); - } -} - -#[test] -fn test_lcg128cmdxsm64_construction() { - // Test that various construction techniques produce a working RNG. - #[rustfmt::skip] - let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16, - 17,18,19,20, 21,22,23,24, 25,26,27,28, 29,30,31,32]; - let mut rng1 = Lcg128CmDxsm64::from_seed(seed); - assert_eq!(rng1.next_u64(), 12201417210360370199); - - let mut rng2 = Lcg128CmDxsm64::from_rng(&mut rng1); - assert_eq!(rng2.next_u64(), 11487972556150888383); - - let mut rng3 = Lcg128CmDxsm64::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 4111470453933123814); - - // This is the same as Lcg128CmDxsm64, so we only have a single test: - let mut rng4 = Pcg64Dxsm::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 4111470453933123814); -} - -#[test] -fn test_lcg128cmdxsm64_reference() { - // Numbers determined using `pcg_engines::cm_setseq_dxsm_128_64` from pcg-cpp. - let mut rng = Lcg128CmDxsm64::new(42, 54); - - let mut results = [0u64; 6]; - for i in results.iter_mut() { - *i = rng.next_u64(); - } - let expected: [u64; 6] = [ - 17331114245835578256, - 10267467544499227306, - 9726600296081716989, - 10165951391103677450, - 12131334649314727261, - 10134094537930450875, - ]; - assert_eq!(results, expected); -} - -#[cfg(feature = "serde")] -#[test] -fn test_lcg128cmdxsm64_serde() { - use postcard; - - let mut rng = Lcg128CmDxsm64::seed_from_u64(0); - - let buf = postcard::to_allocvec(&rng).expect("Could not serialize"); - - let mut deserialized: Lcg128CmDxsm64 = - postcard::from_bytes(&buf).expect("Could not deserialize"); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } -} diff --git a/rand_pcg/tests/lcg128xsl64.rs b/rand_pcg/tests/lcg128xsl64.rs deleted file mode 100644 index 268739b4868..00000000000 --- a/rand_pcg/tests/lcg128xsl64.rs +++ /dev/null @@ -1,71 +0,0 @@ -use rand_core::{Rng, SeedableRng}; -use rand_pcg::{Lcg128Xsl64, Pcg64}; - -#[test] -fn test_lcg128xsl64_advancing() { - for seed in 0..20 { - let mut rng1 = Lcg128Xsl64::seed_from_u64(seed); - let mut rng2 = rng1.clone(); - for _ in 0..20 { - rng1.next_u64(); - } - rng2.advance(20); - assert_eq!(rng1, rng2); - } -} - -#[test] -fn test_lcg128xsl64_construction() { - // Test that various construction techniques produce a working RNG. - #[rustfmt::skip] - let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16, - 17,18,19,20, 21,22,23,24, 25,26,27,28, 29,30,31,32]; - let mut rng1 = Lcg128Xsl64::from_seed(seed); - assert_eq!(rng1.next_u64(), 8740028313290271629); - - let mut rng2 = Lcg128Xsl64::from_rng(&mut rng1); - assert_eq!(rng2.next_u64(), 1922280315005786345); - - let mut rng3 = Lcg128Xsl64::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 2354861276966075475); - - // This is the same as Lcg128Xsl64, so we only have a single test: - let mut rng4 = Pcg64::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 2354861276966075475); -} - -#[test] -fn test_lcg128xsl64_reference() { - // Numbers copied from official test suite (C version). - let mut rng = Lcg128Xsl64::new(42, 54); - - let mut results = [0u64; 6]; - for i in results.iter_mut() { - *i = rng.next_u64(); - } - let expected: [u64; 6] = [ - 0x86b1da1d72062b68, - 0x1304aa46c9853d39, - 0xa3670e9e0dd50358, - 0xf9090e529a7dae00, - 0xc85b9fd837996f2c, - 0x606121f8e3919196, - ]; - assert_eq!(results, expected); -} - -#[cfg(feature = "serde")] -#[test] -fn test_lcg128xsl64_serde() { - use postcard; - - let mut rng = Lcg128Xsl64::seed_from_u64(0); - - let buf = postcard::to_allocvec(&rng).expect("Could not serialize"); - - let mut deserialized: Lcg128Xsl64 = postcard::from_bytes(&buf).expect("Could not deserialize"); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } -} diff --git a/rand_pcg/tests/lcg64xsh32.rs b/rand_pcg/tests/lcg64xsh32.rs deleted file mode 100644 index 14302be9ab7..00000000000 --- a/rand_pcg/tests/lcg64xsh32.rs +++ /dev/null @@ -1,63 +0,0 @@ -use rand_core::{Rng, SeedableRng}; -use rand_pcg::{Lcg64Xsh32, Pcg32}; - -#[test] -fn test_lcg64xsh32_advancing() { - for seed in 0..20 { - let mut rng1 = Lcg64Xsh32::seed_from_u64(seed); - let mut rng2 = rng1.clone(); - for _ in 0..20 { - rng1.next_u32(); - } - rng2.advance(20); - assert_eq!(rng1, rng2); - } -} - -#[test] -fn test_lcg64xsh32_construction() { - // Test that various construction techniques produce a working RNG. - let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let mut rng1 = Lcg64Xsh32::from_seed(seed); - assert_eq!(rng1.next_u64(), 1204678643940597513); - - let mut rng2 = Lcg64Xsh32::from_rng(&mut rng1); - assert_eq!(rng2.next_u64(), 12384929573776311845); - - let mut rng3 = Lcg64Xsh32::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 18195738587432868099); - - // This is the same as Lcg64Xsh32, so we only have a single test: - let mut rng4 = Pcg32::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 18195738587432868099); -} - -#[test] -fn test_lcg64xsh32_reference() { - // Numbers copied from official test suite. - let mut rng = Lcg64Xsh32::new(42, 54); - - let mut results = [0u32; 6]; - for i in results.iter_mut() { - *i = rng.next_u32(); - } - let expected: [u32; 6] = [ - 0xa15c02b7, 0x7b47f409, 0xba1d3330, 0x83d2f293, 0xbfa4784b, 0xcbed606e, - ]; - assert_eq!(results, expected); -} - -#[cfg(feature = "serde")] -#[test] -fn test_lcg64xsh32_serde() { - use postcard; - let mut rng = Lcg64Xsh32::seed_from_u64(0); - - let buf = postcard::to_allocvec(&rng).expect("Could not serialize"); - - let mut deserialized: Lcg64Xsh32 = postcard::from_bytes(&buf).expect("Could not deserialize"); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } -} diff --git a/rand_pcg/tests/mcg128xsl64.rs b/rand_pcg/tests/mcg128xsl64.rs deleted file mode 100644 index f70e6e4792f..00000000000 --- a/rand_pcg/tests/mcg128xsl64.rs +++ /dev/null @@ -1,69 +0,0 @@ -use rand_core::{Rng, SeedableRng}; -use rand_pcg::{Mcg128Xsl64, Pcg64Mcg}; - -#[test] -fn test_mcg128xsl64_advancing() { - for seed in 0..20 { - let mut rng1 = Mcg128Xsl64::seed_from_u64(seed); - let mut rng2 = rng1.clone(); - for _ in 0..20 { - rng1.next_u64(); - } - rng2.advance(20); - assert_eq!(rng1, rng2); - } -} - -#[test] -fn test_mcg128xsl64_construction() { - // Test that various construction techniques produce a working RNG. - let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let mut rng1 = Mcg128Xsl64::from_seed(seed); - assert_eq!(rng1.next_u64(), 7071994460355047496); - - let mut rng2 = Mcg128Xsl64::from_rng(&mut rng1); - assert_eq!(rng2.next_u64(), 12300796107712034932); - - let mut rng3 = Mcg128Xsl64::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 6198063878555692194); - - // This is the same as Mcg128Xsl64, so we only have a single test: - let mut rng4 = Pcg64Mcg::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 6198063878555692194); -} - -#[test] -fn test_mcg128xsl64_reference() { - // Numbers copied from official test suite (C version). - let mut rng = Mcg128Xsl64::new(42); - - let mut results = [0u64; 6]; - for i in results.iter_mut() { - *i = rng.next_u64(); - } - let expected: [u64; 6] = [ - 0x63b4a3a813ce700a, - 0x382954200617ab24, - 0xa7fd85ae3fe950ce, - 0xd715286aa2887737, - 0x60c92fee2e59f32c, - 0x84c4e96beff30017, - ]; - assert_eq!(results, expected); -} - -#[cfg(feature = "serde")] -#[test] -fn test_mcg128xsl64_serde() { - use postcard; - - let mut rng = Mcg128Xsl64::seed_from_u64(0); - - let buf = postcard::to_allocvec(&rng).expect("Could not serialize"); - - let mut deserialized: Mcg128Xsl64 = postcard::from_bytes(&buf).expect("Could not deserialize"); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } -} From b8c99c4563e9c86a7c3f03d79b370c85036e89c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 9 Feb 2026 18:01:48 +0300 Subject: [PATCH 2/2] fix ci --- .github/workflows/test.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 005296492ff..b6b5b0985cf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -58,8 +58,6 @@ jobs: uses: dtolnay/rust-toolchain@nightly - name: rand run: cargo doc --all-features --no-deps - - name: rand_pcg - run: cargo doc --all-features --package rand_pcg --no-deps test: runs-on: ${{ matrix.os }} @@ -121,8 +119,6 @@ jobs: - name: Test rand (all stable features) run: | cargo test --target ${{ matrix.target }} --features=serde,log - - name: Test rand_pcg - run: cargo test --target ${{ matrix.target }} --manifest-path rand_pcg/Cargo.toml --features=serde test-cross: runs-on: ${{ matrix.os }} @@ -153,7 +149,6 @@ jobs: # all stable features: cross test --no-fail-fast --target ${{ matrix.target }} --features=serde,log cross test --no-fail-fast --target ${{ matrix.target }} --examples - cross test --no-fail-fast --target ${{ matrix.target }} --manifest-path rand_pcg/Cargo.toml --features=serde test-miri: runs-on: ubuntu-latest @@ -168,7 +163,6 @@ jobs: run: | cargo miri test --no-default-features --lib --tests cargo miri test --features=log - cargo miri test --manifest-path rand_pcg/Cargo.toml --features=serde test-no-std: runs-on: ubuntu-latest