Skip to content

fix(@stdlib/blas/ext): validate broadcast compatibility of ndarray second args - #14228

Open
Planeshifter wants to merge 1 commit into
developfrom
philipp/ci-fix-circshift-k-broadcast-2026-08-13
Open

fix(@stdlib/blas/ext): validate broadcast compatibility of ndarray second args#14228
Planeshifter wants to merge 1 commit into
developfrom
philipp/ci-fix-circshift-k-broadcast-2026-08-13

Conversation

@Planeshifter

Copy link
Copy Markdown
Member

Resolves #{{TODO: add issue number}}.

Description

What is the purpose of this pull request?

This pull request:

  • Fixes blas/ext/circshift, blas/ext/sort, and blas/ext/sorthp to throw when the k/sortOrder ndarray argument is not broadcast-compatible with the target shape, restoring the missing check on the no-dims code path.

Related Issues

Does this pull request have any related issues?

This pull request has the following related issues:

  • #{{TODO: add related issue number}}

Questions

Any questions for reviewers of this pull request?

No.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

Failing run: https://github.com/stdlib-js/stdlib/actions/runs/31686732576 (nightly macos_test, Node.js 16, develop).

Symptom: 6 assertion failures across blas/ext/circshift, blas/ext/sort, blas/ext/sorthp — the "throws an error if provided a k/sortOrder argument which is not broadcast-compatible" tests (plus (options) variants). Non-scalar-shaped ndarrays ([4], [2,2,2], [0]) passed as the second argument did not trigger a throw.

Root cause: in each lib/main.js, when the second argument is an ndarray and either no options object or an options object without dims is supplied, the value was passed straight to base() with no broadcast check. The opts.dims branch already called maybeBroadcastArray() correctly. With no dims, the operation spans all dimensions, so the implicit target shape is [] — this case had no check.

Fix: route the no-dims paths through maybeBroadcastArray( arg, [] ), matching each file's existing dims branch.

  • circshift/lib/main.js: 2 insertions / 2 deletions (both call sites already existed; swapped pass-through for the broadcast check).
  • sort/lib/main.js: 3 insertions / 1 deletion (2-argument form swapped; the 3-argument opts-without-dims form had no else branch, one was added).
  • sorthp/lib/main.js: 3 insertions / 1 deletion (same as sort).

No new imports — maybeBroadcastArray was already imported and used in each file's dims branch.

Scope note: sort/sorthp were not in the original failure report. An independent reviewer found during review that they share the same code pattern and were failing in the same nightly job on the same commit, so the fix was expanded here rather than filed as a second PR for the same defect.

Downstream effect (found during review): the fix also silently repairs 12 previously-failing assertions in @stdlib/blas/ext/to-sorted and @stdlib/blas/ext/to-sortedhp, which delegate to sort/sorthp and had matching broadcast-compatibility test blocks failing for the same reason. Not part of the original CI report — incidental repair, not new scope.

Validation:

  • Full local suites for all 3 changed packages, before/after: circshift 264/270 → 270/270; sort 344/350 → 350/350; sorthp 344/350 → 350/350.
  • Downstream regression check: to-sorted 431/437 → 437/437; to-sortedhp 403/409 → 409/409.
  • examples/index.js for all three changed packages runs cleanly (exit 0).
  • Reviewed by three independent automated reviewers across two rounds (round 2 after the sort/sorthp expansion): correctness (traced the broadcast-array throw path per failing shape, confirmed the zero-dimensional positive path returns the identical object reference and is unaffected), regression-scope (confirmed no other in-repo consumers beyond to-sorted/to-sortedhp, both net-improved), and style/conventions (spacing, idiom, commit message format, copyright headers checked against each file's own dims branch). All three approved in round 2, no blocking findings.

Reviewer notes (non-blocking):

  • The thrown error is a generic Error from maybeBroadcastArray ("Cannot broadcast an array to a shape having fewer dimensions..."). The structurally similar blas/ext/cusum and blas/ext/join throw a more specific TypeError ("...must be a zero-dimensional ndarray") for the equivalent condition. Both satisfy the existing tests (t.throws(fn, Error)) and the chosen approach matches each file's own dims branch, but the error message is not uniform across blas/ext for this condition.
  • None of the three files' JSDoc @throws blocks document a broadcast-incompatibility error. Predates this commit (the dims branch has the same gap); left out of scope for a CI-failure fix.

Checklist

Please ensure the following tasks are completed before submitting this pull request.

AI Assistance

When authoring the changes proposed in this PR, did you use any kind of AI assistance?

  • Yes
  • No

If you answered "yes" above, how did you use AI assistance?

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

Disclosure

If you answered "yes" to using AI assistance, please provide a short disclosure indicating how you used AI assistance. This helps reviewers determine how much scrutiny to apply when reviewing your contribution. Example disclosures: "This PR was written primarily by Claude Code." or "I consulted ChatGPT to understand the codebase, but the proposed changes were fully authored manually by myself.".

This PR was authored by Claude Code (Anthropic) as part of an automated CI-failure investigation and fix routine; all changes were validated against the failing test suite and independently reviewed by three automated reviewer passes before submission.


@stdlib-js/reviewers


Generated by Claude Code

…cond args

The nightly full-matrix `macos_test` job on develop failed with `not
ok` assertions in `blas/ext/circshift`, `blas/ext/sort`, and
`blas/ext/sorthp` test suites, in blocks named "the function throws
an error if provided a `k`/`sortOrder` argument which is not
broadcast-compatible" (and their `(options)` variants). Each package
expected a thrown error for a non-scalar-shaped ndarray second
argument, but none was thrown.

Root cause: in all three packages' `lib/main.js`, when the second
argument is supplied as an ndarray and either no options object or an
options object without a `dims` property is given, the code passed
the ndarray straight through to the base implementation without
checking that it is broadcast-compatible with the (empty) core shape
implied by "operating across all dimensions". The sibling `dims`-
provided branch in each file already performed this check correctly
via `maybeBroadcastArray()`.

This commit routes the no-`dims` code paths in `circshift`, `sort`,
and `sorthp` through `maybeBroadcastArray( arg, [] )`, matching each
file's already-correct `dims` branch, so a non-broadcast-compatible
second argument throws as documented.

Ref: https://github.com/stdlib-js/stdlib/actions/runs/31686732576
@stdlib-bot stdlib-bot added the BLAS Issue or pull request related to Basic Linear Algebra Subprograms (BLAS). label Aug 13, 2026
@stdlib-bot

Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
blas/ext/circshift $\\color{green}263/263$
$\\color{green}+100.00\\%$
$\\color{green}20/20$
$\\color{green}+100.00\\%$
$\\color{green}1/1$
$\\color{green}+100.00\\%$
$\\color{green}263/263$
$\\color{green}+100.00\\%$
blas/ext/sort $\\color{green}381/381$
$\\color{green}+100.00\\%$
$\\color{green}44/44$
$\\color{green}+100.00\\%$
$\\color{green}5/5$
$\\color{green}+100.00\\%$
$\\color{green}381/381$
$\\color{green}+100.00\\%$
blas/ext/sorthp $\\color{green}381/381$
$\\color{green}+100.00\\%$
$\\color{green}44/44$
$\\color{green}+100.00\\%$
$\\color{green}5/5$
$\\color{green}+100.00\\%$
$\\color{green}381/381$
$\\color{green}+100.00\\%$

The above coverage report was generated for the changes in this PR.

@kgryte
kgryte self-requested a review August 14, 2026 00:10
@kgryte
kgryte marked this pull request as ready for review August 14, 2026 00:10
@kgryte
kgryte requested a review from a team August 14, 2026 00:10
@stdlib-bot stdlib-bot added the Needs Review A pull request which needs code review. label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BLAS Issue or pull request related to Basic Linear Algebra Subprograms (BLAS). Needs Review A pull request which needs code review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants