Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

Refresh the sparse pool, fix CI on SuiteSparse 8, and fix ss.register_new after #630 - #631

Merged
eriknw merged 5 commits into
mainfrom
41-ci-dep-pools-refresh
Oct 1, 2026
Merged

eriknw merged 5 commits into
mainfrom
41-ci-dep-pools-refresh

Conversation

@eriknw

@eriknw eriknw commented Aug 26, 2026 •

Copy link
Copy Markdown
Member

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.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.

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) arms binary.plus on 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.x jit_c_source is None and the test failed at its first assertion wherever the JIT probe passes, which in CI is some macOS runners. It now skips on not _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_udt leaves '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_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 it, or load it from its cache, before the op exists. Under its default jit_c_control of 'run' it does neither, and the call fails with a bare NullPointer. Before #630, touching gb.ss.config first, 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 and gb.dtypes.ss.register_new now 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 off jit_c_control before 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_new also rejects a name of GxB_MAX_NAME_LEN characters 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 nonexistent dtype (Vector.diag), wrong compression defaults and ranges, a graphblas.ops namespace that is graphblas.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 --runslow suites 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.py passes on 9.3.1.0 and 9.4.5.0.

@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 712caaf to 7b5e4e3 Compare August 27, 2026 16:04
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 7b5e4e3 to 5fb2230 Compare August 27, 2026 16:26
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 5fb2230 to 90a345d Compare August 27, 2026 16:40
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 90a345d to d9e757e Compare August 27, 2026 16:46
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch 2 times, most recently from d3abbb0 to 2f55c85 Compare September 18, 2026 03:46
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 2f55c85 to add51db Compare September 23, 2026 18:19
@eriknw
eriknw added this pull request to stack #634 September 23, 2026 18:19
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from add51db to aba52ce Compare September 24, 2026 20:06
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch 2 times, most recently from a3c5b44 to 4162246 Compare September 25, 2026 06:10
Base automatically changed from 40-ss-import-jit-control to main September 26, 2026 05:23
@eriknw
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 4162246 to 439bc4e Compare September 26, 2026 05:23
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
eriknw force-pushed the 41-ci-dep-pools-refresh branch from 439bc4e to 44c030e Compare September 26, 2026 05:25
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.
@eriknw eriknw changed the title Refresh the CI dependency pools to the current releases Refresh the sparse pool, fix CI on SuiteSparse 8, and fix ss.register_new after #630 Sep 27, 2026
@eriknw

eriknw commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

LGTM! This cleans up a number of typos and minor format issues too.

@eriknw
eriknw merged commit 5aa3d4c into main Oct 1, 2026
18 checks passed
@eriknw
eriknw deleted the 41-ci-dep-pools-refresh branch October 1, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant