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

Merge branch 'master' into tnguyen/qcor-modifier-regions

parents 76692d56 23581f9a
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -39,18 +39,18 @@ docker run_macosx_catalina_bottles:
  - $HOME/catalina/run_build.sh $AIDEQC_ACCESS_TOKEN
  allow_failure: true
  
docker run_macosx_mojave_bottles:
  stage: deploy
  only:
    - schedules
  tags: 
    - mojave
  script:
  - id=$(docker run -d -it --device /dev/kvm -p 50922:10022 -v "${HOME}/mojave/mac_hdd_ng.img:/image" sickcodes/docker-osx:naked)
  - sleep 240
  - ssh mojave-ci "PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin bash run_bottle_build.sh $AIDEQC_ACCESS_TOKEN"
  - docker stop $id && docker rm -v $id
  allow_failure: true
# docker run_macosx_mojave_bottles:
#   stage: deploy
#   only:
#     - schedules
#   tags: 
#     - mojave
#   script:
#   - id=$(docker run -d -it --device /dev/kvm -p 50922:10022 -v "${HOME}/mojave/mac_hdd_ng.img:/image" sickcodes/docker-osx:naked)
#   - sleep 240
#   - ssh mojave-ci "PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin bash run_bottle_build.sh $AIDEQC_ACCESS_TOKEN"
#   - docker stop $id && docker rm -v $id
#   allow_failure: true

docker run_docker_deploy:
  stage: deploy
+72 −0
Original line number Diff line number Diff line
# MLIR+QIR as an IR for Quantum-Classical Computing
Here we demonstrate the utility of the QIR and MLIR for enabling the development of compilers for available quantum languages. 

Our motivation with this demonstration is to show how MLIR+QIR enable the main feature of a robust IR: mapping multiple languages or programming approaches to multiple backends.

Our examples will be simple GHZ and Bell circuits for NISQ and FTQC execution, respectively. 

## Goals

- Demonstrate the utility of the MLIR and QIR for creating compilers and executable code for available quantum languages.

- Demonstrate MLIR as language-level IR for quantum-classical computing (control flow from Standard/Affine, etc.).

- Demonstrate write-once, run-on-any available quantum backend and multiple languages to multiple backends.

- Demonstrate accessibility of MLIR and QIR for available Pythonic circuit construction frameworks. 

## NOTES
Poor man's way to count instructions in the LLVM output
```bash
qcor --emit-llvm bell.qasm -O3 &> bell_tmp.ll && cat bell_tmp.ll | grep '%* = \|call' | wc -l && rm bell_tmp.ll
```

## Outline

### Demo 1, Simple Language Lowering, Helpful Classical Passes

- Show off the code in `ghz.qasm`. Note the gate function. 
- Goal is to highlight the unique benefits of mutliple levels of IR abstraction
- Compile and run, note we want to run this in NISQ mode
```bash
qcor -qrt nisq -shots 1000 ghz.qasm -o ghz.x
./ghz.x
```
- Run the compile command with `-v` to show the steps in the workflow
```bash
qcor -v ghz.qasm 
```
- Show the MLIR and QIR Output, noting the Affine Loop (and that we benefit from leveraging classical IR Dialects)
```bash
qcor --emit-mlir ghz.qasm
qcor --emit-llvm ghz.qasm
```
- Show simple classical optimizations, here inlining and loop unrolling
```bash
qcor --emit-milr -O3 ghz.qasm
qcor --emit-llvm -O3 ghz.qasm
```

- Show off the FTQC mode code, noting that the for loop has a conditional statement
- Compile and run with -v 
```bash 
qcor -qrt ftqc -v bell.qasm -o bell.x
./bell.x
```
- Show the MLIR and QIR
```bash
qcor --emit-mlir bell.qasm
qcor --emit-llvm bell.qasm
```
- Note the need for multiple layers of IR, can't get opts from MLIR, but can from LLVM
```bash
qcor --emit-mlir -O3 bell.qasm
qcor --emit-llvm -O3 llvm.qasm
qcor --emit-llvm bell.qasm -O0 &> bell_tmp.ll && cat bell_tmp.ll | grep '%* = \|call' | wc -l && rm bell_tmp.ll
qcor --emit-llvm bell.qasm -O3 &> bell_tmp.ll && cat bell_tmp.ll | grep '%* = \|call' | wc -l && rm bell_tmp.ll
```

- Switch to the Python script to show the audience how all the MLIR/QIR infrastructure just shown can also be generated from Python. Moreover, that Qiskit and Pyquil can also generate MLIR/QIR. 
- Note how `qjit` is the QCOR quantum just-in-time compiler, produces executable functions that enable `mlir()` and `llvm()` methods. 

+33 −0
Original line number Diff line number Diff line
// qcor bell.qasm -o bell.x
// ./bell.x 
//
// qcor -v bell.qasm -o bell.x
// qcor --emit-mlir bell.qasm
// qcor --emit-llvm bell.qasm

OPENQASM 3;

qubit q[2];

const shots = 15;
int count = 0;

for i in [0:15] {
    
    // Create Bell state
    h q[0];
    cnot q[0], q[1];
    
    // Measure and assert both are equal
    bit c[2];
    c = measure q;
    if (c[0] == c[1]) {
        print("iter", i, ": measured =", c[0], c[1]);
        count += 1;
    }

    reset q;
}

print("count is", count);
+34 −0
Original line number Diff line number Diff line
// NISQ Mode Execution
//
// Compile and run on qpp 
// qcor ghz.qasm -o ghz.x -qrt nisq -shots 1000
// ./ghz.x 
//
// Show on local aer with noisy backend
// qcor ghz.qasm -o ghz.x -qrt nisq -shots 100 -qpu aer:ibmq_sydney
// ./ghz.x 
//
// (Now Show off how this works, MLIR + QIR)
//
// qcor -v ghz.qasm -o ghz.x
// qcor --emit-mlir ghz.qasm
// qcor --emit-llvm ghz.qasm


OPENQASM 3;

const n_qubits = 3;

qubit q[n_qubits];

gate ctrl_x a, b {
    ctrl @ x a, b;
}

h q[0];
for i in [0:n_qubits-1] {
    ctrl_x q[i], q[i+1];
}

bit c[n_qubits];
c = measure q;
 No newline at end of file
+45 −0
Original line number Diff line number Diff line
from qcor import qjit, qalloc
import qiskit

# Generate 3-qubit GHZ state with Qiskit
circ = qiskit.QuantumCircuit(3)
circ.h(0)
circ.cx(0, 1)
circ.cx(1, 2)
circ.measure_all()

# Creates a kernel parameterized on a qreg
qcor_kernel = qjit(circ)

# Allocate the qreg
q = qalloc(3)

# Convert to MLIR and print
mlir = qcor_kernel.mlir(q)
print(mlir)

# Convert to QIR and print
qir = qcor_kernel.qir(q, opt=3)
print(qir)

from pyquil import Program
from pyquil.gates import CNOT, H, MEASURE
  
p = Program()
p += H(0)
p += CNOT(0, 1)
ro = p.declare('ro', 'BIT', 2)
p += MEASURE(0, ro[0])
p += MEASURE(1, ro[1])

# This requires rigetti/quilc docker image
qcor_kernel_pyquil = qjit(p, opt=3)
r = qalloc(2)

# Convert to MLIR and print
mlir = qcor_kernel_pyquil.mlir(r)
print(mlir)

# Convert to QIR and print
qir = qcor_kernel_pyquil.qir(r)
print(qir)
 No newline at end of file
Loading