Skip to content
This repository was archived by the owner on Nov 17, 2025. It is now read-only.

Commit 4cda2e5

Browse files
Use the indestructible tag to prevent in-place updates to BroadcastTo output
1 parent 9655d97 commit 4cda2e5

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

aesara/tensor/extra_ops.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,9 @@ def make_node(self, a, *shape):
15751575

15761576
out = type(a.type)(dtype=a.type.dtype, broadcastable=bcast)()
15771577

1578+
# Attempt to prevent in-place operations on this view-based output
1579+
out.tag.indestructible = True
1580+
15781581
return Apply(self, [a] + shape, [out])
15791582

15801583
def perform(self, node, inputs, output_storage):

tests/tensor/test_extra_ops.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
from aesara import function
66
from aesara import tensor as aet
77
from aesara.assert_op import Assert
8+
from aesara.compile.mode import Mode
89
from aesara.configdefaults import config
910
from aesara.gradient import grad
1011
from aesara.graph.basic import applys_between
12+
from aesara.graph.optdb import Query
1113
from aesara.tensor.elemwise import DimShuffle
1214
from aesara.tensor.extra_ops import (
1315
Bartlett,
@@ -41,6 +43,7 @@
4143
unravel_index,
4244
)
4345
from aesara.tensor.math import sum as aet_sum
46+
from aesara.tensor.subtensor import AdvancedIncSubtensor1
4447
from aesara.tensor.type import (
4548
TensorType,
4649
dmatrix,
@@ -1155,3 +1158,22 @@ def test_infer_shape(self):
11551158
[np.random.rand(2, 1, 3).astype(config.floatX), 6, 2, 5, 3],
11561159
self.op_class,
11571160
)
1161+
1162+
def test_inplace(self):
1163+
"""Make sure that in-place optimizations are *not* performed on the output of a ``BroadcastTo``."""
1164+
a = aet.zeros((5,))
1165+
d = aet.vector("d")
1166+
c = aet.set_subtensor(a[np.r_[0, 1, 3]], d)
1167+
b = broadcast_to(c, (5,))
1168+
q = b[np.r_[0, 1, 3]]
1169+
e = aet.set_subtensor(q, np.r_[0, 0, 0])
1170+
1171+
opts = Query(include=["inplace"])
1172+
py_mode = Mode("py", opts)
1173+
e_fn = function([d], e, mode=py_mode)
1174+
1175+
advincsub_node = e_fn.maker.fgraph.outputs[0].owner
1176+
assert isinstance(advincsub_node.op, AdvancedIncSubtensor1)
1177+
assert isinstance(advincsub_node.inputs[0].owner.op, BroadcastTo)
1178+
1179+
assert advincsub_node.op.inplace is False

0 commit comments

Comments
 (0)