Repository navigation
Part M6: small API corrections for GeometricMachineLearning 0.9 - #358
Conversation
Nine items of section M6, each of them a defect a user meets: - `HRedSys` takes its integrator from the caller: all three constructors require the keyword, and the positional one defaults `parameters` to `NullParameters()`. The base defaulted both to undefined names, so a plain call raised `UndefVarError`. - `map_to_cpu` puts the copy on the CPU, in its backend and in its fourth type parameter, where it kept the device backend it was copied off. - `accuracy` returns the fraction in the element type of the loader's input. - The seven trajectory methods move off `Base.iterate` onto `GeometricBase.integrate`, which this package imports and exports, with the 74 call sites in 27 files, the two `@docs` entries and the two `@ref`s. The two sequence-length ternaries become one `_seq_length(arch, ics)`. - `PoissonTensor` and its `GPUArraysCore` extension are removed; a site that used the tensor builds `[0 I; -I 0]`, and one that used the 2-form writes it out. - `update!`, `solve!` and `iterate` leave the exports, `Linear` and `NeuralNetwork` are exported once each, and `test/quality/exports.jl` gains the four names that must not be exported. - `InteractiveUtils` and `TimerOutputs` leave `[deps]` and `[compat]`. `KNOWN_ISSUES.md` K17 and K3 lose the sentences about the removed type and kernel.
The extension's three products are the removed PoissonTensor's, so the file goes with the type. Its test file moves to test/integration/triangular.jl, which holds the same assertions on the structured matrix types this package re-exports: with src/arrays/ gone there is no directory for it to mirror.
`src/optimizers/optimizer.jl` said that `update!` is GeometricOptimizers' verb and that this package adds methods to it. It defines none: the module file imports the name so that `GeometricMachineLearning.update!` is GeometricBase's rather than `ProgressMeter`'s, which `using ProgressMeter` would otherwise supply. `test/quality/exports.jl` said the same of all three bound names in its not-exported list. Only `solve!` carries this package's methods there; `update!` and `iterate` are their owners' objects.
…view found The error count of `accuracy` is halved rather than floored, so a sample that carries no label counts half an error: a `Float32` loader with one unlabelled sample gives `0.9166667` where a floored count gives `1.0`. The fraction is read in the loader's element type, which the `Float64` model on a `Float32` loader pins, and both the unlabelled case and that mixed pair are tests. The two testsets the part adds loop over `Float32` and `Float64` and assert the element type of each result. `map_to_cpu` keeps the host backend it was handed, so `CPU(; static = true)` comes back static and a device network lands on `CPU()`. Its device testset runs under `allowscalar(false)`. The tutorial that solves a PSD network imports `solve!` in its own `@example` block, which is the module Documenter evaluates it in. `README.md` calls `integrate`, the device file's sentence in `docs/src/index.md` says it runs two testsets, and the Metal label names what that file runs. The comments that narrated a change say what the code does instead, the `HRedSys` docstring states which keyword is required and what `parameters` defaults to, and the module's dangling arrays heading is gone. The two scripts that build the canonical matrix carry the guard the test helper has.
…d the input's width
…Unreleased entries as one release
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 5 minutes. View limit details
📝 Summary
Merge Risk:
|
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

Minor · Add integrator to both documented constructor forms. · reduced_system.jl:13
src/reduced_system/reduced_system.jl:13
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd
integratorto both documented constructor forms.Both call forms omit the newly required keyword. A caller who follows either form gets
UndefKeywordError. Showintegrator = ...in both forms. Also showencoderanddecoderas positional arguments in the standard form, as the constructor requires.Also applies to: 31-31

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
99e3cd2a-7b57-4b28-bb8b-9967d76c07c1
Files selected for processing: 67-
CHANGELOG.mdKNOWN_ISSUES.mdProject.tomlREADME.mddocs/check_references.jldocs/make.jldocs/src/architectures/neural_network_integrators.mddocs/src/index.mddocs/src/structure_preservation/symplecticity.mddocs/src/tutorials/linear_symplectic_transformer.mddocs/src/tutorials/matrix_softmax.mddocs/src/tutorials/softmax_comparison.mddocs/src/tutorials/symplectic_autoencoder.mddocs/src/tutorials/symplectic_transformer.mddocs/src/tutorials/sympnet_tutorial.mddocs/src/tutorials/volume_preserving_attention.mddocs/src/tutorials/volume_preserving_transformer_rigid_body.mdext/GPUArraysCoreExt.jlscripts/reproduction/linear_symplectic_transformer_gpu.jlscripts/reproduction/symplectic_autoencoders/online_sympnet.jlscripts/reproduction/symplectic_autoencoders/training.jlscripts/reproduction/symplectic_transformer/double_pendulum.jlscripts/reproduction/symplectic_transformer/double_pendulum_short_integration.jlscripts/reproduction/sympnets/sympnet_toda_lattice.jlscripts/reproduction/transformer_integrator/softmax_comparison.jlscripts/reproduction/transformer_integrator/symplectic_transformer.jlscripts/reproduction/transformer_integrator/symplectic_transformer_vector_softmax.jlscripts/reproduction/volume_preserving_feedforward/abc_flow.jlscripts/reproduction/volume_preserving_feedforward/double_pendulum.jlscripts/reproduction/volume_preserving_feedforward/rigid_body.jlscripts/reproduction/volume_preserving_transformer/rigid_body.jlscripts/utilities/ensemble_plots.jlscripts/utilities/vector_fields.jlscripts/verification/sympnet_upscaling_symplecticity.jlsrc/GeometricMachineLearning.jlsrc/architectures/neural_network_integrator.jlsrc/architectures/resnet.jlsrc/architectures/transformer_integrator.jlsrc/arrays/poisson_tensor.jlsrc/data_loader/batch.jlsrc/data_loader/data_loader.jlsrc/map_to_cpu.jlsrc/optimizers/optimizer.jlsrc/reduced_system/reduced_system.jlsrc/utils.jltest/architectures/psd_architecture_tests.jltest/architectures/sae_error_lower_than_psd_error.jltest/architectures/standard_transformer_integrator.jltest/architectures/symplectic_autoencoder_tests.jltest/architectures/sympnet_integrator.jltest/arrays/poisson_tensor.jltest/data_loader/accuracy.jltest/data_loader/batch.jltest/data_loader/data_loader.jltest/devices/metal.jltest/helpers/poisson.jltest/integration/docstrings/layers_and_architectures.jltest/integration/docstrings/utilities.jltest/integration/qp_dispatch.jltest/integration/triangular.jltest/layers/sympnet_upscaling.jltest/map_to_cpu.jltest/quality/aqua.jltest/quality/exports.jltest/quality/jet.jltest/reduced_system/reduced_system.jltest/runtests.jl
Files with no reviewable changes: 6-
- test/devices/metal.jl
- Project.toml
- docs/src/structure_preservation/symplecticity.md
- ext/GPUArraysCoreExt.jl
- test/arrays/poisson_tensor.jl
- src/arrays/poisson_tensor.jl
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
-
# Conflicts: # CHANGELOG.md
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #358 +/- ##
==========================================
+ Coverage 92.32% 93.07% +0.75%
==========================================
Files 53 51 -2
Lines 1186 1156 -30
==========================================
- Hits 1095 1076 -19
+ Misses 91 80 -11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
michakraus
left a comment
There was a problem hiding this comment.
JuliaGNI/GeometricMachineLearning.jl PR #358 — Part M6: small API corrections for GeometricMachineLearning 0.9
Verdict: request changes. It is posted as a comment because GitHub does not let the author's own account request changes on its own PR.
Reviewed: 8d48786258a35eeffb452128056b6414c7357d53
CI on this head, read job by job (run 40335239943):
- Julia pre fails before any test runs. The log says
Failed to precompile GPUCompiler [61eb1bfa-…] to ".../compiled/v1.14/GPUCompiler/…", afterUndefVarError: libLLVMExtra not defined in LLVM.API. This is a dependency failure on 1.14.0-alpha1.mainatd7a488c2(run 40310215232, job 121529219640) fails on the same line, so the diff does not cause it. - Julia nightly has the same failure on 1.15.0-DEV.143:
Failed to precompile GPUCompiler …, andMetal (skipped, GPUCompiler failed to precompile).mainatd7a488c2(job 121529219595) fails the same way. The diff does not cause it. - Downgrade fails at the forcedeps check, which is a resolver failure and not a test failure:
forcedeps check failed: Zygote resolved to 0.7.5 but lower bound is 0.7.0, plus the same for ChainRulesCore 1.25.1/1.0.0, NNlib 0.9.30/0.8.0 and KernelAbstractions 0.9.38/0.9.0.main(job 121529219128) fails on the same four packages and on a fifth,GPUArraysCore resolved to 0.2.1 but lower bound is 0.2.0. This PR removes the fifth. The diff does not change any of the four floors that remain. - codecov/patch:
86.36% of diff hit (target 92.32%). codecov/project:93.07% (+0.75%). I did not find the uncovered lines (see Not checked). - Every other job passes: Julia 1 and Julia min on ubuntu, macOS and windows, Doctests, Documentation, Metal min and 1, and Scripts.
Findings
| # | severity | file:line | claim | evidence |
|---|---|---|---|---|
| 1 | bug | src/data_loader/data_loader.jl:427 |
T(n - errors) / T(n) raises InexactError on a loader whose input is an integer type when the error count is not whole. That is the case for the unlabelled sample that this PR pins as "half an error". The base formula (n - errors/T1(2)) / n returned a Float64 in that case. When the count is whole, the result is still a Float64 and not T, which contradicts the new docstring sentence. |
Scratch environment with the PR head developed, Julia 1.13.2. DataLoader(rand(0:3, 4, 1, 6), out) with one all-zero target column gives InexactError: Int64(1.5). The same loader with every column labelled gives (0.3333333333333333, Float64). A fix that keeps the Float32/Float64 behaviour and covers integer inputs is F = float(T); F(n - errors) / n. It gives 0.75 Float64 for Int and a Float32 for Float32. |
| 2 | quality | src/data_loader/data_loader.jl:407-408 |
The new docstring says the result is "the fraction of correctly labelled samples". The new testset test/data_loader/accuracy.jl:93 pins one unlabelled sample out of six with five correct as (6 - 1/2)/6 = 0.9167, but the fraction of correctly labelled samples is 5/6. Either the docstring states the half-error rule, or the unlabelled case gets a defined meaning (excluded, or counted as wrong). Pinning the formula's by-product in a test makes it look like a contract. |
The docstring text at :407-408 against the @test a == (T(n_params) - T(1) / 2) / T(n_params) at test/data_loader/accuracy.jl:93-100. |
| 3 | quality | src/reduced_system/reduced_system.jl:13, :31 |
Neither documented call form works. :31 shows HRedSys(odeensemble, encoder, decoder), but this PR makes integrator required, so that call raises UndefKeywordError. :13 shows HRedSys(N, n; encoder, decoder, v_full, f_full, v_reduced, f_reduced, parameters, timespan, timestep, ics, projection_error), which matches no method: encoder through ics are positional, h_full is missing, integrator is missing, and projection_error is not an argument. Only the prose at :22 and :34 names the keyword. The PR body calls :13 pre-existing, but this PR edits the same docstring, so fixing :13 belongs in this change. This confirms the outside-diff CodeRabbit comment on 47f534b, which still holds at this head. |
methods(HRedSys) at this head lists HRedSys(N::Integer, n::Integer, encoder, decoder, v_full, f_full, h_full, timespan::Tuple, timestep::T, ics; parameters, v_reduced, f_reduced, h_reduced, integrator) and two (problem, encoder, decoder; integrator) methods. test/reduced_system/reduced_system.jl:151-152 asserts that the :31 form raises UndefKeywordError, and it passes. Suggested signature lines: HRedSys(N, n, encoder, decoder, v_full, f_full, h_full, timespan, timestep, ics; integrator, parameters = NullParameters(), v_reduced, f_reduced, h_reduced) and HRedSys(odeensemble, encoder, decoder; integrator). Also, :23 calls parameters "a NamedTuple" but gives it the default NullParameters(). |
| 4 | quality | scripts/utilities/vector_fields.jl:34-50 |
The PR rewrites v_field and v_field_explicit, but nothing calls them. They also have a pre-existing dimension mismatch: full_mat is 2m × 2m, while poisson_matrix(size(K, 1)) is m × m. This applied to PoissonTensor(size(K, 1)) on main too. Delete the two functions instead of porting them. That also removes one of the three copies of poisson_matrix. |
grep -rn -E "v_field(_explicit)?\b" over the repository finds only the two definitions. K = assemble_matrix(...).parent is (Ñ+2) × (Ñ+2), and full_mat = hcat(vcat(K + K', zero(K)), vcat(zero(K), one(K)*Δx)). |
| 5 | nit | CHANGELOG.md:20 |
The migration recipe [0 I(n); -I(n) 0] raises an error for every n > 1, because a scalar 0 is not an n × n block. The PR body uses the same text. The comments in test/helpers/poisson.jl, scripts/utilities/vector_fields.jl and scripts/verification/sympnet_upscaling_symplecticity.jl describe the matrix the same way, but their code is correct. |
[0 I(n); -I(n) 0] with n = 2 gives DimensionMismatch: incompatible shape in element 2. [zeros(n, n) I; -I zeros(n, n)] gives the 4×4 matrix and is equal to the helper's result. |
| 6 | nit | src/data_loader/data_loader.jl:426 |
/ T1(2) raises InexactError: Bool(2) for Bool one-hot labels, which the signature T1 <: Integer accepts. The base has the same T1(2), so this PR did not introduce it. The PR rewrites this line, though, and / 2 fixes it. |
accuracy(model, ps, DataLoader(rand(4, 1, 6), Bool.(out))) gives InexactError: Bool(2). |
| 7 | nit | KNOWN_ISSUES.md:219-224 |
The PR edits K3's heading and its last sentence. The evidence in between is still stale: "142 pass, 3 broken" (the CHANGELOG now says 50 assertions, none broken), augment_zeros! in src/data_loader/tensor_assign.jl, and skew_mat_mul_k! in src/kernels/mat_tensor_mul.jl. The PR body lists this as pre-existing, but it sits in the paragraph this PR rewrites. |
grep -rn -E "skew_mat_mul_k!|augment_zeros!" src finds no match. src/kernels/ has no mat_tensor_mul.jl. |
| 8 | nit | test/Project.toml:9 |
GPUArraysCore is now a test-only dependency (test/map_to_cpu.jl, test/devices/jlarray.jl, test/layers/positional_encoding.jl and test/layers/volume_preserving_attention.jl use it). It lost the "0.2" bound that the root [weakdeps]/[compat] gave it, and test/Project.toml adds no bound of its own. |
git diff origin/main... removes GPUArraysCore = "0.2" from Project.toml. test/Project.toml is unchanged and has no GPUArraysCore entry in [compat]. |
| 9 | nit | src/architectures/transformer_integrator.jl:18-23 |
_seq_length branches on isa over two concrete types. Two methods say the same with dispatch: _seq_length(arch::TransformerIntegrator, ::AbstractMatrix) = arch.seq_length and _seq_length(::Union{StandardTransformerIntegrator, SymplecticTransformer}, ics::AbstractMatrix) = size(ics, 2). The second method goes after both types are defined. Optional: the current version folds to a constant. |
code_typed(_seq_length, (VolumePreservingTransformer{…}, Matrix{Float32})) is a single getfield(arch, :seq_length)::Int64, so the branch costs nothing at run time. This is about readability only. |
| 10 | nit | GeometricOptimizers/src/manifolds/symplectic_stiefel_manifold.jl:70-73 (other repository) |
After this merges, that comment is wrong: it says GeometricMachineLearning "exports a PoissonTensor type" and that "unifying the two is a separate change". It needs a follow-up there. |
Read at that path. |
Verified and fine
- I ran 10 test files from this head in a scratch environment (Julia 1.13.2, GeometricOptimizers 0.9.1, GeometricBase 0.15.2, GeometricIntegrators 0.18.7, ExplicitImports 1.15.0, Aqua 0.8.18):
reduced_system/reduced_system.jl,map_to_cpu.jl,data_loader/accuracy.jl,data_loader/batch.jl,quality/exports.jl,quality/aqua.jl(withtest_explicit_imports),integration/qp_dispatch.jl,integration/docstrings/layers_and_architectures.jl,architectures/standard_transformer_integrator.jlandarchitectures/sympnet_integrator.jl. Result: 538 pass, 0 fail, 0 error. GeometricMachineLearning.integrate === GeometricIntegrators.integrate === GeometricBase.integrateistrue. All seven trajectory methods are on that generic, with aNeuralNetworkfirst argument, so this is not piracy.integrate,LinearandNeuralNetworkare exported.update!andsolve!are not.- The claim that the
update!import is needed holds. GeometricBase does not exportupdate!and ProgressMeter does. In a module that only doesusing GeometricBase; using ProgressMeter,update!resolves toProgressMeter. map_to_cpu:nn.backend isa CPU ? nn.backend : CPU()is decided from the type parameter, and the JLArray andCPU(; static = true)testsets pass._seq_lengthinfersInt64forStandardTransformerIntegrator,VolumePreservingTransformerandLinearSymplecticTransformer, andstandard_transformer_integrator.jlasserts the stored-length branch directly.- In
src/,docs/src/,scripts/andtest/, noiterate(nn…,PoissonTensororImplicitMidpoint()default is left. The remaining names are theNOT_EXPORTEDgate and history entries in the CHANGELOG. EveryHRedSys(call site indocs/,scripts/andtest/passesintegrator. - JuliaFormatter (
sciml) reports every changed file undersrc/andtest/, plusdocs/make.jl,docs/check_references.jland the two changed utility/verification scripts, as formatted. - The PR body states that the pre, nightly and Downgrade jobs are red on
mainas well. That is true; see CI above. The PR body has no closing keyword, andclosingIssuesReferencesis empty.
Not checked
- Which lines
codecov/patchcounts as missed. The Codecov API was not reachable from here, and I did not run a local coverage build of the suite. - The
metalgroup, the docs build and the doctests. CI's Metal, Documentation and Doctests jobs pass on this head, and I did not run them again. - The full suite. I ran only the 10 files listed above.
accuracy raised InexactError for an integer input when a sample carried no label (half an error), and for Bool labels on the halving; it now computes in float(T). A new testset covers the integer input. The HRedSys docstring shows integrator in both call forms and the standard form matches the positional method. The two Unreleased changelog bullets are corrected to match: the accuracy formula, and a Poisson-tensor recipe that works for n > 1. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Resolution of the findings in the review above (#358 (review)), as of e59e9ae.
Checks run on e59e9ae before the push: CI on the previous head (run 40335239943): the review above traces the red "Julia pre", "Julia nightly" and "Downgrade" jobs to failures that |
_seq_length dispatches on the architecture instead of branching on isa: the generic method reads arch.seq_length, and StandardTransformerIntegrator and SymplecticTransformer each take the width of the input, beside their own definitions. scripts/utilities/vector_fields.jl loses v_field and v_field_explicit, which nothing called, with the poisson_matrix helper and the LinearAlgebra import that only they used. test/Project.toml bounds the now test-only GPUArraysCore at 0.2, the root bound it had on main. KNOWN_ISSUES K3 names the kernel launches that exist and gives the counts of a new mutation run of test/quality/jet.jl. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
b53ebb4 resolves four of the five findings that the previous comment left open:
Checks before the push: the transformer, docstring, Aqua and JET test files pass (93 of 93). |
The halving of the error count is in floating point, so a Bool target gives the value of the Int64 one; the new testset fails with InexactError: Bool(2) on the old divisor. The Unreleased accuracy bullet now says where the count is taken. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
The CodeRabbit findings on this PR, and what happened to each (as of 18877fa):
|
Part M6 of the 0.9 simplification: small API corrections
Part M6 of the plan that simplifies GeometricOptimizers and GeometricMachineLearning for release
0.9. It fixes a set of small user-visible defects, four of the fixes break an API, and two
behaviours change without a name changing. 67 files, +454 −640.
Relates to #293. Relates to #79.
What changes
Breaking, four.
PoissonTensoris removed, withext/GPUArraysCoreExt.jl, the[weakdeps]and[extensions]entries ofProject.toml, andGPUArraysCoreitself. A site that needs thecanonical tensor builds
[0 I(n); -I(n) 0]ofn2 × n2withn = n2 ÷ 2; a site that used the2-form writes
v₁.q' * v₂.p - v₁.p' * v₂.q, because aMatrixis not callable on one argument.Base.iterateontoGeometricBase.integrate,and the export moves with them. 75 call sites in 28 files, the two
@docsentries and the two@refs renamed.GeometricIntegrators.integrateis the same function object, so a page thatloads both packages resolves one verb.
update!andsolve!are no longer exported. Both keep their binding here —update!isGeometricBase.update!,solve!isSimpleSolvers.solve!— and thesolve!(::NeuralNetwork{<:PSDArch}, …)methods this package defines stay. The import ofupdate!stays as well: without it the name resolves through
using ProgressMetertoProgressMeter.update!, which does export it.HRedSysconstructors requireintegrator, so a call that names none raisesUndefKeywordError(:integrator), and the positional constructor defaultsparameterstoNullParameters().ImplicitMidpointis named nowhere insrc/.Fixed, two.
accuracyreturns the element type of the loader's input. It divided anIntby anInteger,so
/made it aFloat64for every loader, and aFloat64model widened aFloat32loader'sresult. The value of the fraction does not move.
map_to_cpureturns a network whose backend is the host's: theCPUit was handed, orCPU().It returned host leaves behind a device backend and a device type parameter, so the next forward
pass sent host data to the device the network came from.
Elsewhere.
_seq_lengthreplaces the ternary the two matrix methods wrote twice;InteractiveUtilsandTimerOutputsleave[deps]and[compat];test/quality/exports.jlgainsthe four names that must not be exported; the tutorials, the scripts and the manual's GPU section
follow the removals.
The loop
f727c82dstopped on the first advisor question, withhead_facts.jlgreen and 3 of 12 mutants run.
7412b05c:head_tree.shgreen,head_facts.jl40 of 40, 15 mutants written, 14 caught, 1 equivalent.7412b05c, 7 blocking defects: thesymplectic_autoencodertutorial'ssolve!outside its@exampleblock,docs/src/index.md's"three testsets", the two new testsets' precision loops and
allowscalar(false), three commentsthat told history, the accuracy test that could not fail for the element type it names, and the
sentence naming
tensor_cayley.text.
de7c7bc1; verify round 2: PASS, no blocking defect, no other defect of the fixdiff, all nine mutants caught.
julia-branch-verifierpasses. Four commits follow
de7c7bc1, all text:e3ffd50bcorrects one test comment,63ccb563the rationale for
import GeometricBase: integrate, and06ee50fcand47f534bcthe changelog —two
### Fixedbullets for this part's two behaviour changes, and four[Unreleased]bulletsbrought to the release's end state, since an open section is not history.
Gates
de7c7bc1: 93 testsets, 0 failed — Julia 1.13.2 in 448 s, Julia 1.12.7 in679 s.
47f534bc:spec-validate.py --headPASS —head_tree.shandhead_facts.jlboth pass.
test/quality/jet.jl: PASS, 50 assertions, 6 s — a named run on Julia 1.13.2 of the tree at63ccb563, whose two successors changeCHANGELOG.mdonly.de7c7bc1:CIsuccess (run 40313975979 — Doctests, Julia 1, Julia min on Ubuntu,macOS and Windows);
Documentationsuccess (40313979594);Metalsuccess (40313983268);Scriptssuccess (40313987455).
Downgrade,Julia preandJulia nightlyare red onmainatd7a488c2as well, so they are not this part's.de7c7bc1change a comment, one test comment andCHANGELOG.md; noexecutable line changes, so CI is not re-run for them.
Pre-PR verification
Pass 3 of 3,
julia-branch-verifier— verdict: clear to open, 0 unresolved. Diffa664f5c9...47f534bc, 67 files, +454/−640, 8 commits. The last change tosrc/is63ccb563(onecomment) and to
test/quality/jet.jlis0e1136b8, so the passes re-judged points 1, 6 and 7 onthe rewritten lines; points 2–5 stand as measured in pass 1.
Seven points over the whole diff. 1 · correctness, quality, concision — every changed hunk read
with context;
integrateisGeometricBase.integratewith 7 methods and noiterateleft;_seq_lengthcovers the three transformer families that have noseq_lengthfield; everyHRedSys(call site passes the now-requiredintegrator. 2 · type piracy —Aqua.test_piraciespasses; the added methods are on this package'sNeuralNetworkforGeometricBase.integrate, and thePoissonTensorextension is deleted with the type.3 · duplicated functionality — nothing re-implements a dependency:
mapstorageisNeuralNetworkParameters',
integrateGeometricBase's, the triangular types GeometricOptimizers'.4 · type instability —
code_typedgives concrete returns for_seq_lengthon all threearchitectures,
map_to_cpu(::NeuralNetwork)andaccuracy; noAnyoriginates in a changed hunk.5 · avoidable allocations —
fatou lintover 154 files clean. 6 · stale comments — everyadded comment and docstring line read against its code, present tense. 7 · history only in
CHANGELOG.md— historical phrasing occurs nowhere else, and[Unreleased]carries entries forboth behaviour changes of this part. Also clean: the four enabled
ExplicitImportschecks, Aquastale_deps,detect_ambiguities(0 recursive, 0 non-recursive), and the formatter over the 49changed
.jlfiles.Pass 1 fixed the rationale comment for
import GeometricBase: integrate(
src/GeometricMachineLearning.jl:16-19): a bareusingsupplies GeometricBase's exportedintegrate, and it is the method definitions that would start a generic of this module's own. Pass2 found the changelog gap that pass 1 had left, and three further text claims; commit
47f534bcanswers them in
CHANGELOG.md:76,:78and:118, each re-verified againstsrc/data_loader/data_loader.jl:425-427,src/map_to_cpu.jl:22-23and the timing file of thejet.jlrun.Unresolved: one nit.
test/integration/qp_dispatch.jl:95's@test_throws MethodError poisson_matrix(4) * (a = [1.0, 2.0], b = [3.0, 4.0])now tests nothing this package controls — aMatrixtimes aNamedTupleis aMethodErroreither way. The part's spec decides that the rowkeeps its subject, so it stays; it is listed under Recorded, not fixed below.
Not checked by the verifier: points 2–5 were not re-measured (no executable change after pass
1); the suite, the docs build and its doctests, JET standalone and the
metalgroup were not runthere. The gates above are this part's runs.
Critic
Verdict: PASS. All seven earlier blocking defects are fixed, the fix diff adds none, and all nine mutants are caught.
base_facts.jlhead_tree.shhead_tree.sh: PASShead_facts.jlbase_facts.jl: "accuracy of a Float32 loader is a Float64", "copy keeps the JLBackend backend", the halved error countok, PASS, including the mixed pairFloat32, the halved0.9166667, the static host backendCPU(true)T; the mixed pair(Float32, Float64), mixed Float64 model on a Float32 loaderCPU(true)includedeltype(Float32, Float64)allowscalar(false)@inferred map_to_cpu(nn)passes for all six cases; unlabelled gives0.5ofT; a JLArray loader answersdocs/src/index.md: two testsets, both named, noPoissonTensor+linesEarlier blocking defects, all fixed: the tutorial's
solve!in its@exampleblock (prev/givesUndefVarErrorinMain.__atexample__named__toda_lattice,tree/passes);index.md's "threetestsets"; the spec sentence naming
tensor_cayley; theBatchandmap_to_cputestsets' precisionloops and
allowscalar(false); the three history comments; the accuracy testset that could not catcha wrong element type.
Known issues added
None. The branch edits two existing entries rather than adding one: K17 loses its
PoissonTensor * vhalf with the type, and K3's heading and last sentence lose the Poisson-tensor kernel.
Recorded, not fixed
pins.jlharness gap.pins.jlreplaces a branch copy'ssrc/andext/with the base'sand leaves the copy's
Project.toml. The base'ssrc/GeometricMachineLearning.jlhasusing InteractiveUtilsandusing TimerOutputs, and this branch removes both from[deps], so acopy of this branch's tree cannot load the base's source: no unit of this branch can be pinned on
the base with
pins.jlas it stands.poisson_matrixis written three times — intest/helpers/poisson.jl,scripts/utilities/vector_fields.jlandscripts/verification/sympnet_upscaling_symplecticity.jl— because each script stands alone and includes no test helper. A shared copy would need a
src/home that neither a test nor a script should reach.test/integration/qp_dispatch.jl'sMethodErrorrow is now vacuous: aMatrixtimes aNamedTuplehas no method with or without this change. The row keeps its subject, which is thepart's recorded decision; a stronger refusal would assert
_vcaton other keys.HRedSysdocstring's "standard constructor" block(
src/reduced_system/reduced_system.jl:13-15) documents a call that matches no method — keywordswhere the arguments are positional,
h_fullmissing,integratorabsent, andprojection_errora function of an
HRedSysrather than an argument. That is the remaining half of HRedSys standard constructor is unusable: parameters keyword defaults to itself #293.KNOWN_ISSUES.mdK3's evidence namesaugment_zeros!insrc/data_loader/tensor_assign.jlandskew_mat_mul_k!insrc/kernels/mat_tensor_mul.jl, and the release removed both in part M3 (Products through GEMM: one _mul, slicing assign_q_and_p, zero and other-precision seeds in the kernel rrules (part M3) #345).Decisions taken without the user
Decided (advisor, 2026-10-26, medium): the REMOVED requirement on
PoissonTensorreads "The name SHALL be gone fromsrc/,docs/src/,scripts/andKNOWN_ISSUES.md, and from every file oftest/excepttest/quality/exports.jl, whose not-exported gate names it to assert that the package neither exports nor defines it." The scenarios the name is gone and the files that carry the name take the same exception, andhead_tree.shcounts the four directories and adds thatgrep -rlF PoissonTensor testnames exactlytest/quality/exports.jl. The promise the check encodes — that MU10 is killed by a test in the repository — is what the exception protects.Decided (advisor, 2026-10-26, high): GML keeps
import GeometricOptimizers: update!, although no line ofsrc/uses it, because without itGeometricMachineLearning.update!resolves throughusing ProgressMetertoProgressMeter.update!.test/quality/aqua.jlexempts that one name fromno_stale_explicit_importsand gives this reason, and GML defines no method onupdate!. The three comments that say GML adds methods toupdate!are corrected:src/optimizers/optimizer.jl:4-5,test/quality/exports.jl:25-26and §2 Seams of this spec.Clauses the head does not meet as the spec writes it: none.
spec-validate.py --headpasses everycheck:of the delta at47f534bc.