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

Pushing Q# qft example



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent c9ea638b
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -156,6 +156,10 @@
      }                                                                        \
    }                                                                          \
  };                                                                           \
  void OPERATION_NAME(std::shared_ptr<qcor::CompositeInstruction> parent,      \
                      qreg q) {                                                \
    class OPERATION_NAME kernel(parent, q);                                    \
  }                                                                            \
  void OPERATION_NAME(qreg q) { class OPERATION_NAME kernel(q); }              

// Usage:
+9 −5
Original line number Diff line number Diff line

namespace QCOR {
    open QCOR.Intrinsic;
    operation SWAP(q1 : Qubit, q2: Qubit) : Unit {
    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 {
    operation OneQubitQFT (q : Qubit) : Unit is Adj {
        H(q);
    }
    // Rotation gate
@@ -19,14 +19,14 @@ namespace QCOR {
        Rz(angle, q);
    }
    // Prepare binary fraction exponent in place (quantum input)
    operation BinaryFractionQuantumInPlace (register : Qubit[]) : Unit {
    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 {
    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]);
@@ -35,12 +35,16 @@ namespace QCOR {
    // 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 {
    operation QuantumFourierTransform (register : Qubit[]) : Unit is Adj {
        let n = Length(register);
        for i in 0 .. n - 1 {
            BinaryFractionQuantumInPlace(register[i ...]);
        }
        ReverseRegister(register);
    }
    
    operation InverseQFT (register : Qubit[]) : Unit {
        Adjoint QuantumFourierTransform(register);
    }
}
+39 −0
Original line number Diff line number Diff line
#include <iostream> 
#include <vector>
#include "import_kernel_utils.hpp"

using QPEOracleSignature = KernelSignature<qubit>;
qcor_import_qsharp_kernel(QCOR__InverseQFT);

__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)
  QCOR__InverseQFT(parent_kernel, counting_qubits);

  // 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(std::cout, q, oracle);
}