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

Merge branch 'master' into tnguyen/qsharp-demo



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parents 68fbcaf0 6562b688
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
# Grover Demonstration
![circuit](grover_circuit.png)
Code up a grover example live, search for marked states |101> and |011>. We want a general library function that is parameterized on the 
oracle kernel and number of iterations

## Goals
* Show off kernel composition
* Show off compute-action-uncompute pattern
* Show off functional programming

## Steps
* Start off by hard-coding the oracle. And define run_grover to only take qreg and iterations
* Implement run_grover, using hard-coded oracle
* Implement amplification, showing circuit, showing pattern
* Implement main. 
* Compile and run. Show it works.

* Update run_grover to use KernelSignature, move oracle below run_grover.
* compile and run

* Update oracle to be a lambda

* Show off python version
 No newline at end of file
+55 −0
Original line number Diff line number Diff line
// Create a general grover search algorithm.
// Let's create that marks 2 states
// Show figures Init - [Oracle - Amplification for i in iters] - Measure
// https://www.nature.com/articles/s41467-017-01904-7

// Show off kernel composition, common patterns, 
// functional programming (kernels taking other kernels)

using GroverPhaseOracle = KernelSignature<qreg>;

__qpu__ void amplification(qreg q) {
  // H q X q ctrl-ctrl-...-ctrl-Z H q Xq
  // compute - action - uncompute

  compute {
    H(q);
    X(q);
  }
  action {
    auto ctrl_bits = q.head(q.size() - 1);
    auto last_qubit = q.tail();
    Z::ctrl(ctrl_bits, last_qubit);
  }
}

__qpu__ void run_grover(qreg q, GroverPhaseOracle oracle,
                        const int iterations) {
  H(q);

  for (int i = 0; i < iterations; i++) {
    oracle(q);
    amplification(q);
  }

  Measure(q);
}

__qpu__ void oracle(qreg q) {
  // Mark 101 and 011
  CZ(q[0], q[2]);
  CZ(q[1], q[2]);
}

int main() {
  const int N = 3;

  // Allocate some qubits
  auto q = qalloc(N);

  // Call grover given the oracle and n iterations
  run_grover(q, oracle, 1);

  // print the histogram
  q.print();
}
 No newline at end of file
+30 −0
Original line number Diff line number Diff line
from qcor import *

@qjit
def oracle_fn(q: qreg):
    CZ(q[0], q[2])
    CZ(q[1], q[2])
        
@qjit
def amplification(q: qreg):
    with compute:
        H(q)
        X(q)
    with action:
        Z.ctrl(q[0: q.size() - 1], q[q.size() - 1])
            
@qjit
def run_grover(q: qreg, oracle_var: KernelSignature(qreg), iterations: int):
    H(q)
    #Iteratively apply the oracle then reflect
    for i in range(iterations):
        oracle_var(q)
        amplification(q)
    # Measure all qubits
    Measure(q)

set_shots(1000)
q = qalloc(3)
run_grover(q, oracle_fn, 1)
counts = q.counts()
print(counts)
 No newline at end of file
+63.3 KiB
Loading image diff...
+23 −0
Original line number Diff line number Diff line
# Hello World Demonstration

## GHZ Goals
Write a C++ code that prepares a GHZ state on N qubits. 
* How does one write a quantum kernel? 
* What is a qreg? 
* What operations are exposed on qreg? 
* How to reference qubits from a qreg? 
* Quantum Instruction Broadcasting
* Logical-to-physical connectivity mapping - placement
* Print the kernel qasm
* Run on Qpp, Noisy Aer, and IBM
* Demonstrate functional programming with lambdas
* Show equivalent in Python. First run is slow for JIT, but subsequently fast

## Circuit Optimization Goals
Write a C++ code that shows off a kernel that can be reduced to nothing by the Pass Manager.
* Loop over N Hadamards on a qubit
* Z H X H 
* Zero rotations
* Show off CX and X::ctrl 
* Show as_unitary_matrix
* Run with opt-level 1, then opt-level 2, -print-opt-stats
 No newline at end of file
Loading