@@ -78,7 +78,7 @@ add_test(
7878 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-test.sh"
7979 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
8080 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
81- 3 40 40 NULL 12 6
81+ 3 60 30 NULL 12
8282 ${CMAKE_BINARY_DIR } /lib
8383 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
8484)
@@ -91,15 +91,15 @@ if(_APP_CUDAQ_REALTIME_DISPATCH_LIB
9191 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-test.sh"
9292 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
9393 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
94- 3 60 40 NULL 12 6
94+ 3 60 30 NULL 12
9595 ${CMAKE_BINARY_DIR } /lib
9696 nv-qldpc-decoder
9797 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
9898 )
9999 set_tests_properties (
100100 app_examples.surface_code-1-local-test -distance-3-inproc-rpc
101101 PROPERTIES ENVIRONMENT
102- "CUDAQ_QEC_REALTIME_MODE=inproc_rpc;EXTRA_CLI_ARGS=--use-relay-bp "
102+ "CUDAQ_QEC_REALTIME_MODE=inproc_rpc"
103103 # The wrapper exits 77 on GPUs below compute capability 9.0 (the
104104 # device-graph scheduler needs device-side graph launch); report that
105105 # as SKIPPED rather than FAILED.
@@ -113,7 +113,7 @@ add_test(
113113 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-test.sh"
114114 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
115115 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
116- 3 40 40 NULL 12 6
116+ 3 60 30 NULL 12
117117 ${CMAKE_BINARY_DIR } /lib
118118 sliding_window 6 1
119119 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
@@ -128,7 +128,7 @@ add_test(
128128# bash "${CMAKE_CURRENT_SOURCE_DIR}/surface_code-1-test.sh"
129129# ${CMAKE_CURRENT_BINARY_DIR}/surface_code-1-local
130130# ${CMAKE_CURRENT_BINARY_DIR}/surface_code-1-local
131- # 5 40 40 NULL 20 10
131+ # 5 40 40 NULL 20
132132# ${CMAKE_BINARY_DIR}/lib
133133# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
134134# )
@@ -141,6 +141,80 @@ add_test(
141141 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
142142)
143143
144+ # --------------------------------------------------------------------------- #
145+ # surface_code-1 negative / error-path tests
146+ #
147+ # These drive the three throw sites added to surface_code-1.cpp so that every
148+ # error path is exercised by at least one ctest. Each test asserts BOTH a
149+ # nonzero exit AND the expected diagnostic substring.
150+ # --------------------------------------------------------------------------- #
151+ set (_sc1_exe ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local)
152+ set (_sc1_neg_dir ${CMAKE_CURRENT_BINARY_DIR } /sc1_negative)
153+ file (MAKE_DIRECTORY ${_sc1_neg_dir} )
154+ set (_sc1_neg_env "CUDAQ_DEFAULT_SIMULATOR=stim" )
155+
156+ # Helper: command must exit nonzero AND print the expected diagnostic.
157+ function (_sc1_reject name diagnostic )
158+ add_test (NAME app_examples.surface_code-1-negative-${name}
159+ COMMAND bash -c [==[
160+ diag=$1; shift
161+ if out=$("$@" 2>&1); then
162+ printf '%s\n' "$out"
163+ echo "NEGATIVE TEST FAIL: command returned 0; expected a nonzero exit"
164+ exit 1
165+ fi
166+ printf '%s\n' "$out"
167+ printf '%s' "$out" | grep -qF -- "$diag" || {
168+ echo "NEGATIVE TEST FAIL: missing expected diagnostic: $diag"
169+ exit 1
170+ }
171+ ]==] _ "${diagnostic} " ${_sc1_exe} ${ARGN}
172+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR } )
173+ set_tests_properties (app_examples.surface_code-1-negative-${name}
174+ PROPERTIES ENVIRONMENT "${_sc1_neg_env} " )
175+ endfunction ()
176+
177+ # 1. --load_dem with a nonexistent file → setup_decoders throws.
178+ _sc1_reject (load-dem-missing-file "Could not open dem config file"
179+ --load_dem ${_sc1_neg_dir} /nonexistent.yml
180+ --distance 3 --num_rounds 3 )
181+
182+ # 2. --save_syndrome to an unwriteable path → begin_syndrome_capture throws.
183+ _sc1_reject (save-syndrome-bad-path "Could not open syndrome file for writing"
184+ --distance 3 --num_rounds 3 --num_shots 2
185+ --save_syndrome ${_sc1_neg_dir} /no_such_dir/out.txt )
186+
187+ # 3. --load_syndrome with a nonexistent file → replay_syndrome_file throws.
188+ _sc1_reject (load-syndrome-missing-file "Could not open syndrome file"
189+ --distance 3 --num_rounds 3
190+ --load_syndrome ${_sc1_neg_dir} /nonexistent.txt )
191+
192+ # Fixture: capture a valid d=3 syndrome file, then derive a
193+ # corrections-flipped copy (0↔1 in the CORRECTIONS block).
194+ add_test (NAME app_examples.surface_code-1-negative-replay-fixtures
195+ COMMAND bash -c "set -e
196+ '${_sc1_exe} ' --distance 3 --num_rounds 3 --num_shots 5 \
197+ --save_syndrome '${_sc1_neg_dir} /cap.txt'
198+ sed '/CORRECTIONS_START/,/CORRECTIONS_END/{s/^0$/X/;s/^1$/0/;s/^X$/1/}' \
199+ '${_sc1_neg_dir} /cap.txt' > '${_sc1_neg_dir} /cap_mismatch.txt'"
200+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR } )
201+ set_tests_properties (app_examples.surface_code-1-negative-replay-fixtures
202+ PROPERTIES FIXTURES_SETUP sc1_replay ENVIRONMENT "${_sc1_neg_env} " )
203+
204+ # 4. Replay d=3 capture against d=5 experiment → num_data mismatch (9 vs 25).
205+ _sc1_reject (replay-geometry-mismatch "Syndrome file mismatch"
206+ --distance 5 --num_rounds 5
207+ --load_syndrome ${_sc1_neg_dir} /cap.txt )
208+ set_tests_properties (app_examples.surface_code-1-negative-replay-geometry-mismatch
209+ PROPERTIES FIXTURES_REQUIRED sc1_replay)
210+
211+ # 5. Replay with flipped corrections → correction mismatch throw.
212+ _sc1_reject (replay-correction-mismatch "Replay correction mismatch"
213+ --distance 3 --num_rounds 3
214+ --load_syndrome ${_sc1_neg_dir} /cap_mismatch.txt )
215+ set_tests_properties (app_examples.surface_code-1-negative-replay-correction-mismatch
216+ PROPERTIES FIXTURES_REQUIRED sc1_replay)
217+
144218# End of surface code 1, fully local, regular Stim simulator
145219#------------------------------------------------------------------------------#
146220
@@ -183,19 +257,7 @@ if(TARGET cudaq-qec-realtime-decoding-server-cqr)
183257 nvqir nvqir-stim )
184258 qec_realtime_app_link_options (surface_code-1-cqr )
185259
186- # Enable Relay-BP only when this build provides nv-qldpc support.
187- set (_surface_code_1_cqr_has_nv_qldpc_decoder FALSE )
188- if (TARGET cudaq-qec-nv-qldpc-decoder
189- OR QEC_EXTERNAL_DECODERS
190- OR DEFINED ENV{QEC_EXTERNAL_DECODERS})
191- set (_surface_code_1_cqr_has_nv_qldpc_decoder TRUE )
192- endif ()
193-
194260 set (_surface_code_1_cqr_env CUDAQ_DEVICE_CALL_CHANNEL=host_dispatch)
195- if (TARGET cudaq-qec-realtime-cudevice-proprietary
196- AND _surface_code_1_cqr_has_nv_qldpc_decoder)
197- list (APPEND _surface_code_1_cqr_env EXTRA_CLI_ARGS=--use-relay-bp)
198- endif ()
199261
200262 add_test (
201263 NAME app_examples.surface_code-1-cqr-test-distance-3
@@ -204,7 +266,7 @@ if(TARGET cudaq-qec-realtime-decoding-server-cqr)
204266 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-test.sh"
205267 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-cqr
206268 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-cqr
207- 3 60 40 NULL 12 6
269+ 3 60 30 NULL 12
208270 ${CMAKE_BINARY_DIR } /lib
209271 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
210272 )
@@ -217,14 +279,16 @@ if(TARGET cudaq-qec-realtime-decoding-server-cqr)
217279 add_test (
218280 NAME app_examples.surface_code-1-cqr-two-process-test-distance-3
219281 COMMAND
220- # Non-zero threshold 60 (vs the -local test's 40): unseeded runs at
221- # 1000 shots land ~35-45, so 40 flakes; a broken decode path produces
222- # ~150+, so 60 still discriminates.
282+ # The app seeds the simulator (--seed, default 42), so the run is
283+ # deterministic: ~10 non-zero and ~67 corrections at 1000 shots. The
284+ # thresholds (non-zero <= 60, corrections >= 30) leave margin while
285+ # still catching a broken decode path (which applies ~0 corrections,
286+ # leaving all ~70 raw logical errors uncorrected).
223287 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-cqr-two-process-test.sh"
224288 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-cqr
225- 3 60 40
289+ 3 60 30
226290 $<TARGET_FILE :decoding_server >
227- 12 6
291+ 12
228292 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
229293 )
230294 endif ()
@@ -245,7 +309,7 @@ cudaqx_add_device_code(surface_code-1-quantinuum-emulate
245309 SOURCES
246310 surface_code-1.cpp
247311 COMPILER_FLAGS
248- --target quantinuum --emulate --quantinuum-machine Helios-Fake -DMANUALLY_INJECT_ERRORS=1
312+ --target quantinuum --emulate --quantinuum-machine Helios-Fake
249313 DEPENDS_ON
250314 # Must wait for the local executable to be built because it has the same
251315 # surface_code-1.cpp file, and the nvq++ compiler will use the same filename
@@ -274,7 +338,10 @@ add_test(
274338 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-test.sh"
275339 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
276340 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-quantinuum-emulate
277- 3 0 1000 NULL 12 6
341+ # QIR emulation applies no noise, so the live generate-and-decode run
342+ # finds 0 errors / 0 corrections: this is a lowering + run smoke test
343+ # (matches the distance-5 variant's 0/0 thresholds).
344+ 3 0 0 NULL 12
278345 ${CMAKE_BINARY_DIR } /lib
279346 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
280347)
@@ -285,7 +352,7 @@ add_test(
285352 bash "${CMAKE_CURRENT_SOURCE_DIR } /surface_code-1-test.sh"
286353 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-local
287354 ${CMAKE_CURRENT_BINARY_DIR } /surface_code-1-quantinuum-emulate
288- 5 0 0 NULL 20 10
355+ 5 0 0 NULL 5
289356 ${CMAKE_BINARY_DIR } /lib
290357 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
291358)
0 commit comments