Skip to content

array API: add positive, logical_xor, trunc, count_nonzero, diff, full_like#3730

Merged
zcbenz merged 4 commits into
ml-explore:mainfrom
katlun-lgtm:array-api-new-ops
Jun 28, 2026
Merged

array API: add positive, logical_xor, trunc, count_nonzero, diff, full_like#3730
zcbenz merged 4 commits into
ml-explore:mainfrom
katlun-lgtm:array-api-new-ops

Conversation

@katlun-lgtm

Copy link
Copy Markdown
Contributor

Summary

Focused split from #3684. Adds six new ops required by the Python array API standard that have substantive implementations (not pure aliases).

Op Implementation
positive mx::astype(a, a.dtype()) — copy with same dtype (shallow copy semantics per @zcbenz's comment on #3684)
logical_xor not_equal(bool(a), bool(b))
trunc where(a < 0, ceil(a), floor(a)) — truncate toward zero
count_nonzero sum(not_equal(a, 0).astype(int32)) with axis/keepdims support
diff n-th discrete difference via slice subtraction; supports prepend/append
full_like mx::full(a.shape(), vals) with optional dtype override

Files changed

  • python/src/ops.cpp — C++ lambda registrations in init_ops()
  • docs/src/python/ops.rst — alphabetical entries
  • python/tests/test_ops.pytest_array_api_elementwise, test_diff, test_array_api_creation (full_like part)

Related

Split from #3684 per reviewer feedback from @zcbenz.

@katlun-lgtm katlun-lgtm mentioned this pull request Jun 20, 2026
4 tasks

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ops that are not pure aliases should have C++ versions and then exposed in python

@katlun-lgtm katlun-lgtm force-pushed the array-api-new-ops branch 4 times, most recently from 1c52b70 to 76d436c Compare June 23, 2026 03:54
@zcbenz

zcbenz commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Most of this PR looks good to me, but same with #3731 (comment) would you mind removing the append/prepend args of diff?

katlun-lgtm added a commit to katlun-lgtm/mlx that referenced this pull request Jun 26, 2026
Per maintainer request (ml-explore#3730), remove the prepend/append parameters and
the second diff() overload. diff is now diff(a, n, axis, stream) only;
callers that need edge padding can concatenate before calling.
@katlun-lgtm

Copy link
Copy Markdown
Contributor Author

Done — removed the prepend/append arguments and the second diff overload. diff is now just diff(a, n, axis, stream). Thanks for the review!

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

katlun-lgtm and others added 4 commits June 28, 2026 13:16
…f, full_like

New elementwise and utility ops required by the Python array API standard
(https://data-apis.org/array-api/latest/):

- positive: unary plus, returns a copy (mx::astype to same dtype)
- logical_xor: element-wise XOR via not_equal(bool(a), bool(b))
- trunc: truncate toward zero (where(a < 0, ceil, floor))
- count_nonzero: count non-zero elements; returns int32; supports axis/keepdims
- diff: n-th discrete difference along an axis, with optional prepend/append
- full_like: fill an array shaped like the input; optional dtype override

Docs and tests included.

Part of the array API split from ml-explore#3684.
Per zcbenz review: ops that are not pure aliases must have C++
implementations exposed through the usual mlx/ops.h + mlx/ops.cpp
path, not inline Python-binding lambdas.

- positive: array copy (like __copy__)
- logical_xor: not_equal(astype(a,bool_), astype(b,bool_))
- trunc: where(less(a,0), ceil, floor); integers returned as-is
- count_nonzero: sum(not_equal(a,0).astype(int32)) with axis overloads
- diff: n-th slice subtraction with optional prepend/append
- full_like: delegates to existing mx::full_like C++ overload

Python bindings in python/src/ops.cpp now call the C++ functions
instead of duplicating the logic inline.
Per maintainer request (ml-explore#3730), remove the prepend/append parameters and
the second diff() overload. diff is now diff(a, n, axis, stream) only;
callers that need edge padding can concatenate before calling.
@zcbenz zcbenz force-pushed the array-api-new-ops branch from 2713894 to a1151b5 Compare June 28, 2026 04:29
@zcbenz zcbenz merged commit e94b415 into ml-explore:main Jun 28, 2026
16 checks passed
@katlun-lgtm katlun-lgtm deleted the array-api-new-ops branch June 28, 2026 12:06
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.

2 participants