1919#include < common/NoiseModel.h>
2020#include < fstream>
2121
22+ // [Begin Save DEM]
2223// Save decoder configuration to YAML file
2324void 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
5457void 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]
115123int 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 (" \n Step 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 (" \n Done!\n " );
138155 return 0 ;
139156}
157+ // [End Main]
158+ // [End Documentation]
0 commit comments