Repository navigation
Refresh the sparse pool, fix CI on SuiteSparse 8, and fix ss.register_new after #630 - #631
Merged
Merged
Conversation
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
August 27, 2026 16:04
712caaf to
7b5e4e3
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
August 27, 2026 16:26
7b5e4e3 to
5fb2230
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
August 27, 2026 16:40
5fb2230 to
90a345d
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
August 27, 2026 16:46
90a345d to
d9e757e
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
2 times, most recently
from
September 18, 2026 03:46
d3abbb0 to
2f55c85
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
September 23, 2026 18:19
2f55c85 to
add51db
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
September 24, 2026 20:06
add51db to
aba52ce
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
2 times, most recently
from
September 25, 2026 06:10
a3c5b44 to
4162246
Compare
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
September 26, 2026 05:23
4162246 to
439bc4e
Compare
The pools refresh below this commit left sparse behind: the pool stopped at 0.15 while 0.16 through 0.19.2 exist, and py3.13/3.14 hardcoded "NA" under a comment saying sparse does not support them. That was true in the 0.15 era, when numba could not run on those Pythons; it is not true now. Constraints read off conda-forge metadata rather than assumed: every sparse release here is noarch with numba >=0.49 and numpy >=1.17 and no numpy ceiling, so only the Python floors matter. 0.16/0.17 declare python >=3.10 and 0.18/0.19 declare >=3.11. On py3.13/3.14 the pool starts at 0.16 because 0.14/0.15 predate those Pythons; on py3.11/3.12 the old entries stay. No new pairing rules are needed: the workflow already skips sparse whenever numba is skipped or NA, which covers sparse's only runtime dependency. The validate() Python check moves from "any sparse on py3.13+" to the 0.16 floor, and the stress test passes 160000 combos. Verified beyond metadata on this machine (py3.14, macOS arm64): sparse 0.16.0 and 0.19.2 pass the pydata-sparse io tests, and 0.18.0 passed the full suite. **Edit: rebased to include the changes on main, which largely supercedes this**
eriknw
force-pushed
the
41-ci-dep-pools-refresh
branch
from
September 26, 2026 05:25
439bc4e to
44c030e
Compare
The CI pools started sparse at 0.16 on py3.13 and 0.18 on py3.14, and the io extra in pyproject.toml had the same floors. Each was the first sparse release to come out after that Python, on the assumption that older ones might not work there. They do. sparse is noarch, and every release from 0.14 on declares numba >=0.49, numpy >=1.17 and a Python floor of 3.11 or lower (>=3.8 for 0.14/0.15, >=3.10 for 0.16/0.17, >=3.11 for 0.18/0.19), with no ceiling on any of them. Each pin, as conda-forge resolves it (0.14.0, 0.15.5, 0.16.0, 0.17.0, 0.18.0 and 0.19.2), solves on both Pythons and passes the pydata-sparse tests with the oldest and newest numpy/numba pair each Python draws: numpy 2.1 with numba 0.62 and numpy 2.5 with numba 0.67 on py3.13, numpy 2.3 with numba 0.63 and numpy 2.5 with numba 0.67 on py3.14. So every Python now draws from the same pool, 0.14 through 0.19 plus latest, and the io extra requires sparse >=0.14 wherever numba installs. No pairing rules are needed, since the workflow already drops sparse whenever it skips numba. The stress test passes 160000 combinations, and both version audits pass.
test_failed_compile_is_not_retried_at_the_next_arming, from #630, arms binary.plus on a UDT with C source for SuiteSparse to compile, then makes that compile fail. An op is armed with C source only when the JIT string setters exist, and those arrived in SuiteSparse 9, so on 8.x jit_c_source is None and the test failed at its first assertion. It gets that far only where the JIT probe passes. In CI that happens only on some macOS runners that draw psg 8 (numpy 1.x); main's CI failed there after #630 merged. The test now skips when _has_jit_set is false, like the other tests that need an armed op. On 8.x the stand-in config tests still check that _enable_jit_for_udt leaves 'load' alone. Locally on psg 9.3.1.0, the only release in the CI pool that takes its pre-9.4 branch, it runs and passes.
gb.unary.ss.register_new and its binary, indexunary, select, and indexbinary siblings create the op from a C definition and no function pointer, so SuiteSparse has to compile the definition, or load it from its cache, before the op exists. Under its default jit_c_control of 'run' it does neither, and the registration fails with a bare NullPointer. Before #630, importing graphblas.ss raised the control to 'on', and the docstrings of these functions send users to gb.ss.config, so touching it first was enough; a process that never touched gb.ss already failed. #630 stopped the import from changing the control and moved the raise to _enable_jit_for_udt, which UDT op arming and gb.dtypes.ss.register_new call but these registrars did not. Since then nothing raises it for them, and each fails in a fresh process, on SuiteSparse 8.0.2 and 10.5 alike. The four op registrars and gb.dtypes.ss.register_new now create through one context manager, _compiling_c_source, which raises 'run' first and still honors an explicit 'off', 'pause', or 'load'. When creation fails anyway, SuiteSparse's error (NullPointer, InvalidValue, or from 9.4 JitError) has no message, so the same exception is raised again with the reason, read off jit_c_control before and after: the JIT is off or paused; it was left at 'load' and the kernel is not cached; this compile failed and SuiteSparse set 'load'; the compiler probe failed in this very call; or the control is still 'run' because no compiler was found or the library has no JIT. gb.dtypes.ss.register_new also accepted a name of GxB_MAX_NAME_LEN characters. That limit counts the NUL, so SuiteSparse cut the name by one, it no longer matched the typedef, and the compile failed. It is now rejected up front. The user guide's list of what raises the control includes the op registrars. New tests register one op of each kind in a fresh process, resetting the control to 'run' before each so none can rely on another, check each reason's message, and check the name limit.
Messages: Matrix, Vector, and Scalar __sizeof__ printed a literal
{backend} (no f prefix); the Matrix diagonal size-mismatch message ran two
sentences together, and the nrows/ncols error two words; the compression
level error named only "lz4hc" where "zstd" also takes a level; the UDT
repr size warning ended its first sentence twice.
Docstrings: isequal documented check_dtype as check_dtypes; from_csc
documented col_indices and said ncols is computed where it takes
row_indices and computes nrows; from_dicts documented d for nested_dicts;
Vector.diag documented a dtype it does not take; Vector.from_scalar
documented nrows and ncols for size; serialize gave the zstd default level
as 19 and a 1-9 range for both methods (zstd defaults to 1 and takes
1-19), and the descriptor docs gave the lz4hc default as 1 (it is 9);
operator registration pointed at a graphblas.ops namespace, which is
graphblas.op; several parameter lines numpydoc cannot parse ("name: type",
"name :type"); two choice lists missing a closing quote; .mtz.gz for
.mtx.gz in mmread; "`first` any `any`" in a comment.
Docs: "the the" in the operators guide, the README converting the scipy
matrix back instead of the GraphBLAS one, and two misspellings in a CSS
comment.
Member
Author
|
LGTM! This cleans up a number of typos and minor format issues too. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test and allow every sparse release on Python 3.13 and 3.14. The CI pools started sparse at 0.16 on py3.13 and 0.18 on py3.14, and the io extra in
pyproject.tomlhad the same floors. Each was the first sparse release to come out after that Python, on the assumption that older ones might not work there. They do. sparse is noarch, and every release from 0.14 on declaresnumba >=0.49,numpy >=1.17and a Python floor of 3.11 or lower (>=3.8for 0.14/0.15,>=3.10for 0.16/0.17,>=3.11for 0.18/0.19), with no ceiling on any of them. Each pin, as conda-forge resolves it (0.14.0, 0.15.5, 0.16.0, 0.17.0, 0.18.0 and 0.19.2), solves on both Pythons and passes the pydata-sparse tests with the oldest and newest numpy/numba pair each Python draws: numpy 2.1 with numba 0.62 and numpy 2.5 with numba 0.67 on py3.13, numpy 2.3 with numba 0.63 and numpy 2.5 with numba 0.67 on py3.14. So every Python now draws from the same pool, 0.14 through 0.19 plus latest, and the io extra requiressparse >=0.14wherever numba installs. No pairing rules are needed, since the workflow already drops sparse whenever it skips numba. The stress test passes 160000 combinations, and both version audits pass.Skip the failed-compile JIT test on SuiteSparse 8. Main's CI has been red since #630 merged: every failing job in the latest wave, on main and across the stack, drew psg 8 (SuiteSparse 8.0.2 or 8.2.x, reachable only with numpy 1.x).
test_failed_compile_is_not_retried_at_the_next_arming(#630) armsbinary.pluson a UDT with C source and makes the compile fail. Ops get C source only where the JIT string setters exist, which is SuiteSparse 9, so on 8.xjit_c_sourceisNoneand the test failed at its first assertion wherever the JIT probe passes, which in CI is some macOS runners. It now skips onnot _has_jit_set, like the other tests that need an armed op; the stand-in config tests still check on 8.x that_enable_jit_for_udtleaves'load'alone. Verified on psg 8.0.2.1 and 8.2.1.0 (fails before, skips after) and on 9.3.1.0, the only release in the pool that takes its pre-9.4 branch (runs and passes). The two other SuiteSparse 8 failures are in tests added by #590 and #613, fixed there.Enable the JIT when registering from C source, and say why it failed.
gb.unary.ss.register_newand itsbinary,indexunary,select, andindexbinarysiblings create the op from a C definition and no function pointer, so SuiteSparse has to compile it, or load it from its cache, before the op exists. Under its defaultjit_c_controlof'run'it does neither, and the call fails with a bareNullPointer. Before #630, touchinggb.ss.configfirst, as these docstrings suggest, raised the control; #630 moved the raise to_enable_jit_for_udt, which these registrars did not call, so each fails in a fresh process on SuiteSparse 8.0.2 through 10.5. CI missed it because the JIT test module turns the JIT on for all its tests. The registrars andgb.dtypes.ss.register_newnow create through_compiling_c_source, which raises'run'(still honoring'off','pause', and'load') and, when creation fails anyway, raises the same exception again with the reason read offjit_c_controlbefore and after, since SuiteSparse's own error has no message: the JIT is switched off, the control is'load'and the kernel is not cached, this compile failed, the compiler probe failed in this very call, or no compiler was found.gb.dtypes.ss.register_newalso rejects a name ofGxB_MAX_NAME_LENcharacters up front: the limit counts the NUL, so SuiteSparse cut such a name by one and it failed to compile. New tests cover each registrar in a fresh process, each reason, and the name limit.Fix small errors in docstrings, messages, and docs. Three
__sizeof__errors printed a literal{backend}; two messages ran words together; the compression-level error omitted"zstd"; the UDT repr size warning ended a sentence twice. Docstrings documented the wrong parameter names (isequal,from_csc,from_dicts,Vector.from_scalar), a nonexistentdtype(Vector.diag), wrong compression defaults and ranges, agraphblas.opsnamespace that isgraphblas.op, and several parameter lines numpydoc cannot parse. Also a README example that converted the wrong object, a doubled "the", two unclosed quotes, and two CSS comment typos.Verified locally: full
--runslowsuites pass on psg 8.0.2.1 and SuiteSparse 10.5.0, both backends, for this branch and for the top of the stack;test_ssjit.pypasses on 9.3.1.0 and 9.4.5.0.