Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion libs/qec/include/cudaq/qec/realtime/decoding_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ struct decoder_config {
std::string type;
uint64_t block_size = 0;
uint64_t syndrome_size = 0;
uint64_t num_syndromes_per_round = 0;
std::vector<std::int64_t> H_sparse;
std::vector<std::int64_t> O_sparse;
std::optional<std::vector<std::int64_t>> D_sparse;
Expand Down
13 changes: 0 additions & 13 deletions libs/qec/lib/realtime/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ struct MappingTraits<cudaq::qec::decoding::config::decoder_config> {
io.mapRequired("type", config.type);
io.mapRequired("block_size", config.block_size);
io.mapRequired("syndrome_size", config.syndrome_size);
io.mapRequired("num_syndromes_per_round", config.num_syndromes_per_round);
io.mapRequired("H_sparse", config.H_sparse);
io.mapRequired("O_sparse", config.O_sparse);
io.mapOptional("D_sparse", config.D_sparse);
Expand Down Expand Up @@ -425,18 +424,6 @@ struct MappingTraits<cudaq::qec::decoding::config::decoder_config> {
INIT_AND_MAP_DECODER_CUSTOM_ARGS(
cudaq::qec::decoding::config::sliding_window_config);
}

// Validate that the number of syndromes per round is less than or equal to
// the syndrome size and >= 0.
if (config.num_syndromes_per_round < 0 ||
config.num_syndromes_per_round > config.syndrome_size) {
throw std::runtime_error(
"num_syndromes_per_round (" +
std::to_string(config.num_syndromes_per_round) +
") is not greater than 0 and less than or equal to syndrome_size (" +
std::to_string(config.syndrome_size) + ") for decoder " +
std::to_string(config.id));
}
}
};

Expand Down
14 changes: 2 additions & 12 deletions libs/qec/lib/realtime/realtime_decoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,8 @@ int configure_decoders(
if (decoder_config.D_sparse.has_value()) {
new_decoder->set_D_sparse(*decoder_config.D_sparse);
} else {
// Auto-generate a hard-wired D_sparse.
auto num_rounds = decoder_config.syndrome_size /
decoder_config.num_syndromes_per_round;
CUDAQ_INFO("Auto-generating D_sparse for decoder {} with "
"num_syndromes_per_round {} and num_rounds {}",
decoder_config.id, decoder_config.num_syndromes_per_round,
num_rounds);
std::vector<std::int64_t> D_sparse =
cudaq::qec::generate_timelike_sparse_detector_matrix(
decoder_config.num_syndromes_per_round, num_rounds,
/*include_first_round=*/false);
new_decoder->set_D_sparse(D_sparse);
throw std::runtime_error(
"D_sparse must be provided in decoder configuration");
}

// Invoke a dummy decoding operation to force the decoder to be
Expand Down
2 changes: 0 additions & 2 deletions libs/qec/python/bindings/py_decoding_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ void bindDecodingConfig(py::module &mod) {
.def_readwrite("type", &decoder_config::type)
.def_readwrite("block_size", &decoder_config::block_size)
.def_readwrite("syndrome_size", &decoder_config::syndrome_size)
.def_readwrite("num_syndromes_per_round",
&decoder_config::num_syndromes_per_round)
.def_readwrite("H_sparse", &decoder_config::H_sparse)
.def_readwrite("O_sparse", &decoder_config::O_sparse)
.def_readwrite("D_sparse", &decoder_config::D_sparse)
Expand Down
9 changes: 3 additions & 6 deletions libs/qec/python/tests/test_decoders_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def create_test_empty_decoder_config(decoder_id):
config.type = "single_error_lut"
config.block_size = 20
config.syndrome_size = 10
config.num_syndromes_per_round = config.syndrome_size

# Create sparse H matrix representation from a zero matrix
H = np.zeros((config.syndrome_size, config.block_size), dtype=np.uint8)
Expand All @@ -80,8 +79,7 @@ def create_test_empty_decoder_config(decoder_id):

# Generate timelike sparse detector matrix
config.D_sparse = qec.generate_timelike_sparse_detector_matrix(
config.num_syndromes_per_round, 2, include_first_round=False)

config.syndrome_size, 2, include_first_round=False)
return config


Expand Down Expand Up @@ -219,7 +217,6 @@ def test_sliding_window_decoder():
config.type = "sliding_window"
config.block_size = n_cols
config.syndrome_size = n_rows
config.num_syndromes_per_round = n_syndromes_per_round

# Convert PCM to sparse representation
config.H_sparse = qec.pcm_to_sparse_vec(pcm)
Expand All @@ -228,8 +225,8 @@ def test_sliding_window_decoder():
O = np.zeros((2, n_cols), dtype=np.uint8)
config.O_sparse = qec.pcm_to_sparse_vec(O)

# Reset D_sparse for sliding window (set to None to indicate it's not used)
config.D_sparse = None
config.D_sparse = qec.generate_timelike_sparse_detector_matrix(
config.syndrome_size, 2, include_first_round=False)

# Sliding window config
sw_config = qec.qecrt.config.sliding_window_config()
Expand Down
12 changes: 4 additions & 8 deletions libs/qec/python/tests/test_decoding_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,9 @@ def test_configure_valid_multi_error_lut_decoders():
dc.type = "multi_error_lut"
dc.block_size = 10
dc.syndrome_size = 3
dc.num_syndromes_per_round = 3
dc.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
dc.D_sparse = qec.generate_timelike_sparse_detector_matrix(
dc.syndrome_size, 2, include_first_round=False)
dc.set_decoder_custom_args(nv)

mdc = qec.multi_decoder_config()
Expand All @@ -195,7 +196,6 @@ def test_decoder_config_yaml_roundtrip_and_custom_args():
dc.type = "nv-qldpc-decoder"
dc.block_size = 10
dc.syndrome_size = 3
dc.num_syndromes_per_round = 3
dc.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
dc.set_decoder_custom_args(nv)

Expand All @@ -210,7 +210,6 @@ def test_decoder_config_yaml_roundtrip_and_custom_args():
assert dc2.type == "nv-qldpc-decoder"
assert dc2.block_size == 10
assert dc2.syndrome_size == 3
assert dc2.num_syndromes_per_round == 3

# Recover NV config from decoder_custom_args (it's already the config object)
nv2 = dc2.decoder_custom_args
Expand All @@ -236,7 +235,6 @@ def test_multi_decoder_config_yaml_roundtrip():
d1.type = "nv-qldpc-decoder"
d1.block_size = 10
d1.syndrome_size = 3
d1.num_syndromes_per_round = 3
d1.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
d1.set_decoder_custom_args(nv)

Expand All @@ -248,7 +246,6 @@ def test_multi_decoder_config_yaml_roundtrip():
d2.type = "multi_error_lut"
d2.block_size = 10
d2.syndrome_size = 3
d2.num_syndromes_per_round = 3
d2.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
d2.set_decoder_custom_args(lut_config)

Expand Down Expand Up @@ -280,7 +277,6 @@ def test_configure_decoders_from_str_smoke():
decoder_config.type = "nv-qldpc-decoder"
decoder_config.block_size = 10
decoder_config.syndrome_size = 3
decoder_config.num_syndromes_per_round = 3
decoder_config.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
decoder_config.set_decoder_custom_args(nv)
yaml_str = decoder_config.to_yaml_str()
Expand Down Expand Up @@ -310,8 +306,9 @@ def test_configure_valid_decoders():
dc.type = "multi_error_lut"
dc.block_size = 10
dc.syndrome_size = 3
dc.num_syndromes_per_round = 3
dc.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
dc.D_sparse = qec.generate_timelike_sparse_detector_matrix(
dc.syndrome_size, 2, include_first_round=False)
lut_config = qec.multi_error_lut_config()
lut_config.lut_error_depth = 2
dc.set_decoder_custom_args(lut_config)
Expand All @@ -336,7 +333,6 @@ def test_configure_invalid_decoders():
decoder_config.type = "invalid-decoder"
decoder_config.block_size = 10
decoder_config.syndrome_size = 3
decoder_config.num_syndromes_per_round = 3
decoder_config.H_sparse = [1, 2, 3, -1, 6, 7, 8, -1, -1]
decoder_config.set_decoder_custom_args(nv)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ void save_dem_to_file(const cudaq::qec::detector_error_model &dem,
config.type = "multi_error_lut";
config.block_size = dem.num_error_mechanisms();
config.syndrome_size = dem.num_detectors();
config.num_syndromes_per_round = numSyndromesPerRound;
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(dem.detector_error_matrix);
config.O_sparse =
cudaq::qec::pcm_to_sparse_vec(dem.observables_flips_matrix);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ void save_dem_to_file(const cudaq::qec::detector_error_model &dem,
config.type = "multi_error_lut";
config.block_size = dem.num_error_mechanisms();
config.syndrome_size = dem.num_detectors();
config.num_syndromes_per_round = numSyndromesPerRound;
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(dem.detector_error_matrix);
config.O_sparse =
cudaq::qec::pcm_to_sparse_vec(dem.observables_flips_matrix);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ create_decoder_config(uint64_t id, const cudaq::qec::detector_error_model &dem,
config.type = "multi_error_lut";
config.block_size = dem.num_error_mechanisms();
config.syndrome_size = dem.num_detectors();
config.num_syndromes_per_round = numSyndromesPerRound;
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(dem.detector_error_matrix);
config.O_sparse = cudaq::qec::pcm_to_sparse_vec(dem.observables_flips_matrix);
config.D_sparse = det_mat;
Expand Down
1 change: 0 additions & 1 deletion libs/qec/unittests/realtime/app_examples/surface_code_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ def save_dem_to_file(dem, dem_filename, numSyndromesPerRound, num_logical):
config.type = "multi_error_lut"
config.block_size = dem.num_error_mechanisms()
config.syndrome_size = dem.num_detectors()
config.num_syndromes_per_round = numSyndromesPerRound
config.H_sparse = qec.pcm_to_sparse_vec(dem.detector_error_matrix)
config.O_sparse = qec.pcm_to_sparse_vec(dem.observables_flips_matrix)
config.D_sparse = qec.generate_timelike_sparse_detector_matrix(
Expand Down
7 changes: 3 additions & 4 deletions libs/qec/unittests/test_decoders_yaml.cpp
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,12 @@ create_test_empty_decoder_config(int id) {
config.type = "single_error_lut";
config.block_size = 20;
config.syndrome_size = 10;
config.num_syndromes_per_round = config.syndrome_size;
cudaqx::tensor<uint8_t> H({config.syndrome_size, config.block_size});
cudaqx::tensor<uint8_t> O({2, config.block_size});
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(H);
config.O_sparse = cudaq::qec::pcm_to_sparse_vec(O);
config.D_sparse = cudaq::qec::generate_timelike_sparse_detector_matrix(
config.num_syndromes_per_round, 2, /*include_first_round=*/false);
config.syndrome_size, 2, /*include_first_round=*/false);
return config;
}

Expand Down Expand Up @@ -208,7 +207,6 @@ TEST(DecoderYAMLTest, SlidingWindowDecoder) {
config.type = "sliding_window";
config.block_size = n_cols;
config.syndrome_size = n_rows;
config.num_syndromes_per_round = n_syndromes_per_round;

// Sliding window config
config.decoder_custom_args =
Expand All @@ -219,7 +217,8 @@ TEST(DecoderYAMLTest, SlidingWindowDecoder) {
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(pcm);
config.O_sparse =
cudaq::qec::pcm_to_sparse_vec(cudaqx::tensor<uint8_t>({2, n_cols}));
config.D_sparse.reset();
config.D_sparse = cudaq::qec::generate_timelike_sparse_detector_matrix(
config.syndrome_size, 2, /*include_first_round=*/false);
sw_config.window_size = 1;
sw_config.step_size = 1;
sw_config.num_syndromes_per_round = n_syndromes_per_round;
Expand Down