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

Update Q# NISQ examples



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 63d179e1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
namespace QCOR 
{
open QCOR.Intrinsic;
open Microsoft.Quantum.Intrinsic;

operation Bell(qubits : Qubit[]) : Unit {
    H(qubits[0]);
    for index in 0 .. Length(qubits) - 2 {
+3 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@

// Util pre-processor to wrap Q# operation 
// in a QCOR QuantumKernel.
// Compile:
// Note: need to use alpha package since this kernel will take a qubit array.
// qcor -qdk-version 0.17.2106148041-alpha bell.qs bell_driver.cpp -shots 1024
qcor_import_qsharp_kernel(QCOR__Bell);

int main() {
+30 −47
Original line number Diff line number Diff line
namespace QCOR 
{
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Canon;

namespace QCOR {
    open QCOR.Intrinsic;
operation SWAP(q1 : Qubit, q2: Qubit) : Unit is Adj {
  CNOT(q1, q2);
  CNOT(q2, q1);
  CNOT(q1, q2);
}

    // 1-qubit QFT
    operation OneQubitQFT (q : Qubit) : Unit is Adj {
        H(q);
operation IQFT(qq: Qubit[]): Unit {
  Message("Hello from Q# IQFT");
  for i in 0 .. Length(qq)/2 - 1 {
    SWAP(qq[i], qq[Length(qq)-i-1]);
  }
    // Rotation gate
    // Applies a rotation about the |1⟩ state by an angle 
    // specified as a dyadic fraction.
    operation Rotation (q : Qubit, k : Int) : Unit is Adj+Ctl {
        let angle = 2.0 * PI() / IntAsDouble(1 <<< k);
        Rz(angle, q);
    }
    // Prepare binary fraction exponent in place (quantum input)
    operation BinaryFractionQuantumInPlace (register : Qubit[]) : Unit is Adj {
        OneQubitQFT(register[0]);
        for ind in 1 .. Length(register) - 1 {
            Controlled Rotation([register[ind]], (register[0], ind + 1));
        }
    }
    // Reverse the order of qubits
    operation ReverseRegister (register : Qubit[]) : Unit is Adj {
        let N = Length(register);
        for ind in 0 .. N / 2 - 1 {
            SWAP(register[ind], register[N - 1 - ind]);
        }
    }
    // Quantum Fourier transform
    // Input: A register of qubits in state |j₁j₂...⟩
    // Goal: Apply quantum Fourier transform to the input register
    operation QuantumFourierTransform (register : Qubit[]) : Unit is Adj {
        let n = Length(register);
        for i in 0 .. n - 1 {
            BinaryFractionQuantumInPlace(register[i ...]);
        }
        ReverseRegister(register);
    
  for i in 0 .. Length(qq) - 2 {
    H(qq[i]);
    let j = i + 1;
    mutable y = i;
    repeat {
      let theta = -3.14159 / IntAsDouble(1 <<< (j-y));
      // Controlled R1 == CPhase
      Controlled R1([qq[j]], (theta, qq[y]));
      set y = y - 1;
    } until (y < 0);
  }

    operation InverseQFT (register : Qubit[]) : Unit {
        Adjoint QuantumFourierTransform(register);
  H(qq[Length(qq) -1]);
}
}
 No newline at end of file
+8 −3
Original line number Diff line number Diff line
@@ -2,8 +2,10 @@
#include <vector>
#include "import_kernel_utils.hpp"

// Compile:
// qcor -qdk-version 0.17.2106148041-alpha qft.qs qft_driver.cpp -shots 1024 -print-final-submission
using QPEOracleSignature = KernelSignature<qubit>;
qcor_import_qsharp_kernel(QCOR__InverseQFT);
qcor_import_qsharp_kernel(QCOR__IQFT);

__qpu__ void qpe(qreg q, QPEOracleSignature oracle) {
  // Extract the counting qubits and the state qubit
@@ -24,7 +26,7 @@ __qpu__ void qpe(qreg q, QPEOracleSignature oracle) {

  // Run Inverse QFT on counting qubits
  // Using the Q# Kernel (wrapped as a QCOR kernel)
  QCOR__InverseQFT(parent_kernel, counting_qubits);
  QCOR__IQFT(parent_kernel, counting_qubits);

  // Measure the counting qubits
  Measure(counting_qubits);
@@ -35,5 +37,8 @@ __qpu__ void oracle(qubit q) { T(q); }

int main(int argc, char **argv) {
  auto q = qalloc(4);
  qpe::print_kernel(std::cout, q, oracle);
  // qpe::print_kernel(std::cout, q, oracle);
  // Run
  qpe(q, oracle);
  q.print();
}