Commit c6997a17 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Added an example using bit-flip QEC from std lib



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent ddf7d0d9
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
#include <qalloc>

// Example demonstrates a simple 3-qubit bit-flip code.
// Compile:
// qcor -qpu aer[noise-model:<noise.json>] -qrt ftqc bit-flip-code.cpp 
@@ -93,7 +91,6 @@ __qpu__ void resetAll(qreg q) {
// Error corrected Bell example:
// Note: the 3-q bit-flip code can only protect against X errors.
__qpu__ void bellQEC(qreg q, int nbRuns) {
  using qcor::xasm;
  int ancQbId = 6;
  for (int i = 0; i < nbRuns; ++i) {
    // Apply H before encoding.
+22 −0
Original line number Diff line number Diff line
#include <qcor_qec>

__qpu__ void applyError(qreg q, int qIdx) {
  std::cout << "Apply X error @ q[" << qIdx << "].\n";
  X(q[qIdx]);
}

using namespace ftqc;

int main() {
  auto q = qalloc(4);
  bit_flip_encoder(q, 0, {1, 2});
  std::vector<int> syndromes;
  // If using a perfec simulator, apply a random X error to observe syndrome changes.
  applyError(q, 2);

  // Measure the stabilizer syndromes:
  measure_stabilizer_generators(q, bit_flip_code_stabilizers(), {0, 1, 2}, 3, syndromes);
  assert(syndromes.size() == 2);
  std::cout << "Syndrome: <Z0Z1> = " << syndromes[0] << "; <Z1Z2> = " << syndromes[1] << "\n";
  
  // Recover:
  bit_flip_recover(q, {0, 1, 2}, syndromes);
  // Measure again to check:
  syndromes.clear();
  measure_stabilizer_generators(q, bit_flip_code_stabilizers(), {0, 1, 2}, 3, syndromes);
  std::cout << "AFTER CORRECTION: \nSyndrome: <Z0Z1> = " << syndromes[0] << "; <Z1Z2> = " << syndromes[1] << "\n";
}
 No newline at end of file
+24 −0
Original line number Diff line number Diff line
#pragma once
#include <qcor_common>

std::vector<std::vector<qcor::PauliOperator>> bit_flip_code_stabilizers() {
  static const std::vector<std::vector<qcor::PauliOperator>> STABILIZERS{
      {qcor::Z(0), qcor::Z(1)}, {qcor::Z(1), qcor::Z(2)}};
  return STABILIZERS;
}

__qpu__ void bit_flip_encoder(qreg q, int dataQubitIdx,
                              std::vector<int> scratchQubitIdx) {
  CX(q[dataQubitIdx], q[scratchQubitIdx[0]]);
  CX(q[dataQubitIdx], q[scratchQubitIdx[1]]);
}

__qpu__ void bit_flip_recover(qreg q, std::vector<int> logicalReg,
                              std::vector<int> syndromes) {
  const bool parity01 = (syndromes[0] == 1);
  const bool parity12 = (syndromes[1] == 1);
  // Correct error based on parity results
  if (parity01 && !parity12) {
    X(q[logicalReg[0]]);
  }

  if (parity01 && parity12) {
    X(q[logicalReg[1]]);
  }

  if (!parity01 && parity12) {
    X(q[logicalReg[2]]);
  }
}

#ifdef _QCOR_FTQC_RUNTIME
namespace ftqc {
__qpu__ void measure_stabilizer_generators(