Repository navigation
Conversation
6f99a07 to
057605c
Compare
057605c to
90d9ce6
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors the DaCe lowering pipeline for gt4py.next by renaming key lowering entry points and restructuring how builtin-function visitors are dispatched in both the fieldview and iterator lowering paths.
Changes:
- Renames/reshapes lowering entry points (e.g.,
build_sdfg_from_gtir→lower_program_to_sdfg) and adjusts imports/types accordingly. - Refactors builtin dispatch in
GTIRToSDFG(fieldview) andLambdaToDataflow(iterator) via centralized handler maps. - Updates scan/primitives/type helpers to use the split fieldview/iterator lowering modules.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_types.py | Updates local-view helpers to return iterator-based IteratorExpr/MemletExpr types. |
| src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_scan.py | Switches scan lowering to the new fieldview/iterator module split and updated dataflow types. |
| src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_primitives.py | Retypes primitives to the split builders and iterator dataflow edges; small typing-related adjustments. |
| src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_iterator.py | Refactors builtin dispatch in lambda-to-dataflow and retargets builder typing to fieldview interfaces. |
| src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_fieldview.py | Refactors builtin dispatch in program lowering; introduces _visit_* helpers; renames program lowering entry point. |
| src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_concat_where.py | Updates concat_where lowering to use the fieldview lowering module split. |
| src/gt4py/next/program_processors/runners/dace/lowering/init.py | Updates lowering package exports to point at the refactored lowering entry points. |
Comments suppressed due to low confidence (3)
src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_iterator.py:58
gtir_to_sdfg_iterator.pyimportsgtir_to_sdfg_fieldviewusing thesrc.gt4py...package path, which will fail at runtime outside the repository checkout layout. Also, since this module usesfrom __future__ import annotations, this import is only needed for type checking and can be placed underTYPE_CHECKINGto avoid creating an import cycle (fieldview -> primitives -> iterator -> fieldview).
src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_iterator.py:18- The new
TYPE_CHECKING-guarded import forgtir_to_sdfg_fieldview(recommended below) requiresTYPE_CHECKINGto be imported fromtypingin this module.
src/gt4py/next/program_processors/runners/dace/lowering/init.py:23 lowering/__init__.pyre-exportsbuild_sdfg_from_gtirfromgtir_to_sdfg_fieldview, but that function was renamed tolower_program_to_sdfg(andbuild_sdfg_from_gtirno longer exists). This currently breaks imports likegtx_dace_lowering.build_sdfg_from_gtir(...)used elsewhere in the codebase.
from gt4py.next.program_processors.runners.dace.lowering.gtir_to_sdfg_fieldview import (
build_sdfg_from_gtir,
)
from gt4py.next.program_processors.runners.dace.lowering.gtir_to_sdfg_utils import (
flatten_tuple_fields,
get_map_variable,
)
__all__ = [
"build_sdfg_from_gtir",
"flatten_tuple_fields",
"get_map_variable",
]
4d8ca3b to
e92eade
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_fieldview.py:1231
- This comment line has a stray "to." at the end (likely meant to be "symbols."), which makes the sentence ungrammatical.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/gt4py/next/program_processors/runners/dace/lowering/gtir_to_sdfg_iterator.py:52
gtir_to_sdfg_fieldviewis imported here only to satisfy type annotations, but this creates an avoidable import edge (and contributes to circular imports: fieldview -> primitives -> iterator -> fieldview). Since this module usesfrom __future__ import annotations, you can move the import behindtyping.TYPE_CHECKING(or otherwise defer it) to keep runtime imports acyclic.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
|
cscs-ci run default |
Lower an `as_fieldop` whose body is a `reduce` using library nodes instead of a native Python accumulation loop, matching the SDFG lowering: - `dace.libraries.standard.Reduce` for dense connectivities, and - `ReduceWithSkipValues` for connectivities with skip values. The fused schedule-tree reduce `reduce(λ(acc, e0..ek) → op(acc, f(...)), init)(l0..lk)` is decomposed into a per-neighbor element list `map_list(λ → f(...))(l0..lk)` (materialized via the existing ListType path) reduced with WCR `op`. Nested reductions fall back to the native loop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ee lowering" This reverts commit cb24e93.
|
cscs-ci run default |
|
cscs-ci run default |
…op bodies (#2818) ## Summary `DistributedBufferRelocator` can move the final write back of a temporary into a state nested inside a `LoopRegion`. The write back then executes in **every loop iteration** on data that the loop has only written partially, racing with the per-iteration partial writes and producing nondeterministic garbage in the unaffected parts of the output. This is what broke the `scan` tests on the `run_dace_stree_*` backends in #2690 (e.g. [CI run 32715667466](https://github.com/GridTools/gt4py/actions/runs/32715667466)): for a scan, the state that (partially) defines the scan temporary is the scan loop body, and the full-array write back after the loop was relocated into it. **Enabler:** `SDFG.states()` recurses into control-flow scopes (`return list(self.all_states())`), so `find_upstream_states()` now also discovers loop-body states as candidate definition locations — on top-level-only semantics this relocation could never have happened. ## Fix Never relocate into a state that is (transitively) nested inside a `LoopRegion`: `_find_candidates()` now skips such definition states via the new `_is_inside_loop()` helper. Relocation into conditional branches — the use case this pass was designed for — remains legal, as does any relocation into states that are not executed repeatedly. ## Test New unit test `test_distributed_buffer_definition_in_loop` builds the scan-shaped SDFG (per-iteration write of `t[k]` inside a loop body, full write back `t -> b` in the state after the loop) and asserts that the write back stays after the loop and that no write to the output is added inside the loop. The test fails without the fix (the pass relocates into the loop body) and passes with it. ## Validation - New reproducer test: fails without the fix, passes with it. - Full `transformation_tests/` unit suite: 326 passed, 3 xfailed (pre-existing). - On #2690's branch, an equivalent guard made all 32 CI-failing scan tests pass locally (incl. 5/5 stress runs of `test_scan.py::test_solve_triag` and `test_icon_like_scan.py` across all four `run_dace_stree_*` backends).
Summary
Adds a second GTIR→SDFG lowering path for the
gt4py.nextDaCe backend that goes throughDaCe's schedule tree (
ScheduleTreeRoot) instead of building the SDFG directly, andwires six new
run_dace_stree_*backends into the test matrix:run_dace_stree_fview_{cpu,gpu}[_noopt]— fieldview pipeline (as today)run_dace_stree_iview_{cpu,gpu}[_noopt]— with the ITIR common-transforms pipeline(
apply_common_transforms), which is now supported only on the stree loweringThis follows the direction set by the cartesian schedule-tree decision
(ADR: DaCe backends – schedule tree):
express the program's execution schedule at tree level and let
ScheduleTreeRoot.as_sdfg()produce the state machine, so that macro-level optimizations (loop merging, re-ordering)
can later operate on the tree instead of pattern-matching SDFGs.
Design
Direct GTIR → schedule-tree lowering (no intermediate TreeIR), in the new
runners/dace/lowering_stree/module (+5144 lines), alongside the existinglowering/:gtir_to_stree.py—GTIRToScheduleTreevisitor: statements, storage, let-lambdas,dispatch. All program storage is pre-allocated on
root.containers/root.symbols;let-lambdas are inlined into the same root (dict-union shadowing, call stack = implicit
push/pop) — no nested SDFGs produced by the lowering itself. (
as_sdfg()may stillintroduce them downstream; see
scan_carry_scalarization.py.)gtir_to_stree_codegen.py—StreePythonCodegen: each stencil body becomes one Pythoncode string inside a
TaskletNode. No library nodes — reductions are lowereddirectly to tasklet code.
ForScopeinside aMapScope. For scalar leaves the carry lives in ascalar transient that is pre-initialized with
initbefore the loop and read/writteneach iteration. List-typed leaves still read their carry from the result array at the
previous index and therefore keep a
carry if k > start else initternary to guard thefirst iteration. Backward scans are handled as well.
The legacy lowering is untouched by this PR and remains the default.
Test coverage
tests/next_tests/definitions.py, each mapped to a dedicatedDACE_STREE_SKIP_TEST_LISTinBACKEND_SKIP_TEST_MATRIX, so the full next test suiteruns against the stree backends in the
test_next (dace, *)nox sessions.Currently unsupported there (skipped):
USES_LIFT,USES_SCAN_IN_STENCIL,USES_SPARSE_FIELDS,USES_TUPLE_ITERATOR.pytest.mark.uses_dacemarker (GPU onesalso
requires_gpu), so the established nox matrix selection applies to them unchanged.Dependencies
This branch bundles the following transformation-layer fixes, which are still open as
standalone PRs: #2811, #2812, #2813, #2815, #2816, #2817, #2818. Each is a latent hazard
that the stree-lowered SDFGs — structured around regions and boundary states — trip and
that the legacy lowering never produced. They appear in this diff
(
transformations/{simplify,state_fusion,redundant_array_removers,utils}.pyandtest_distributed_buffer_relocator.py); once they merge individually, rebasing will dropthem from here.
The visitor-dispatch refactor this builds on, #2824, has already merged. Note that it
renamed
gtir_dataflow.py→gtir_to_sdfg_lambda.py;gtir_to_sdfg.pykept its name.