Skip to content

Commit 6648209

Browse files
committed
code examples fixed and integrated
Signed-off-by: Kevin Mato <[email protected]>
1 parent 5f92ae5 commit 6648209

File tree

3 files changed

+157
-223
lines changed

3 files changed

+157
-223
lines changed

docs/sphinx/examples/qec/cpp/real_time_complete.cpp

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <common/NoiseModel.h>
2020
#include <fstream>
2121

22+
// [Begin Save DEM]
2223
// Save decoder configuration to YAML file
2324
void save_dem(const cudaq::qec::detector_error_model &dem,
2425
const std::string &filename) {
@@ -30,35 +31,39 @@ void save_dem(const cudaq::qec::detector_error_model &dem,
3031
config.syndrome_size = dem.num_detectors();
3132
config.H_sparse = cudaq::qec::pcm_to_sparse_vec(dem.detector_error_matrix);
3233
config.O_sparse = cudaq::qec::pcm_to_sparse_vec(dem.observables_flips_matrix);
33-
34+
3435
// Calculate numRounds from DEM (we send 1 additional round, so add 1)
35-
uint64_t numSyndromesPerRound = 2; // Z0Z1 and Z1Z2
36+
uint64_t numSyndromesPerRound = 2; // Z0Z1 and Z1Z2
3637
auto numRounds = dem.num_detectors() / numSyndromesPerRound + 1;
3738
config.D_sparse = cudaq::qec::generate_timelike_sparse_detector_matrix(
3839
numSyndromesPerRound, numRounds, false);
39-
40+
4041
cudaq::qec::decoding::config::multi_error_lut_config lut_config;
4142
lut_config.lut_error_depth = 2;
4243
config.decoder_custom_args = lut_config;
43-
44+
4445
cudaq::qec::decoding::config::multi_decoder_config multi_config;
4546
multi_config.decoders.push_back(config);
46-
47+
4748
std::ofstream file(filename);
4849
file << multi_config.to_yaml_str(200);
4950
file.close();
5051
printf("Saved config to %s\n", filename.c_str());
5152
}
53+
// [End Save DEM]
5254

55+
// [Begin Load DEM]
5356
// Load decoder configuration from YAML file
5457
void load_dem(const std::string &filename) {
5558
std::ifstream file(filename);
5659
std::string yaml((std::istreambuf_iterator<char>(file)),
5760
std::istreambuf_iterator<char>());
58-
auto config = cudaq::qec::decoding::config::multi_decoder_config::from_yaml_str(yaml);
61+
auto config =
62+
cudaq::qec::decoding::config::multi_decoder_config::from_yaml_str(yaml);
5963
cudaq::qec::decoding::config::configure_decoders(config);
6064
printf("Loaded config from %s\n", filename.c_str());
6165
}
66+
// [End Load DEM]
6267

6368
// Prepare logical |0⟩
6469
__qpu__ void prep0(cudaq::qec::patch logical) {
@@ -68,72 +73,86 @@ __qpu__ void prep0(cudaq::qec::patch logical) {
6873
}
6974

7075
// Measure ZZ stabilizers for 3-qubit repetition code
71-
__qpu__ std::vector<cudaq::measure_result> measure_stabilizers(
72-
cudaq::qec::patch logical) {
76+
__qpu__ std::vector<cudaq::measure_result>
77+
measure_stabilizers(cudaq::qec::patch logical) {
7378
for (std::size_t i = 0; i < logical.ancz.size(); ++i) {
7479
cudaq::reset(logical.ancz[i]);
7580
}
76-
81+
7782
// Z0Z1 stabilizer
7883
cudaq::x<cudaq::ctrl>(logical.data[0], logical.ancz[0]);
7984
cudaq::x<cudaq::ctrl>(logical.data[1], logical.ancz[0]);
80-
85+
8186
// Z1Z2 stabilizer
8287
cudaq::x<cudaq::ctrl>(logical.data[1], logical.ancz[1]);
8388
cudaq::x<cudaq::ctrl>(logical.data[2], logical.ancz[1]);
84-
89+
8590
return {mz(logical.ancz[0]), mz(logical.ancz[1])};
8691
}
8792

93+
// [Begin QEC Circuit]
8894
// QEC circuit with real-time decoding
8995
__qpu__ int64_t qec_circuit() {
9096
cudaq::qec::decoding::reset_decoder(0);
91-
97+
9298
cudaq::qvector data(3);
9399
cudaq::qvector ancz(2);
94-
cudaq::qvector ancx; // Empty for repetition code
100+
cudaq::qvector ancx; // Empty for repetition code
95101
cudaq::qec::patch logical(data, ancx, ancz);
96-
102+
97103
prep0(logical);
98-
104+
99105
// 3 rounds of syndrome measurement
100106
for (int round = 0; round < 3; ++round) {
101107
auto syndromes = measure_stabilizers(logical);
102108
cudaq::qec::decoding::enqueue_syndromes(0, syndromes);
103109
}
104-
110+
105111
// Get corrections and apply them
106112
auto corrections = cudaq::qec::decoding::get_corrections(0, 3);
107113
for (std::size_t i = 0; i < 3; ++i) {
108114
if (corrections[i])
109115
cudaq::x(data[i]);
110116
}
111-
117+
112118
return cudaq::to_integer(mz(data));
113119
}
120+
// [End QEC Circuit]
114121

122+
// [Begin Main]
115123
int main() {
116-
auto code = cudaq::qec::get_code("repetition",
124+
// [Begin Get Code]
125+
auto code = cudaq::qec::get_code("repetition",
117126
cudaqx::heterogeneous_map{{"distance", 3}});
118-
127+
// [End Get Code]
128+
129+
// [Begin DEM Generation]
119130
// Step 1: Generate detector error model
120131
printf("Step 1: Generating DEM...\n");
121132
cudaq::noise_model noise;
122133
noise.add_all_qubit_channel("x", cudaq::depolarization2(0.01), 1);
123-
134+
124135
auto dem = cudaq::qec::z_dem_from_memory_circuit(
125136
*code, cudaq::qec::operation::prep0, 3, noise);
126-
137+
// [End DEM Generation]
138+
139+
// [Begin Save DEM]
127140
save_dem(dem, "config.yaml");
128-
141+
// [End Save DEM]
142+
143+
// [Begin Load and Run]
129144
// Step 2: Load config and run circuit
130145
printf("\nStep 2: Running circuit with decoding...\n");
131146
load_dem("config.yaml");
132-
147+
133148
cudaq::run(10, qec_circuit);
134149
printf("Ran 10 shots\n");
135-
150+
136151
cudaq::qec::decoding::config::finalize_decoders();
152+
// [End Load and Run]
153+
137154
printf("\nDone!\n");
138155
return 0;
139156
}
157+
// [End Main]
158+
// [End Documentation]

docs/sphinx/examples/qec/python/real_time_complete.py

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,72 +15,86 @@
1515
"""
1616

1717
import os
18+
1819
os.environ["CUDAQ_DEFAULT_SIMULATOR"] = "stim"
1920

2021
import cudaq
2122
import cudaq_qec as qec
2223

24+
2325
# Prepare logical |0⟩
2426
@cudaq.kernel
2527
def prep0(logical: qec.patch):
2628
for i in range(logical.data.size()):
2729
cudaq.reset(logical.data[i])
2830

31+
2932
# Measure ZZ stabilizers for 3-qubit repetition code
3033
@cudaq.kernel
3134
def measure_stabilizers(logical: qec.patch):
3235
for i in range(logical.ancz.size()):
3336
cudaq.reset(logical.ancz[i])
34-
37+
3538
# Z0Z1 stabilizer
3639
cudaq.cx(logical.data[0], logical.ancz[0])
3740
cudaq.cx(logical.data[1], logical.ancz[0])
38-
41+
3942
# Z1Z2 stabilizer
4043
cudaq.cx(logical.data[1], logical.ancz[1])
4144
cudaq.cx(logical.data[2], logical.ancz[1])
42-
45+
4346
return [cudaq.mz(logical.ancz[0]), cudaq.mz(logical.ancz[1])]
4447

48+
49+
# [Begin QEC Circuit]
4550
# QEC circuit with real-time decoding
4651
@cudaq.kernel
4752
def qec_circuit():
4853
qec.reset_decoder(0)
49-
54+
5055
data = cudaq.qvector(3)
5156
ancz = cudaq.qvector(2)
5257
ancx = cudaq.qvector(0)
5358
logical = qec.patch(data, ancx, ancz)
54-
59+
5560
prep0(logical)
56-
61+
5762
# 3 rounds of syndrome measurement
5863
for _ in range(3):
5964
syndromes = measure_stabilizers(logical)
6065
qec.enqueue_syndromes(0, syndromes)
61-
66+
6267
# Get corrections and apply them
6368
corrections = qec.get_corrections(0, 3, False)
6469
for i in range(3):
6570
if corrections[i]:
6671
cudaq.x(data[i])
67-
72+
6873
cudaq.mz(data)
6974

75+
76+
# [End QEC Circuit]
77+
78+
79+
# [Begin Main]
7080
def main():
81+
# [Begin Get Code]
7182
# Get 3-qubit repetition code
7283
code = qec.get_code("repetition", distance=3)
73-
84+
# [End Get Code]
85+
86+
# [Begin DEM Generation]
7487
# Step 1: Generate detector error model
7588
print("Step 1: Generating DEM...")
7689
cudaq.set_target("stim")
77-
90+
7891
noise = cudaq.NoiseModel()
7992
noise.add_all_qubit_channel("x", cudaq.Depolarization2(0.01), 1)
80-
81-
dem = qec.z_dem_from_memory_circuit(
82-
code, qec.operation.prep0, 3, noise)
83-
93+
94+
dem = qec.z_dem_from_memory_circuit(code, qec.operation.prep0, 3, noise)
95+
# [End DEM Generation]
96+
97+
# [Begin Save DEM]
8498
# Save decoder config
8599
config = qec.DecoderConfig()
86100
config.id = 0
@@ -89,30 +103,41 @@ def main():
89103
config.syndrome_size = dem.detector_error_matrix.shape[0]
90104
config.H_sparse = qec.pcm_to_sparse_vec(dem.detector_error_matrix)
91105
config.O_sparse = qec.pcm_to_sparse_vec(dem.observables_flips_matrix)
92-
106+
93107
# Calculate numRounds from DEM (we send 1 additional round, so add 1)
94108
num_syndromes_per_round = 2 # Z0Z1 and Z1Z2
95-
num_rounds = dem.detector_error_matrix.shape[0] // num_syndromes_per_round + 1
109+
num_rounds = dem.detector_error_matrix.shape[
110+
0] // num_syndromes_per_round + 1
96111
config.D_sparse = qec.generate_timelike_sparse_detector_matrix(
97112
num_syndromes_per_round, num_rounds, False)
98113
config.decoder_custom_args = {"lut_error_depth": 2}
99-
114+
100115
multi_config = qec.MultiDecoderConfig()
101116
multi_config.decoders = [config]
102-
117+
103118
with open("config.yaml", 'w') as f:
104119
f.write(multi_config.to_yaml_str(200))
105120
print("Saved config to config.yaml")
106-
121+
# [End Save DEM]
122+
123+
# [Begin Load and Run]
107124
# Step 2: Load config and run circuit
108125
print("\nStep 2: Running circuit with decoding...")
126+
# [Begin Load DEM]
109127
qec.configure_decoders_from_file("config.yaml")
110-
128+
# [End Load DEM]
129+
111130
cudaq.sample(qec_circuit, shots_count=10)
112131
print("Ran 10 shots")
113-
132+
114133
qec.finalize_decoders()
134+
# [End Load and Run]
135+
115136
print("\nDone!")
116137

138+
139+
# [End Main]
140+
117141
if __name__ == "__main__":
118142
main()
143+
# [End Documentation]

0 commit comments

Comments
 (0)