Skip to content

Sync dev-milestone with master - #3076

Merged
ndgrigorian merged 10 commits into
dev-milestonefrom
master
Sep 24, 2026
Merged

ndgrigorian merged 10 commits into
dev-milestonefrom
master

Conversation

@xaleryb

@xaleryb xaleryb commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Syncs dev-milestone with the current master (bfa29d30f70).

dev-milestone carries no commits of its own — it is 10 behind master and 0 ahead — so this is a fast-forward sync, not an integration merge. No conflicts, and the branch tip becomes identical to master.

Commits brought in:

antonwolfy and others added 10 commits September 7, 2026 13:52
The array API conformance job skipped
`test_dlpack.py::test_dunder_dlpack` as a workaround for a bug in the
test itself (tracked in
[array-api-tests#457](data-apis/array-api-tests#457)):
the test pinned the requested `dl_device` to `kDLCPU` while drawing
`copy` from `{True, False, None}`, so on a SYCL device (reported as
`kDLOneAPI`) the `copy=False` case forced a cross-device transfer and
the spec-mandated `BufferError` was counted as a failure.

The upstream test has since been fixed to tolerate `BufferError` only
when `copy is False` and the requested device differs from the array's
own `__dlpack_device__()` — behavior dpnp already implements correctly
by delegating to dpctl. The conformance job checks out the
array-api-tests default branch without pinning a ref, so the fix is
already picked up on new runs and the skip is now dead weight.

This change removes only that entry. The remaining `tanh` special-case
skip is unrelated (an open array-api spec issue) and is left in place.
In the `dpnp.linalg.norm` implementation, the 2-norm and Frobenius-norm
branches computed `sqrt(sum(...))` (or `sqrt(dot(...))` on the
`axis=None` fast path) allocating a fresh array for the `sqrt` output on
top of the array already produced by the reduction.

These branches now capture the reduction (or dot) result and pass it
back as `out=` to `dpnp.sqrt`, so the intermediate buffer is reused as
the output instead of allocating a new one. The reused buffer is a
private, unaliased array in every case, and its dtype matches the `sqrt`
output, so the in-place write is safe. On the `axis=None` fast path the
reused buffer is a scalar, so the change there is for consistency.

This is an allocation saving only; it does not change results or reduce
the number of kernel launches.
## Summary

`dpnp.cumsum`, `dpnp.cumprod`, and their `nan`/`cumulative_*` variants
(including `dpnp.tensor.cumulative_sum`/`cumulative_prod`) could
silently return incorrect results when accumulating along an axis of a
multi-row array, with no error raised. The corruption is triggered when
the accumulation axis is long enough to require three or more reduction
levels in the internal block-scan (axis length greater than `chunk_size
** 2`, where `chunk_size = wg_size * n_wi`, i.e. roughly a million
elements on GPU and about four million on CPU) and the array has more
than one batch row. The elementwise total is conserved but redistributed
across rows.

## Root cause

In the batched scan driver `inclusive_scan_iter` (`accumulators.hpp`),
the intermediate block-scan fixup `update_local_chunks` passed a
`NoOpIndexer` for the per-row (iter) offset into the `src` buffer. The
intermediate block-scan buffers, however, are laid out strided per row
with a stride of `src_size`. The `local_scans` read already used the
correct `iter_gid * local_stride` offset, but the `src` write offset was
unstrided, so rows overwrote each other. This cancels out only when
`iter_nelems == 1` (a single row) or when fewer than three levels are
needed, which is why the bug went unnoticed.

## Fix

Give `update_local_chunks` a `Strided1DIndexer{iter_nelems, src_size}`
for the row offset instead of the `NoOpIndexer` (the within-row
`out_indexer` stays `NoOp`, since the level buffers are contiguous
within a row).
…p.histogram2d (#3064)

Fixes several documentation rendering issues.

- `dpnp.ndarray` operator methods documented their behavior with a
`:math:` role wrapping the expression in `\text{...}`. In LaTeX/MathJax
math mode `&`, `^`, and `%` are special, so `__and__`, `__xor__`,
`__mod__` and their variants rendered as error strings or truncated
text. These are plain Python operator snippets, so they now render as
inline code literals; all operator dunder docstrings were converted for
consistency.
- `dpnp.histogram2d` and `dpnp.left_shift` were missing the blank line
before their `Returns` section, so numpydoc did not parse it as a
section header.
One more minor layout issue detected during an app-testing in comparison
to numpy behavior:

Fixes: #3056
Boolean arrays may contain non-zero bytes like `0x02` or `0xFF` that
NumPy treats as True but dpnp does not.

Fixes #3054
Two `See Also` entries used `obj:` instead of `:obj:` (missing the
leading colon), so Sphinx did not recognize the cross-reference role and
rendered it as literal `obj:` text in the API docs:

- `dpnp.argsort` — the `dpnp.take_along_axis` entry rendered as "…from
obj: dpnp.argsort…"
- `dpnp.histogram` — the `dpnp.histogram_bin_edges` entry rendered as
"…by the obj:dpnp.histogram function"

Adding the missing colon makes both render as proper cross-reference
links. This is a docstring-only change with no functional impact.
This PR improves `dpnp.einsum` performance by avoiding a copy into
C-order.

Commit 039b7f1 (#3058) remaps `order="K"` to `"C"` which turned the
final `dpnp.asarray` from a no-op into a full device copy because dpnp
contracts operands in reverse order so `"ij,jk"` computes `(a @ b).T`
and the result is naturally `f-contiguous`

This PR builds the result directly in the requested layout instead of
fixing it afterwards. The last contraction determines the output axis
order, so it can choose which operand is on the left side of the matmul
and avoid an extra copy.
This is only applied for `"C"` order, since for other layouts the
default operand order already matches the expected `order="K" +
optimize=True` behavior. The swap does not move any data. It only
changes the operand order in the matmul
Replaced with modern f-strings
@xaleryb
xaleryb requested a review from antonwolfy as a code owner September 24, 2026 16:46
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

View rendered docs @ https://intelpython.github.io/dpnp/index.html

@github-actions

Copy link
Copy Markdown
Contributor

Array API standard conformance tests for dpnp=0.21.0dev8=py314ha0e2e8e_11 ran successfully.
Passed: 1376
Failed: 0
Skipped: 6

@coveralls

Copy link
Copy Markdown
Collaborator

Coverage Status

Coverage is 78.479% — master into dev-milestone. No base build found for dev-milestone.

@ndgrigorian
ndgrigorian merged commit 31ef426 into dev-milestone Sep 24, 2026
191 of 216 checks passed
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.

7 participants