Skip to content

[QEC] Relax surface_code-1 emulate test tolerances for noise-model runs - #776

Merged
bmhowe23 merged 1 commit into
NVIDIA:mainfrom
bmhowe23:bmh/fix-surface-code-1-emulate-noise-tolerances
Aug 7, 2026
Merged

[QEC] Relax surface_code-1 emulate test tolerances for noise-model runs#776
bmhowe23 merged 1 commit into
NVIDIA:mainfrom
bmhowe23:bmh/fix-surface-code-1-emulate-noise-tolerances

Conversation

@bmhowe23

@bmhowe23 bmhowe23 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

The two surface_code-1 --target quantinuum --emulate tests assert that the live generate-and-decode run finds exactly 0 residual logical errors, on the premise recorded in the CMake comment that "QIR emulation applies no noise".

That premise no longer holds on recent CUDA-Q (since NVIDIA/cuda-quantum#5051. surface_code-1 attaches its circuit-level depolarizing noise through a host-side cudaq::noise_model handed to cudaq::run, and the noise model travels on the ExecutionContext

The two surface_code-1 --target quantinuum --emulate tests assert that the
live generate-and-decode run finds exactly 0 residual logical errors, on the
premise recorded in the CMake comment that "QIR emulation applies no noise".

That premise no longer holds on recent CUDA-Q. surface_code-1 attaches its
circuit-level depolarizing noise through a host-side cudaq::noise_model
handed to cudaq::run, and the noise model travels on the ExecutionContext:

  runtime/common/ExecutionContext.h    const noise_model *noiseModel;
  runtime/nvqir/CircuitSimulator.h     noiseModel = context.noiseModel;
                                       if (!noiseModel) return;   // no noise

CUDA-Q's emulated shot loop used to clear the thread-local execution context
for the duration of the loop, as a workaround for qubit deallocation being
skipped while a context is set. With the context cleared the simulator saw a
null noise model and every emulated shot ran noiselessly, which is what the
0-error expectation encoded. NVIDIA/cuda-quantum#5051 removed that workaround
in favour of a typed execution-mode flag, so the context -- and with it the
noise model -- now stays visible and the shots are genuinely noisy.

Nothing about the compiled program changed: the emitted QIR is byte-identical
for p_cnot=0.001 and p_cnot=0.2, and contains no noise operations at all. The
channels are injected by the simulator at runtime, keyed on gate name. Driving
p_cnot to ~0 yields 0 errors and 0 corrections, confirming the circuit itself
is unaffected.

Measured against cuda-quantum@edcb4b1b, the emulated runs now land in the same
regime as the local Stim runs:

  distance 3   emulate 7 non-zero / 56 corrections   local 6 / 71
  distance 5   emulate 12 / 43

So bound the residual logical errors at 60, matching the local tests, and
leave the corrections bound at 0. The corrections bound is a lower bound and
was already vacuous at 0, so this does not weaken any check that was
previously meaningful. Both tests then pass whether or not the CUDA-Q in use
delivers the noise model, which lets this land ahead of any CUDA-Q bump.

surface_code-2 and surface_code-4-yaml are untouched: they apply noise
in-kernel via cudaq::apply_noise, which the erase-noise pass strips before
codegen for both hardware and emulation targets, so they never depended on
the cleared-context behaviour.

Verified with cuda-quantum@edcb4b1b installed:
app_examples.surface_code-1-quantinuum-emulate-test-distance-3-in-process
passes with the new bounds and fails with the old ones.

Signed-off-by: Ben Howe <bhowe@nvidia.com>
@bmhowe23
bmhowe23 merged commit ec5fc99 into NVIDIA:main Aug 7, 2026
24 checks passed
@bmhowe23
bmhowe23 deleted the bmh/fix-surface-code-1-emulate-noise-tolerances branch August 7, 2026 16:09
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