Skip to content

feat[next-dace]: Support external memory for transient arrays - #2719

Open
edopao wants to merge 25 commits into
mainfrom
dace_ext_memory_staging
Open

feat[next-dace]: Support external memory for transient arrays#2719
edopao wants to merge 25 commits into
mainfrom
dace_ext_memory_staging

Conversation

@edopao

@edopao edopao commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces a new "external workspace" memory mode for DaCe transients in the gt4py.next DaCe backend, allowing users to provide their own workspace buffers and thereby avoid per-call GPU memory allocation overhead. The change is documented in a new ADR and is implemented by extending the transient memory mode enum, updating backend and compilation workflows, and making the memory management API more flexible and explicit. The pull request also cleans up and unifies transient memory handling throughout the codebase.

The most important changes are:

External Workspace Memory Mode (EXTERNAL) Implementation:

  • Introduced a new TransientMemoryMode enum with an EXTERNAL option, allowing users to supply their own workspace buffers for DaCe transients. This is documented in a detailed ADR (docs/development/ADRs/next/0027-External_Workspace_Memory.md) and referenced in the ADR index. [1] [2] [3]
  • Updated the auto-optimization and post-processing pipeline to support the new transient memory mode, including logic for configuring transient lifetimes and workspace installation. [1] [2] [3] [4] [5] [6] [7]

Backend and Compilation Workflow Updates:

  • Added a new load_artifact method to the Backend class, allowing backends to inject runtime data (such as external workspaces) into loaded programs. The DaCe backend overrides this to install the user-supplied workspace.
  • Modified CompiledProgramsPool to use the backend's load_artifact method instead of directly calling artifact.load(), ensuring that all loaded programs receive the correct workspace configuration. [1] [2]

API and Import Cleanup:

  • Updated imports and __all__ lists to expose the new TransientMemoryMode and the refactored utility function for configuring transient lifetimes, replacing the previous persistent-only approach. [1] [2] [3]

These changes collectively provide a more flexible, efficient, and explicit mechanism for managing workspace memory in DaCe-based GT4Py workflows, particularly for repeated or multi-program GPU workloads.

@edopao
edopao requested a review from Copilot July 28, 2026 08:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@edopao
edopao force-pushed the dace_ext_memory_staging branch 5 times, most recently from f331eb9 to 63f4bf5 Compare July 29, 2026 13:23

@egparedes egparedes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good. I just some comments and questions, I guess mostly for me to understand some decisions

Comment thread src/gt4py/next/otf/compiled_program.py Outdated
Comment thread src/gt4py/next/otf/compiled_program.py Outdated
Comment thread src/gt4py/next/otf/compiled_program.py Outdated
Comment thread src/gt4py/next/program_processors/runners/dace/workflow/compilation.py Outdated
Comment thread src/gt4py/next/program_processors/runners/dace/workflow/compilation.py Outdated
Comment thread src/gt4py/next/program_processors/runners/dace/transformations/auto_optimize.py Outdated
@edopao
edopao requested a review from egparedes July 31, 2026 09:50
@edopao
edopao force-pushed the dace_ext_memory_staging branch 2 times, most recently from 617e411 to 0ea8985 Compare August 3, 2026 08:05
@edopao
edopao requested a review from Copilot August 3, 2026 08:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

Suppressed comments (10)

src/gt4py/next/program_processors/runners/dace/workflow/backend.py:147

  • transient_memory_mode is checked with is not here; use value equality so callers can pass a string value (the enum is str, Enum) without silently bypassing the intended warning path.
    elif transient_memory_mode := optimization_args.get("transient_memory_mode"):
        if transient_memory_mode is not gtx_transformations.TransientMemoryMode.EXTERNAL:

src/gt4py/next/program_processors/runners/dace/workflow/compilation.py:178

  • The RuntimeError suggests calling set_external_workspace(), but that method is on DaCeDecoratedProgram / injected via the backend, not on CompiledDaceProgram itself. The message should point callers to the correct API entry point.
            if self.external_workspace is None:
                raise RuntimeError(
                    "External workspace is not set. Please call `set_external_workspace()`"
                    " before the first call to the program."
                )

src/gt4py/next/program_processors/runners/dace/workflow/backend.py:142

  • make_dace_backend compares transient_memory_mode using is, which will fail when the value comes in as an equivalent string (e.g. from config/CLI) rather than the exact Enum singleton, causing the EXTERNAL/workspace validation to be skipped.

This issue also appears on line 146 of the same file.

    if external_workspace is None:
        if (
            optimization_args.get("transient_memory_mode")
            is gtx_transformations.TransientMemoryMode.EXTERNAL
        ):

src/gt4py/next/program_processors/runners/dace/workflow/backend.py:40

  • DaCeBackend.load_artifact always injects an empty dict when external_workspace is None, which defeats the downstream "workspace is not set" guard (it becomes "device not found") and can make failures harder to understand.
    def load_artifact(self, artifact: stages.CompilationArtifact) -> stages.ExecutableProgram:
        program = super().load_artifact(artifact)
        assert isinstance(program, gtx_wfddecoration.DaCeDecoratedProgram)
        # Inject the backend-level workspace so it is used when arguments are constructed.
        program.set_external_workspace(self.external_workspace or {})

src/gt4py/next/program_processors/runners/dace/workflow/compilation.py:80

  • Using assert here turns a missing GPU device type into an AssertionError (and can be stripped with -O). This should be a proper runtime error so external workspace setup fails predictably.

This issue also appears on line 174 of the same file.

    elif storage == dace.StorageType.GPU_Global:
        assert core_defs.CUPY_DEVICE_TYPE is not None
        device = core_defs.CUPY_DEVICE_TYPE
    else:

src/gt4py/next/program_processors/runners/dace/workflow/compilation.py:100

  • The _validate_external_workspace docstring claims an alignment check and references request.nbytes/request.alignment, but the function currently only validates array-interface presence and (optionally) nbytes. This documentation should match the actual checks.
        ValueError: If ``wsp`` is smaller than ``request.nbytes`` or its
            base pointer is not aligned to ``request.alignment`` bytes.

src/gt4py/next/program_processors/runners/dace/workflow/compilation.py:107

  • The TypeError message still refers to an "External memory allocator" returning the buffer, but the new API passes a workspace buffer directly. This wording is misleading for users debugging invalid workspace objects.
        raise TypeError(
            f"External memory allocator returned {type(wsp).__name__!r} for storage "
            f"{storage!r}, which does not expose `__array_interface__` or "
            f"`__cuda_array_interface__`."
        )

src/gt4py/next/program_processors/runners/dace/workflow/decoration.py:36

  • The docstring says teardown is forwarded so the pool can release external workspaces, but external workspace lifetime is explicitly caller-owned (and ExecutableProgram is just a Callable). This sentence is misleading.
    program. Teardown is forwarded to the underlying ``CompiledDaceProgram``
    so that the generic otf pool -- which only sees this callable -- can
    release external-memory workspaces when the pool is finalized.

tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_backend.py:375

  • In the EXTERNAL/CPU branch the comment says external-memory API calls should replace host malloc/free, but the assertions currently require new/malloc and delete/free to appear. This makes the test validate the opposite of what the comment (and EXTERNAL mode intent) describes.
                # CPU external mode should route transient workspace setup via
                # external-memory API calls rather than host malloc/free calls.
                assert any(marker in generated_code for marker in ("new ", "malloc"))
                assert any(marker in generated_code for marker in ("delete ", "free"))

src/gt4py/next/program_processors/runners/dace/transformations/auto_optimize.py:121

  • TransientMemoryMode docs state SCOPED is the default strategy, but gt_auto_optimize currently defaults to TransientMemoryMode.POOL. Either the default or the documentation should be aligned.
    - `SCOPED`: Transients are allocated and deallocated in the scope of the SDFG
        where they are defined, being it the top-level SDFG or a nested one.
        This is the default strategy.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Suppressed comments (4)

tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_compilation.py:437

  • There is no unit test that a host-only workspace (only __array_interface__) is rejected when the SDFG requests GPU_Global workspace. Without this, a regression could silently accept an invalid buffer for GPU storage.
def test_construct_arguments_accepts_gpu_workspace():
    """A device workspace with matching size is accepted and installed."""
    workspace = _make_array_buffer(nbytes=128, cuda=True)
    program = _make_compiled_program(
        external_workspace={core_defs.DeviceType.CUDA: workspace},
        workspace_sizes={dace.StorageType.GPU_Global: 128},
    )

src/gt4py/next/program_processors/runners/dace/workflow/decoration.py:72

  • The comment refers to fun.csdfg_args, but the attribute is csdfg_argv. This makes the first-call logic harder to follow when debugging.
            # NOTE: If this is the first time then we will generate an exception because
            #   `fun.csdfg_args` is `None`
            # TODO(phimuell, edopao): Think about refactor the code such that the update
            #   of the argument vector is a Method of the `CompiledDaceProgram`.
            self._update_sdfg_call_args(args, self._fun.csdfg_argv, offset_provider)  # type: ignore[arg-type]  # Will error out in first call.

src/gt4py/next/program_processors/runners/dace/transformations/utils.py:69

  • The TODO says “Find out why scalars are processed”, but this branch is taken for data nodes that are not arrays or scalars. This is misleading when reading the lifetime-selection logic.
                desc = dnode.desc(nsdfg)
                if not desc.transient or type(desc) not in {dace.data.Array, dace.data.Scalar}:
                    # TODO(phimuell): Find out why scalars are processed.
                    not_modify_lifetime.add(dnode.data)
                    continue

tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_backend.py:395

  • The comment says CPU external mode should use external-memory APIs “rather than host malloc/free calls”, but the assertions below currently require new/malloc and delete/free markers to be present. Either the comment or the assertions should be adjusted so they describe the same expected behavior.
                # CPU external mode should route transient workspace setup via
                # external-memory API calls rather than host malloc/free calls.
                assert any(marker in generated_code for marker in ("new ", "malloc"))
                assert any(marker in generated_code for marker in ("delete ", "free"))

Comment thread src/gt4py/next/program_processors/runners/dace/workflow/compilation.py Outdated
edopao added 13 commits August 4, 2026 15:18
This pull request introduces a more flexible and extensible way to
control the allocation and lifetime of transient arrays in the DaCe
backend, replacing the previous `make_persistent` and `gpu_memory_pool`
options with a new `TransientMemoryMode` policy. It also adds support
for externally managed memory via an `external_memory_allocator`
parameter, and refactors related utility functions to support these
changes.

**API and Configuration Improvements:**

* Introduced the `TransientMemoryMode` enum to specify transient array
lifetime/allocation strategies (`SCOPED`, `PERSISTENT`, `POOL`,
`EXTERNAL`), and replaced the `make_persistent` and `gpu_memory_pool`
parameters throughout the codebase with this unified approach.
[[1]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706R114-R127)
[[2]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L133)
[[3]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L177-R185)
[[4]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L197)
[[5]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L403-L409)
[[6]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L921-L923)
[[7]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L942-R963)
[[8]](diffhunk://#diff-c7967b0fa16e0de89cb43f3c81e9aee884122772946f031d50fb31d1cb16215bR20)
[[9]](diffhunk://#diff-c7967b0fa16e0de89cb43f3c81e9aee884122772946f031d50fb31d1cb16215bR123)

* Added support for an `external_memory_allocator` parameter in the DaCe
backend and workflow, which allows users to provide custom allocation
logic for external memory. This is validated to only be used with
`transient_memory_mode=external`.
[[1]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbR40)
[[2]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbR52)
[[3]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbR67)
[[4]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbR82-R83)
[[5]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbR120-R138)
[[6]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR184)
[[7]](diffhunk://#diff-91264fda895ecc56c869858ac9724e1ff60ed6514a121d1cd4f323197053e5aaR38)
[[8]](diffhunk://#diff-91264fda895ecc56c869858ac9724e1ff60ed6514a121d1cd4f323197053e5aaR77)

**Utility Function Refactoring:**

* Refactored the persistent transients utility into a more general
`_gt_configure_transient_lifetime` function, which now supports both
`Persistent` and `External` lifetimes. Exposed two public functions:
`gt_make_transients_persistent` and the new
`gt_make_transients_external`.
[[1]](diffhunk://#diff-6ce6c03a192e5b5b7e735ecc3aa1071dc7ce0ac5d90f206f948b1e3f8e952637L29-R39)
[[2]](diffhunk://#diff-6ce6c03a192e5b5b7e735ecc3aa1071dc7ce0ac5d90f206f948b1e3f8e952637L84-R70)
[[3]](diffhunk://#diff-c7967b0fa16e0de89cb43f3c81e9aee884122772946f031d50fb31d1cb16215bL87-R88)
[[4]](diffhunk://#diff-c7967b0fa16e0de89cb43f3c81e9aee884122772946f031d50fb31d1cb16215bR137)

**Documentation and Safety:**

* Updated docstrings and comments to reflect the new transient memory
modes and clarify the behavior and constraints of each mode, including
safety considerations when using global-lifetime transients.
[[1]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L177-R185)
[[2]](diffhunk://#diff-6ce6c03a192e5b5b7e735ecc3aa1071dc7ce0ac5d90f206f948b1e3f8e952637L84-R70)

These changes make the backend's memory management more robust and
adaptable, and lay the groundwork for advanced use cases such as
externally managed memory.
This pull request introduces support for external workspace memory
allocation in the DaCe backend, allowing users to provide custom memory
allocators for transient workspaces. It updates the compilation workflow
to use an external allocator when configured, ensures workspaces are
only allocated once, and adds comprehensive tests for the new
functionality. The changes also improve device type handling and test
coverage for transient memory modes.

**External workspace allocator integration:**
* Added an `external_memory_allocator` parameter to
`CompiledDaceProgram` and `DaCeCompilationArtifact`, allowing external
allocation of workspace memory buffers. Workspaces are now tracked and
only allocated once per compiled program instance.
(`src/gt4py/next/program_processors/runners/dace/workflow/compilation.py`
[[1]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR88-R96)
[[2]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR116-R137)
[[3]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR194-R207)
[[4]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR299)
* Implemented the `_map_workspace_storage_to_device` helper to map DaCe
storage types to device types for allocation.
(`src/gt4py/next/program_processors/runners/dace/workflow/compilation.py`
[src/gt4py/next/program_processors/runners/dace/workflow/compilation.pyR50-R61](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR50-R61))
* Ensured external workspaces are configured during argument
construction and only set up once.
(`src/gt4py/next/program_processors/runners/dace/workflow/compilation.py`
[src/gt4py/next/program_processors/runners/dace/workflow/compilation.pyR146](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR146))

**Testing and validation:**
* Added tests to verify that external workspace allocation works as
intended, including correct device routing, error propagation, and
single allocation per program instance.
(`tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_compilation.py`
[tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_compilation.pyR235-R311](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3R235-R311))
* Extended backend tests to check that different transient memory modes
(EXTERNAL, POOL, PERSISTENT, SCOPED) use the correct allocation APIs and
honor the external allocator, with device-specific checks for CPU and
GPU.
(`tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_backend.py`
[tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_backend.pyR213-R378](diffhunk://#diff-19fed38498781ceef82337d097e43458274d2ebe7e0bae4578839e9fbed15194R213-R378))

**Device type handling improvements:**
* Updated device type selection in tests to use
`core_defs.CUPY_DEVICE_TYPE` for GPU tests, ensuring compatibility with
the available GPU backend.
(`tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_backend.py`
[tests/next_tests/unit_tests/program_processor_tests/runners_tests/dace_tests/test_dace_backend.pyR26-R43](diffhunk://#diff-19fed38498781ceef82337d097e43458274d2ebe7e0bae4578839e9fbed15194R26-R43))

These changes make the DaCe backend more flexible and robust by
supporting custom workspace allocation, improving test coverage, and
ensuring correct behavior across memory modes and device types.
This pull request introduces a new "External Memory Allocator" mode for
DaCe transients in the `gt4py.next` backend, allowing explicit,
caller-managed workspace allocation and teardown. This enables reusing a
single workspace buffer across multiple SDFGs, removing per-call
allocation overhead and providing more control over memory lifetime. The
public API now exposes a typed allocator protocol, and the backend
enforces that allocators are picklable to ensure compatibility with
process-based compilation. The changes also include explicit pool-driven
teardown of resources and improved error handling for allocator
pickling.

**External Memory Allocator for DaCe Transients**

*Design and API additions:*
- Added an explicit `EXTERNAL` mode to `TransientMemoryMode`, backed by
a caller-supplied `ExternalMemoryAllocator` protocol. This protocol is
defined with typed `allocate` and `deallocate` methods and requires
picklability.
(`[[1]](diffhunk://#diff-b86bd892b20495d184cedc1d9057e4b1ef0e837d723e998628332943d900aa74R1-R147)`,
`[[2]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706R117-R178)`,
`[[3]](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706L133-R202)`)
- Introduced `AllocationRequest` and `Buffer` type alias to formalize
the workspace allocation contract.
(`[src/gt4py/next/program_processors/runners/dace/transformations/auto_optimize.pyR117-R178](diffhunk://#diff-ddbc0e8ab1d5b89929dfbd12477936ae3acad531911fa9afb125066b6fe74706R117-R178)`)
- Re-exported `AllocationRequest`, `Buffer`, and
`ExternalMemoryAllocator` from the `transformations` package for public
use.
(`[[1]](diffhunk://#diff-c7967b0fa16e0de89cb43f3c81e9aee884122772946f031d50fb31d1cb16215bL16-R19)`,
`[[2]](diffhunk://#diff-c7967b0fa16e0de89cb43f3c81e9aee884122772946f031d50fb31d1cb16215bR95-R99)`)

*Backend and resource management:*
- Updated the DaCe backend to accept an `ExternalMemoryAllocator`
instance, with improved documentation and type safety.
(`[[1]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbL67-R66)`,
`[[2]](diffhunk://#diff-04258cb5c4aa36c40ab7da9246c27d69866a707135824bba4f76d46e93de72fbL82-R85)`)
- Added a check to ensure the allocator is picklable at backend
construction, raising a clear error if not.
(`[src/gt4py/next/program_processors/runners/dace/workflow/compilation.pyR43-R75](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dR43-R75)`)
- Implemented explicit resource teardown: when a `CompiledProgramsPool`
is deleted, any compiled programs with a `finalize()` method have it
called to release external resources, with warnings on failure.
(`[[1]](diffhunk://#diff-cae915aa5b7a62aa4a6eb295978c894fc43270cf6e08e82fca56414bf37d7cdeR88-R113)`,
`[[2]](diffhunk://#diff-cae915aa5b7a62aa4a6eb295978c894fc43270cf6e08e82fca56414bf37d7cdeR404-R417)`)

*Documentation:*
- Added ADR 0026 documenting the rationale, design, and consequences of
the external memory allocator feature.
(`[docs/development/ADRs/next/0026-External_Memory_Allocator.mdR1-R147](diffhunk://#diff-b86bd892b20495d184cedc1d9057e4b1ef0e837d723e998628332943d900aa74R1-R147)`)

These changes provide a robust, explicit, and user-extensible mechanism
for managing transient workspace memory in DaCe-based workflows,
improving performance and resource control for advanced use cases.
edopao and others added 12 commits August 4, 2026 15:18
…der fingerprint (#2739)

This pull request refactors and improves the GPU trace marker logic in
the DaCe compilation workflow, enhances test coverage, and clarifies
test parameterization. The main functional change is to ensure that the
fingerprint of the build folder includes the modified SDFG after
applying the GPU transaction markers. This way, enabling or not the GPU
transaction markers results in different build artifacts. Tests are
updated to reflect the new marker application logic and to ensure that
build artifacts change when relevant compilation settings differ.

**DaCe compilation logic improvements:**

* Refactored `_add_tx_markers` to take and return an `ExtensionSource`,
only modifying the SDFG if GPU scheduling is detected, and returning a
new `ExtensionSource` with updated SDFG JSON.
* Updated the main DaCe compiler logic to call `_add_tx_markers` only
when GPU trace markers are requested and the device type is GPU,
ensuring markers are not redundantly applied.
[[1]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dL200-R222)
[[2]](diffhunk://#diff-89b749ff9b80be5fdb8a7e0d05411d2b992b6a5892f819c7a3e001c4241a6c0dL218-R235)

**Test suite improvements:**

* Refactored tests to use a real `program_source` fixture and removed
unnecessary mocks and spies, directly verifying the presence or absence
of GPU TX markers on the compiled SDFG.
[[1]](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3L82-R83)
[[2]](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3R100-L109)
[[3]](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3L119-L123)
[[4]](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3L138-L173)
* Added new tests to assert that identical compilation inputs produce
the same artifact, and that changing instrumentation or compiler flags
results in different artifacts.
[[1]](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3R181-R203)
[[2]](diffhunk://#diff-57ff279a6de9ce815a6bde8ae126007687da1d07f6ad28626e998541fc9d89b3R213-R248)

**Test parameterization and device naming:**

* Updated device type parameterization in both compilation and
translation tests to use consistent and descriptive IDs (`CPU`, `GPU`,
`CUDA`, `ROCM`) and to use the correct device type constants.
[[1]](diffhunk://#diff-19fed38498781ceef82337d097e43458274d2ebe7e0bae4578839e9fbed15194L31-R33)
[[2]](diffhunk://#diff-8ba502dd24c52188c94e85f0bcd66c31fbe3093077168033f99c14eb19ac1cb4L54-R55)

These changes improve the correctness, maintainability, and clarity of
both the DaCe compilation workflow and its associated tests.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@edopao
edopao force-pushed the dace_ext_memory_staging branch from f909c37 to 73a16cc Compare August 4, 2026 13:18
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.

3 participants