Skip to content

Commit d6be6ce

Browse files
fetches Stim directly with FetchContent when libstim is not already available
Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
1 parent f6d7fdf commit d6be6ce

4 files changed

Lines changed: 34 additions & 4 deletions

File tree

libs/qec/lib/CMakeLists.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
set(LIBRARY_NAME cudaq-qec)
1010

11+
include(FetchContent)
12+
1113
add_compile_options(-Wno-attributes)
1214

1315
find_package(CUDAToolkit REQUIRED)
@@ -59,18 +61,28 @@ list(APPEND QEC_SOURCES
5961
# FIXME?: This must be a shared library. Trying to build a static one will fail.
6062
add_library(${LIBRARY_NAME} SHARED ${QEC_SOURCES})
6163

62-
add_subdirectory(decoders/plugins/example)
63-
add_subdirectory(decoders/plugins/pymatching)
64+
if(NOT TARGET libstim)
65+
FetchContent_Declare(
66+
stim
67+
GIT_REPOSITORY https://github.com/quantumlib/Stim.git
68+
GIT_TAG v1.15.0
69+
EXCLUDE_FROM_ALL
70+
)
71+
FetchContent_MakeAvailable(stim)
72+
endif()
6473

6574
if(NOT TARGET libstim)
6675
message(FATAL_ERROR
67-
"libstim target not available; required by cudaq-qec for Stim DEM parsing.")
76+
"Stim FetchContent did not provide the libstim target.")
6877
endif()
6978
target_link_libraries(${LIBRARY_NAME} PRIVATE libstim)
7079
target_link_options(${LIBRARY_NAME} PRIVATE
7180
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:-Wl,--exclude-libs,libstim.a>
7281
)
7382

83+
add_subdirectory(decoders/plugins/example)
84+
add_subdirectory(decoders/plugins/pymatching)
85+
7486
# The TRT decoder plugin honors the tri-state `CUDAQ_QEC_BUILD_TRT_DECODER`
7587
# cache variable (AUTO/ON/OFF) declared in the parent CMakeLists.txt. Skip
7688
# descending entirely when the user explicitly opted out; otherwise let the

libs/qec/lib/decoder_stim_dem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dem_default_values dem_defaults_for_missing_keys(
1717
const std::function<bool(const std::string &)> &contains_user_key,
1818
const detector_error_model &dem) {
1919
dem_default_values out;
20-
if (!contains_user_key("O"))
20+
if (!contains_user_key("O") && dem.num_observables() > 0)
2121
out.O = &dem.observables_flips_matrix;
2222
if (!contains_user_key("error_rate_vec"))
2323
out.error_rate_vec = &dem.error_rates;

libs/qec/python/tests/test_decoder.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,5 +836,13 @@ def test_get_decoder_from_stim_dem_user_O_wins_over_dem_derived():
836836
qec.get_decoder_from_stim_dem("pymatching", dem_text, O=bad_O)
837837

838838

839+
def test_get_decoder_from_stim_dem_without_observables_returns_errors():
840+
decoder = qec.get_decoder("pymatching", "error(0.1) D0\n")
841+
842+
result = decoder.decode([1.0])
843+
assert result.converged is True
844+
assert list(result.result) == [1.0]
845+
846+
839847
if __name__ == "__main__":
840848
pytest.main()

libs/qec/unittests/test_decoders.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,16 @@ error(0.1) L0 L0
821821
<< "duplicate L0 in error 1 should XOR-cancel to 0";
822822
}
823823

824+
TEST(StimDemDecoderFactory, DemWithoutObservablesDoesNotAddODefault) {
825+
auto dem = cudaq::qec::dem_from_stim_text("error(0.1) D0\n");
826+
auto defaults = cudaq::qec::dem_defaults_for_missing_keys(
827+
[](const std::string &) { return false; }, dem);
828+
829+
EXPECT_EQ(defaults.O, nullptr);
830+
ASSERT_NE(defaults.error_rate_vec, nullptr);
831+
EXPECT_EQ(defaults.error_rate_vec->size(), 1u);
832+
}
833+
824834
TEST(StimDemDecoderFactory, ThrowsOnProbabilityOutOfRange) {
825835
const std::string dem_text = "error(1.5) D0\n";
826836
EXPECT_THROW(

0 commit comments

Comments
 (0)