Skip to content

fix[next-dace]: do not apply DoubleWriteRemover if the destination is read in the Map - #2816

Open
edopao wants to merge 2 commits into
GridTools:mainfrom
edopao:fix/double-write-remover-war
Open

fix[next-dace]: do not apply DoubleWriteRemover if the destination is read in the Map#2816
edopao wants to merge 2 commits into
GridTools:mainfrom
edopao:fix/double-write-remover-war

Conversation

@edopao

@edopao edopao commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Description

DoubleWriteRemover distributes the final write of an intermediate transient buffer into the producing Map, i.e. the destination access node is written directly by each Map iteration. If the destination is also read inside the Map scope, this creates a write-after-read hazard: independent branches inside a Map scope can be scheduled in arbitrary (insertion) order, so the read may observe the newly written value instead of the original one, producing silently wrong results.

This showed up as wrong numerical output in the icon4py stencil tests with the dace backend (e.g. extrapolate_temporally_exner_pressure): stencils computing an auxiliary output from a field they also update in place read the already-overwritten value.

The fix rejects the transformation when any final consumer is read inside the Map scope. The scope scan recurses into nested scopes and skips ExitNodes, whose in-edges carry the data written by the scope rather than reads into it.

A unit test reproducing the hazard pattern is added: a Map produces a transient b in one branch and reads c through an independent branch, followed by the write back c[:] = b[:]. Without this fix the transformation is applied despite the hazard (the test fails with nb_applied == 1), with the fix the buffer is kept and the transformation does not apply.

Requirements

  • All fixes and/or new features come with corresponding tests.
  • Important design decisions have been documented in the appropriate ADR inside the docs/development/ADRs/ folder.

…is read in the Map

The `DoubleWriteRemover` transformation distributes the final write of an
intermediate transient buffer into the producing Map, i.e. the destination
access node is written directly by each Map iteration. If the destination is
also read inside the Map scope, this creates a write-after-read hazard: the
read may observe the newly written value instead of the original one, because
DaCe does not order independent branches within a Map body (this was observed
to produce silently wrong results with larger fused maps, where the write was
emitted before the read).

Reject the transformation when any final consumer is read inside the Map
scope. The scope scan recurses into nested scopes and skips ExitNodes, whose
in-edges carry the data written by the scope rather than reads into it.

Add a regression test that reproduces the issue: a Map producing a transient
`b` in one branch and reading `c` in an independent branch, followed by the
write back `c[:] = b[:]`. Without the fix the transformation applies, which
the test now forbids.
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.

1 participant