Supported subset¶
Anything outside this subset is rejected with a precise diagnostic (line/column + caret) — never silently miscompiled.
| Scalar construct | Vectorized equivalent |
|---|---|
+ - * / (and unary - +) |
same operators |
x ** y |
xp.pow(x, y) |
x // y, x % y |
xp.floor_divide, xp.remainder (Python sign semantics) |
& \| ^ << >> ~ |
same operators (integer inputs) |
abs, round, min, max |
xp.abs, xp.round, exact left-folded xp.minimum/xp.maximum |
int(x), float(x), bool(x) |
xp.astype(x, xp.int64/float64/bool) (truncation toward zero) |
math.sqrt, math.exp, math.expm1, math.log, math.log1p, math.log2, math.log10, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan, math.atan2, math.sinh, math.cosh, math.tanh, math.asinh, math.acosh, math.atanh, math.pow, math.floor, math.ceil, math.hypot, math.copysign, math.isnan, math.isinf, math.isfinite |
corresponding xp.* |
math.trunc(x) |
xp.astype(x, xp.int64) |
math.pi, math.e, math.tau, math.inf, math.nan |
literals (xp.inf / xp.nan for the last two) |
comparisons, chains (a < b < c) |
elementwise; chains fold with xp.logical_and |
and / or / not |
exact value-select lowering (xp.where(x != 0, y, x)); xp.logical_* when both operands are boolean |
ternary a if c else b |
xp.where(coerce(c), a, b) |
if/elif/else, early return |
nested xp.where merges |
assignment, += etc. |
SSA rebinding (x, x_1, x_2, ...) |
for i in range(N) (N constant) |
a real loop in the generated source; loop-carried variables become explicit phis |
| call to another pure scalar function | recursively vectorized, memoized by function object |
| closure/global scalars | frozen as constants at generation time |
| closure/global arrays | hidden keyword parameters with bound defaults |
Not supported (rejected)¶
while, break/continue, return inside loop bodies, side effects,
comprehensions/generators, *args/**kwargs, try, match, walrus,
f-strings, subscripts, tuple/list/set/dict literals, tuple returns,
global/nonlocal, statements after return, annotated assignments,
non-literal defaults, str/None/complex literals, bare if x:
truthiness (write if x != 0:), recursive helper calls, and
round(x, n) (decimals= is not in the Array API standard).
Exactness in the numeric edges¶
min/max over mixed operands and boolean arithmetic do not lower to
bare xp.minimum/operator calls: strict backends reject mixed-dtype
promotion and boolean arithmetic, and naive casts lose exactness.
Instead the lowering emits small runtime helpers
(architecture) that compute exact
results whenever a single dtype can hold them, and produce a documented
float64 fallback only for
genuinely unrepresentable per-lane results.