Skip to content

Commit fa85b07

Browse files
committed
Fix JAX AdvancedIncSubtensor crashing on a 0d update
set_subtensor(x[idx_vector], 1.0) raises AttributeError: 'float' object has no attribute 'shape' under the JAX backend. The update input is a 0d TensorType, so _check_runtime_broadcast_of_vector_index is entitled to a value with a .shape, but jax_typify downgrades 0d arrays to Python scalars before the op ever sees them. Coerce y back to an array at the dispatch, which is the layer that knows it is handing linker values to a check written against arrays. The .item() in jax_typify is load-bearing for dispatches that need a static Python scalar (axis/shape/loop-bound arguments), so it is left alone.
1 parent a85bc78 commit fa85b07

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

pytensor/link/jax/dispatch/subtensor.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import jax.numpy as jnp
2+
13
from pytensor.link.jax.dispatch.basic import jax_funcify
24
from pytensor.tensor.subtensor import (
35
AdvancedIncSubtensor,
@@ -60,7 +62,11 @@ def incsubtensor(x, y, *ilist, jax_fn=jax_fn, idx_list=op.idx_list):
6062
indices = indices[0]
6163

6264
if isinstance(op, AdvancedIncSubtensor):
63-
op._check_runtime_broadcast_of_vector_index(node, x, y, indices)
65+
# jax_typify downgrades 0d arrays to Python scalars, which have no .shape,
66+
# so re-arrayify y for a check that is written against array values.
67+
op._check_runtime_broadcast_of_vector_index(
68+
node, x, jnp.asarray(y), indices
69+
)
6470

6571
return jax_fn(x, indices, y)
6672

tests/link/jax/test_subtensor.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,26 @@ def test_jax_IncSubtensor():
225225
compare_jax_and_py([], [out_pt], [])
226226

227227

228+
@pytest.mark.parametrize(
229+
"func", (pt_subtensor.advanced_inc_subtensor1, pt_subtensor.advanced_set_subtensor1)
230+
)
231+
def test_jax_AdvancedIncSubtensor1_scalar_y(func):
232+
"""A 0d update must not trip the runtime-broadcast check.
233+
234+
The check is written against array values, but ``jax_typify`` turns a 0d array into a
235+
Python scalar, which has no ``.shape``.
236+
"""
237+
from pytensor import function
238+
239+
x = pt.zeros((5,))
240+
out = func(x, 1.0, np.array([1, 3]))
241+
242+
res = function([], out, mode="JAX")()
243+
expected = np.zeros(5)
244+
expected[[1, 3]] = 1.0
245+
np.testing.assert_allclose(res, expected)
246+
247+
228248
@pytest.mark.parametrize(
229249
"func", (pt_subtensor.advanced_inc_subtensor1, pt_subtensor.advanced_set_subtensor1)
230250
)

0 commit comments

Comments
 (0)