Skip to content

[WIP] DEM from kernel#4602

Draft
khalatepradnya wants to merge 5 commits into
NVIDIA:mainfrom
khalatepradnya:pkhalate/qec-dem-from-kernel
Draft

[WIP] DEM from kernel#4602
khalatepradnya wants to merge 5 commits into
NVIDIA:mainfrom
khalatepradnya:pkhalate/qec-dem-from-kernel

Conversation

@khalatepradnya
Copy link
Copy Markdown
Collaborator

No description provided.

@khalatepradnya khalatepradnya force-pushed the pkhalate/qec-dem-from-kernel branch 2 times, most recently from 9a507f7 to 3e71d7a Compare May 26, 2026 23:15
@NVIDIA NVIDIA deleted a comment from github-actions Bot May 26, 2026
@khalatepradnya khalatepradnya force-pushed the pkhalate/qec-dem-from-kernel branch from 3e71d7a to b327041 Compare May 26, 2026 23:54
khalatepradnya and others added 5 commits May 26, 2026 23:47
… entry

Add `__quantum__qis__mz_handle__to__register` (returns `i64` directly)
alongside the sentinel-pointer `__quantum__qis__mz` so `quake.mz ->
!cc.measure_handle` lowerings carry a chronological measurement index
that the QEC adapters added in NVIDIA#4564 can resolve. Discriminate of a
handle goes through the spec-canonical `__quantum__rt__read_result`
runtime function (not the adaptive-profile `__qis__read_result__body`)
to keep full-QIR codegen aligned with the QIR specification.

Adds `CircuitSimulatorBase::getMeasureIndex()` virtual with
`std::numeric_limits<std::int64_t>::max()` sentinel, matching
`cudaq::measure_handle::index`'s "unbound" convention. Stim overrides
return `committed + pending - 1`.

Required for the upcoming `cudaq::dem_from_kernel` analysis primitive.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Pradnya Khalate <pkhalate@nvidia.com>
Add a `nvqir::dem::make_scope` factory that returns an `AnalysisScope`
backed by an on-demand-loaded NVQIR plugin (default: stim). On entry,
the scope resets the plugin simulator's `nvqir::RecordedCircuit` so
the next run starts from an empty circuit; on exit it releases the
thread-local simulator slot.

Mirrors `nvqir::resource_counter::make_scope`. The `dlopen` of
`libnvqir-<plugin>.so` lets the analysis engine work in processes that
do not eager-link the simulator target.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Pradnya Khalate <pkhalate@nvidia.com>
Add the `cudaq::dem_from_kernel(kernel, noise = nullptr, args...)` API
that runs a CUDA-Q kernel through the Stim NVQIR plugin under an
`nvqir::dem::make_scope` and returns the resulting detector error model
as a UTF-8 string in Stim's standard `.dem` file format.

- Public header `runtime/cudaq/algorithms/dem.h`: templated overloads
  plus an inline `dlopen` shim that resolves the type-erased core from
  `libcudaq-analysis` on first use (no eager Stim link for callers
  that never invoke the API). Platform-portable `.so`/`.dylib` lookup.
- Type-erased core `runtime/cudaq/analysis/Dem.cpp` + new
  `libcudaq-analysis` shared library: serializes concurrent DEM calls,
  drives the kernel through the analysis scope, hands the recorded
  Stim circuit to `ErrorAnalyzer::circuit_to_detector_error_model`,
  returns `DetectorErrorModel::str()`.
- Python binding `cudaq.dem_from_kernel(kernel, noise_model=None,
  *args) -> str`.
- Integration tests on `nvq++`-compiled kernels (trivial, noisy
  detector, multi-handle, multi-round memory experiment, vectorized,
  non-Clifford diagnostic) in C++ and Python.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Pradnya Khalate <pkhalate@nvidia.com>
Add `"dem"` to the analysis-scope allowlist on the REST transport so a
host callback issued from inside an analysis-driven kernel does not
trip the resource-counter-only guard. Skip the per-target pipeline in
the Python QPU launcher when the active execution context is `"dem"`,
since target pipelines that mark the `qec` dialect illegal would
reject `qec.detector` / `qec.observable` / `qec.pair_detectors` ops
that DEM analysis must preserve.
Adds a Python builder-mode test and a Python emulate-target test for
`cudaq.dem_from_kernel`, plus a backend regression test on the IonQ
transport that mirrors the existing resource-counter regression.
Co-authored-by: Cursor <cursoragent@cursor.com>

Signed-off-by: Pradnya Khalate <pkhalate@nvidia.com>
PR NVIDIA#4566 added the `cudaq::make_kernel().detector(...)` /
`.logical_observable(...)` / `.detectors(...)` C++ builder API, but the
JIT pipeline in `kernel_builder.cpp` still used the legacy
`createConvertToQIR` pass which carries no QEC patterns. Builder
kernels using QEC ops therefore failed to JIT-compile with `failed to
legalize operation 'qec.detector'`.

Swap the legacy pass for `addConvertToQIRAPIPipeline` + an explicit
`createCCToLLVM`, matching the codegen path Python kernels already use.
The 297 BuilderTester tests all still pass, and the dem_from_kernel
integration test now covers the C++ builder mode with both the scalar
`.detector` / `.logical_observable` and the paired-stdvec
`.detectors(prev, curr)` forms.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Pradnya Khalate <pkhalate@nvidia.com>
@khalatepradnya khalatepradnya force-pushed the pkhalate/qec-dem-from-kernel branch from f1f6be4 to 3c7211f Compare May 27, 2026 07:41
@NVIDIA NVIDIA deleted a comment from github-actions Bot May 27, 2026
@NVIDIA NVIDIA deleted a comment from copy-pr-bot Bot May 27, 2026
@github-actions
Copy link
Copy Markdown

CI Summary (push) — ❌ failed

Run #26497860912 · ✅ 5 · ⏩ 7 · ❌ 1 · ⛔ 0

❌ Failed or cancelled
Job Result Link
build_and_test ❌ failure view
Top-level jobs (13)
Job Result
binaries ⏩ skipped
build_and_test ❌ failure
config_devdeps ✅ success
config_source_build ⏩ skipped
config_wheeldeps ✅ success
devdeps ✅ success
docker_image ⏩ skipped
gen_code_coverage ⏩ skipped
metadata ✅ success
python_metapackages ⏩ skipped
python_wheels ⏩ skipped
source_build ⏩ skipped
wheeldeps ✅ success
⏩ Skipped jobs (7) — intentionally skipped on PR builds; run on merge_group / workflow_dispatch
Job
binaries
config_source_build
docker_image
gen_code_coverage
python_metapackages
python_wheels
source_build
All sub-jobs (42) — every matrix leg, with links
Job Status Link
Build and test (amd64, gcc12, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, gcc12, openmpi) / Dev environment (Python) ❌ failure view
Build and test (amd64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, llvm, openmpi) / Dev environment (Python) ❌ failure view
Build and test (arm64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (arm64, llvm, openmpi) / Dev environment (Python) ❌ failure view
CI Summary ❔ in_progress view
Configure build (devdeps) ✅ success view
Configure build (source_build) ⏩ skipped view
Configure build (wheeldeps) ✅ success view
Create CUDA Quantum installer ⏩ skipped view
Create Docker images ⏩ skipped view
Create Python metapackages ⏩ skipped view
Create Python wheels ⏩ skipped view
Gen code coverage ⏩ skipped view
Load dependencies (amd64, gcc12) / Caching ✅ success view
Load dependencies (amd64, gcc12) / Finalize ✅ success view
Load dependencies (amd64, gcc12) / Metadata ✅ success view
Load dependencies (amd64, llvm) / Caching ✅ success view
Load dependencies (amd64, llvm) / Finalize ✅ success view
Load dependencies (amd64, llvm) / Metadata ✅ success view
Load dependencies (arm64, gcc12) / Caching ✅ success view
Load dependencies (arm64, gcc12) / Finalize ✅ success view
Load dependencies (arm64, gcc12) / Metadata ✅ success view
Load dependencies (arm64, llvm) / Caching ✅ success view
Load dependencies (arm64, llvm) / Finalize ✅ success view
Load dependencies (arm64, llvm) / Metadata ✅ success view
Load source build cache ⏩ skipped view
Load wheel dependencies (amd64, 12.6) / Caching ✅ success view
Load wheel dependencies (amd64, 12.6) / Finalize ✅ success view
Load wheel dependencies (amd64, 12.6) / Metadata ✅ success view
Load wheel dependencies (amd64, 13.0) / Caching ✅ success view
Load wheel dependencies (amd64, 13.0) / Finalize ✅ success view
Load wheel dependencies (amd64, 13.0) / Metadata ✅ success view
Load wheel dependencies (arm64, 12.6) / Caching ✅ success view
Load wheel dependencies (arm64, 12.6) / Finalize ✅ success view
Load wheel dependencies (arm64, 12.6) / Metadata ✅ success view
Load wheel dependencies (arm64, 13.0) / Caching ✅ success view
Load wheel dependencies (arm64, 13.0) / Finalize ✅ success view
Load wheel dependencies (arm64, 13.0) / Metadata ✅ success view
Prepare cache clean-up ❔ in_progress view
Retrieve PR info ✅ success view
⚠️ Required checks (3/6) — 3 missing — declared in .github/required-checks.yml for push
Required check Status Link
Build and test (amd64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, llvm, openmpi) / Dev environment (Python) ❌ failure view
Build and test (arm64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (arm64, llvm, openmpi) / Dev environment (Python) ❌ failure view
Build and test (amd64, gcc12, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, gcc12, openmpi) / Dev environment (Python) ❌ failure view

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