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

Merge branch 'master' into tnguyen/update-qasm3

parents 042e4752 f736ea3b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -60,10 +60,12 @@ docker run_docker_deploy:
  - cd docker/ci/alpine/qcor && docker build -t qcor/cli . --no-cache
  - cd ../code-server && docker build -t qcor/qcor . --no-cache
  - cd ../qsharp-code-server && docker build -t qcor/qsharp-qcor . --no-cache
  - cd ../code-server-dev && docker build -t qcor/qcor-dev . --no-cache
  - echo "$REGISTRY_PASSWORD" | docker login -u qcor --password-stdin
  - docker push qcor/cli
  - docker push qcor/qcor
  - docker push qcor/qsharp-qcor
  - docker push qcor/qcor-dev
  - docker system prune -f
  - docker rmi -f qcor/qcor qcor/cli
  - docker rmi -f qcor/qcor qcor/cli qcor/qsharp-qcor qcor/qcor-dev xacc/alpine
  allow_failure: true
+80 −0
Original line number Diff line number Diff line
OPENQASM 3;
include "qelib1.inc";

// NISQ-mode lowering to conditional (If) statements
// Compile targeting nisq runtime and a capable QPU:
// (1) Qpp simulator (default):
// qcor -qrt nisq -shots 1024 measure_conditional.qasm -print-final-submission 
// (2) Aer simulator (inspect the QObj to see the use of "conditional" to control quantum instructions)
// qcor -qrt nisq -qpu aer -shots 1024 measure_conditional.qasm -print-final-submission 
// (3) Honeywell: see the OpenQASM2 with if statements.
// qcor -qrt nisq -qpu honeywell:HQS-LT-S1-APIVAL -shots 1024 measure_conditional.qasm -print-final-submission 

// Expected to get 4 bits (iteratively) of 1011 (or 1101 LSB) = 11(decimal):
// phi_est = 11/16 (denom = 16 since we have 4 bits)
// => phi = 2pi * 11/16 = 11pi/8 = 2pi - 5pi/8
// i.e. we estimate the -5*pi/8 angle...
qubit q[2];
const bits_precision = 4;
bit c[bits_precision];

// Prepare the eigen-state: |1>
x q[1];

// First bit
h q[0];
// Controlled rotation: CU^k
for i in [0:8] {
  cphase(-5*pi/8) q[0], q[1];
}
h q[0];
// Measure and reset
measure q[0] -> c[0];
reset q[0];

// Second bit
h q[0];
for i in [0:4] {
  cphase(-5*pi/8) q[0], q[1];
}
// Conditional rotation
if (c[0] == 1) {
  rz(-pi/2) q[0];
}
h q[0];
// Measure and reset
measure q[0] -> c[1];
reset q[0];

// Third bit
h q[0];
for i in [0:2] {
  cphase(-5*pi/8) q[0], q[1];
}
// Conditional rotation
if (c[0] == 1) {
  rz(-pi/4) q[0];
}
if (c[1] == 1) {
  rz(-pi/2) q[0];
}
h q[0];
// Measure and reset
measure q[0] -> c[2];
reset q[0];

// Fourth bit
h q[0];
cphase(-5*pi/8) q[0], q[1];
// Conditional rotation
if (c[0] == 1) {
  rz(-pi/8) q[0];
}
if (c[1] == 1) {
  rz(-pi/4) q[0];
}
if (c[2] == 1) {
  rz(-pi/2) q[0];
}
h q[0];
measure q[0] -> c[3];
 No newline at end of file
+25 −0
Original line number Diff line number Diff line
OPENQASM 3;

// QCOR can scan for this and make 
// sure MLIRGen does not add main()
// This is useful for QASM3 files that are 
// purely library functions
#pragma no_entrypoint;

// Inverse QFT subroutine on n_counting qubits
def inverse_qft(int[64]:nc) qubit[nc]:qq {
    for i in [0:nc/2] {
        swap qq[i], qq[nc-i-1];
    }
    for i in [0:nc-1] {
        h qq[i];
        int j = i + 1;
        int y = i;
        while (y >= 0) {
            double theta = -pi / (2^(j-y));
            cphase(theta) qq[j], qq[y];
            y -= 1;
        }
    }
    h qq[nc-1];
}
 No newline at end of file
+46 −0
Original line number Diff line number Diff line
#include "qir_nisq_kernel_utils.hpp"

// Compile:
// qcor qft.qasm qpe.cpp -shots 1024 
using QPEOracleSignature = KernelSignature<qubit>;

// External QASM3 function with signature void(qreg, int)
// All imported kernels assumed to take qreg as first arg
qcor_import_qasm3_kernel(inverse_qft, int);

__qpu__ void qpe(qreg q, QPEOracleSignature oracle) {
  // Extract the counting qubits and the state qubit
  auto counting_qubits = q.extract_range({0,3});
  auto state_qubit = q[3];
  // Put it in |1> eigenstate
  X(state_qubit);
  // Create uniform superposition on all 3 qubits
  H(counting_qubits);

  // run ctr-oracle operations
  for (auto i : range(counting_qubits.size())) {
    const int nbCalls = 1 << i;
    for (auto j : range(nbCalls)) {
      oracle.ctrl(counting_qubits[i], state_qubit);
    }
  }

  // Run Inverse QFT on counting qubits
  // Using the Q# Kernel (wrapped as a QCOR kernel)
  // Signature is void(qreg, int) as per above import stmt
  inverse_qft(counting_qubits, counting_qubits.size());

  // Measure the counting qubits
  Measure(counting_qubits);
}

// Oracle to consider
__qpu__ void oracle(qubit q) { T(q); }

int main(int argc, char **argv) {
  auto q = qalloc(4);
  qpe::print_kernel(q, oracle);
  // Run
  qpe(q, oracle);
  q.print();
}
+15 −0
Original line number Diff line number Diff line
// qcor -qdk-version 0.17.2106148041-alpha qrng.qs driver.qasm
// for i in {1..10} ; do ./a.out ; done 
OPENQASM 3;

// Declare kernel:
// This one is from Q#...
kernel QCOR__GenerateRandomInt__body(int[64]) -> int64_t;


// Generate the random number (4 bits)
int64_t max_bits = 4;
int64_t n = QCOR__GenerateRandomInt__body(max_bits);

// Print the random number
print("[ OpenQASM3 ] Random", max_bits, "bit int =     ", n);
 No newline at end of file
Loading