Repository navigation
Conversation
…e random methods, docs and tests ### Motivation - Ensure in-place randomization for `UniTensor` is performed via its instance methods instead of allowing the `random` submodule functions to accept `UniTensor` objects. - Align Python bindings and type stubs with the intended API surface by removing `UniTensor` overloads from the `random` module. ### Description - Removed `UniTensor` overloads from the `random` typing stub file `cytnx/cytnx/random.pyi` so `normal_` and `uniform_` are no longer typed to accept `UniTensor`. - Deleted the `UniTensor` bindings for `normal_` and `uniform_` from `pybind/random_py.cpp`, leaving bindings for `Tensor` and `Storage` only. - Updated the example in `docs/code/python/doc_codes/guide_uniten_create_from_generator.py` to demonstrate the `UniTensor` instance methods `normal_()` and `uniform_()` for in-place randomization. - Added unit tests in `pytests/random_test.py` verifying that `UniTensor.normal_()` and `UniTensor.uniform_()` randomize in place and that calling `cytnx.random.normal[_]` and `cytnx.random.uniform[_]` with a `UniTensor` raises `TypeError`. ### Testing - Ran the new tests in `pytests/random_test.py` with `pytest`, and all tests passed. - The new tests cover in-place randomization for `UniTensor` and enforcement that the `random` module functions reject `UniTensor` inputs, and they succeeded.
There was a problem hiding this comment.
Code Review
This pull request removes the normal_ and uniform_ functions for UniTensor from the random module bindings and type stubs, as they are now implemented as in-place methods on the UniTensor class. It also adds documentation examples and comprehensive unit tests for these in-place methods on both dense and block UniTensor instances. The review feedback highlights a style guide violation regarding the use of leading underscores in new helper functions, and recommends using np.testing.assert_allclose instead of np.testing.assert_array_equal for floating-point comparisons to prevent flaky tests.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 587567f1a6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1074 +/- ##
==========================================
+ Coverage 69.43% 69.47% +0.04%
==========================================
Files 209 209
Lines 22614 22616 +2
Branches 72 72
==========================================
+ Hits 15701 15713 +12
+ Misses 6891 6881 -10
Partials 22 22
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
…or randomization docs and tests ### Motivation - Avoid duplicate bindings for UniTensor instances by removing module-level normal_ and uniform_ overloads and document the intended in-place APIs on UniTensor. - Ensure block UniTensor in-place randomization uses different seeded streams per block while remaining reproducible for a given seed. ### Description - Removed normal_ and uniform_ UniTensor overload bindings from pybind/random_py.cpp so only Tensor/Storage module-level overloads remain. - Updated type stubs in cytnx/cytnx/random.pyi to drop UniTensor overloads for normal_ and uniform_. - Added example usage to docs/code/python/doc_codes/guide_uniten_create_from_generator.py showing in-place calls UniTensor.normal_(...) and UniTensor.uniform_(...) on existing UniTensor instances. - Updated UniTensor::normal_ and UniTensor::uniform_ so block UniTensors pass seed + block_index to each block randomization call. - Added unit tests in pytests/unitensor_random_test.py that verify same-seed reproducibility for dense and block UniTensor normal_/uniform_ without hard-coded std::distribution-dependent values, and verify uniform_ produces distinct block values. ### Testing - pre-commit run --files src/UniTensor.cpp pytests/unitensor_random_test.py cytnx/cytnx/random.pyi docs/code/python/doc_codes/guide_uniten_create_from_generator.py pybind/random_py.cpp - .claude/skills/build-test-workflow/scripts/build_preset.sh openblas-cpu --target pycytnx - source build/openblas-cpu-venv/bin/activate && pytest pytests/unitensor_random_test.py -q - git diff --check Co-Authored-By: OpenAI Codex <codex@openai.com>
### Motivation - Keep the per-block seed offset for UniTensor in-place randomization so block tensors receive deterministic but distinct streams. - Restore the Python random module in-place APIs for UniTensor after review feedback, while keeping out-of-place random construction shape-based. - Document both supported in-place entry points and cover the restored bindings with regression tests. ### Description - Re-added pybind overloads for cytnx.random.normal_(UniTensor, ...) and cytnx.random.uniform_(UniTensor, ...), forwarding to the existing C++ in-place UniTensor randomizers. - Restored UniTensor overloads in cytnx.random type stubs. - Kept cytnx.random.normal(UniTensor, ...) and cytnx.random.uniform(UniTensor, ...) absent, so only in-place module functions accept UniTensor templates. - Updated the UniTensor generator guide to mention both instance-method and cytnx.random module in-place randomization. - Added regression coverage that checks the restored module-level UniTensor APIs match the instance-method behavior. ### Testing - pre-commit run --files pybind/random_py.cpp cytnx/cytnx/random.pyi docs/code/python/doc_codes/guide_uniten_create_from_generator.py pytests/unitensor_random_test.py - git submodule update --init --recursive - apt-get update && apt-get install -y --fix-missing libboost-dev libopenblas-dev liblapacke-dev libarpack2-dev libgtest-dev libgmock-dev libbenchmark-dev - .claude/skills/build-test-workflow/scripts/build_preset.sh openblas-cpu --target pycytnx - source build/openblas-cpu-venv/bin/activate && pytest pytests/unitensor_random_test.py -q && git diff --check Co-Authored-By: Codex <codex@openai.com>
### Motivation - Keep the per-block seed offset for UniTensor in-place randomization so block tensors receive deterministic but distinct streams. - Keep the Python random module in-place APIs for UniTensor available after review feedback, while leaving out-of-place random construction shape-based. - Document both supported in-place entry points and stabilize the Arnoldi block-UniTensor regression affected by the random-stream change. ### Description - Kept pybind overloads for cytnx.random.normal_(UniTensor, ...) and cytnx.random.uniform_(UniTensor, ...), forwarding to the existing C++ in-place UniTensor randomizers. - Restored UniTensor overloads in cytnx.random type stubs. - Kept cytnx.random.normal(UniTensor, ...) and cytnx.random.uniform(UniTensor, ...) absent, so only in-place module functions accept UniTensor templates. - Updated the UniTensor generator guide to demonstrate instance normal_ and module-level cytnx.random.uniform_ in-place randomization. - Added regression coverage that checks the restored module-level UniTensor APIs match the instance-method behavior. - Tightened Arnoldi_Gnd.Arnoldi_BK_test convergence settings and replaced boolean comparison assertions with EXPECT_NEAR/EXPECT_LT. ### Testing - cmake --build --preset openblas-cpu --target test_main -- -j3 - build/openblas-cpu/tests/test_main --gtest_filter=Arnoldi_Gnd.Arnoldi_BK_test - pre-commit run --files docs/code/python/doc_codes/guide_uniten_create_from_generator.py tests/linalg_test/Arnoldi_Ut_test.cpp - source build/openblas-cpu-venv/bin/activate && pytest pytests/unitensor_random_test.py -q && git diff --check Co-Authored-By: Codex <codex@openai.com>
…ibution funtions Add examples about initializing UniTensor with: - cytnx.random.normal_(unitensor, ...) - unitensor.normal_(...) - cytnx.random.uniform_(unitensor, ...) - unitensor.uniform_(...)
…rion The previous commit set max iterations too high and convergence criterion too small. We don't need to go that extreme to pass the test.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61d36ee422
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
(This was posted by Codex after review by @ianmccul - the codex attribution was missing from the original posting) A few comments after looking at the current end state of this PR. The Arnoldi test changeThe modified Also, explicitly setting For context, the other helper in this file, It would be better for the Arnoldi fixture to contain fixed data rather than depend on the precise random streams used by an unrelated randomization API test. Scope and implementationThe current diff no longer matches the PR title/body: it does not remove the module-level UniTensor overloads. It aligns the member The duplicated implementation should be removed rather than synchronized manually. One of UniTensor::uniform_()
random::uniform_(UniTensor&)should forward to the other, and likewise for Testing the distributionsExact equality between two calls using the same seed is appropriate for testing reproducibility; A robust alternative is to retain the exact reproducibility tests and add large-sample property tests. For example, use a dense Double UniTensor with shape def assert_distribution(values, expected_mean, expected_variance,
variance_se_factor, expected_kurtosis):
x = np.asarray(values).ravel()
n = x.size
sample_mean = x.mean()
sample_variance = x.var(ddof=1)
mean_tol = 8.0 * np.sqrt(expected_variance / n)
variance_tol = (
8.0 * expected_variance * np.sqrt(variance_se_factor / n)
)
assert abs(sample_mean - expected_mean) < mean_tol
assert abs(sample_variance - expected_variance) < variance_tol
centered = x - sample_mean
sample_kurtosis = np.mean(centered**4) / np.mean(centered**2) ** 2
assert abs(sample_kurtosis - expected_kurtosis) < 0.25For At this sample size those are deliberately generous tolerances, robust across different valid random streams, while still reliably detecting an ignored range, wrong scale, no-op fill, or wrong distribution family. The small block-UniTensor tests can then concentrate on exact same-seed reproducibility, valid uniform bounds, and ensuring equal-sized blocks do not receive identical streams. |
|
Follow-up with concrete tolerances for the proposed statistical tests. For For
I would round these upward and use: assert np.all(values >= -3.0)
assert np.all(values <= 7.0)
assert abs(values.mean() - 2.0) < 0.10
assert abs(values.var(ddof=1) - 100.0 / 12.0) < 0.25
assert abs(sample_kurtosis(values) - 1.8) < 0.25For
Again rounding upward: assert abs(values.mean() - 2.0) < 0.10
assert abs(values.var(ddof=1) - 9.0) < 0.40
assert abs(sample_kurtosis(values) - 3.0) < 0.25where def sample_kurtosis(values):
x = np.asarray(values).ravel()
centered = x - x.mean()
return np.mean(centered**4) / np.mean(centered**2) ** 2These tolerances are intentionally much wider than ordinary sampling fluctuations. They should be robust across standard-library RNG implementations while still failing clearly if the parameters are ignored, the fill is a no-op, the scaling is wrong, or normal and uniform distributions are confused. Exact same-seed equality should remain a separate reproducibility assertion. — Codex |
cytnx.random.uniform and cytnx.random.normal had no Python test coverage. Add pytests/random_distribution_test.py, which draws large samples (500k elements) and checks them against independent scipy.stats references rather than another cytnx code path: - uniform: boundary containment (samples stay within [low, high)) and a Kolmogorov-Smirnov test of marginal uniformity. - normal: a Cramer-von Mises CDF test, a Kolmogorov-Smirnov test, and a chi-square test over z-score tail bins. Each parametrization's seed is fixed and was chosen so every check passes at alpha=1e-6. Add scipy to the `test` optional-dependency group in pyproject.toml since these goodness-of-fit tests need it. Co-Authored-By: Claude <noreply@anthropic.com>
|
Conflict in tests/linalg_test/Arnoldi_Ut_test.cpp: master moved the whole file into the `cytnx::test::` anonymous namespace and renamed the gtest suite/case from `Arnoldi_Gnd, Arnoldi_BK_test` to `ArnoldiGnd, ArnoldiBKTest`, while this branch changed the body of that same test. Resolved by keeping master's namespacing/indentation and re-applying this branch's body changes on top: - iterate `exact_eigs[0].get_blocks_()` as `const Tensor&` instead of `auto&` - pass explicit `maxiter = 10000` and `cvg_crit = 1e-12` to `linalg::Arnoldi`, which the test needs now that `UniTensor::uniform_` rotates the seed per block and each block no longer repeats the same random sequence - use `EXPECT_NEAR`/`EXPECT_LT` in place of `EXPECT_TRUE` on a comparison Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4f9e4183ec
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Review by Codex, after discussion with @ianmccul. I reviewed this more broadly because the existing RNG implementation has important consequences for what Findings1.
|
|
@ianmccul Thank you for reviewing. The points 1-5 are good and make Cytnx better, but they are out of scope of this'll PR. We can open issues for them. For the sixth point about reproducibility, this PR tests on the current python interface by this file pytests/unitensor_random_test.py. We cannot test the reproducibility with one seed by until we implement the generator mechanism like numpy. |
|
Posted by Claude Code on behalf of @pcchen @ianmccul @IvanaGyro We checked the points raised in the review comments above against master Fix before v2.0.0
Deferred to after v2.0.0
These change seeded output and the API. They will not be ready for v2.0.0, so v2.0.0 will document that seeded output is not guaranteed stable across versions or platforms. That leaves room to make the change in a 2.x release. Can wait
Proposal for this PR1. Scope: this PR fixes #679 and nothing more. 2. Changes requested before merge.
3. Merge mechanics.
4. This is not the final RNG fix. 5. Release note for v2.0.0. 6. Follow-ups, each as its own issue. We will open them.
|
test_block_unitensor_normal_same_seed_is_reproducible passed on the unfixed code because it only compared two same-seed calls. Add the distinct-blocks assertion the uniform_ test already has, so the normal_ half of the #679 fix has a regression guard. Verified on hotrg-2 (openblas-cpu): the test fails on master c7fda0a and passes with the src/UniTensor.cpp change in this PR. Co-Authored-By: Claude <noreply@anthropic.com>
Motivation
In-place
blockunitensor.uniform_andblockunitensor.normal_didn't rotate seed while generating random numbers per block, which leads the values per block use the same sequence.Description
random.uniform_andrandom.normal_.docs/code/python/doc_codes/guide_uniten_create_from_generator.pyshowing in-place and global alls on existingUniTensorinstances.pytests/unitensor_random_test.pythat verify deterministic, seeded behavior for both dense and blockUniTensorusingnormal_anduniform_.Arnoldi_BK_testsmaller to pass the test. The test was wrongly passed with all blocks using the same random sequence.Testing
pytests/unitensor_random_test.pyviapytest, and the tests passed for the seeded deterministic checks ofUniTensor.normal_andUniTensor.uniform_.Arnoldi_Gnd.Arnoldi_BK_test