Running test circuits

Using mqss-opt

The binary mqss-opt is used to invoke passes on input MLIR dialects. To check the list of available passes Run:

mqss-opt -h

Make sure mqss-opt is on the$PATH environment variable of your shell. If it isn’t Run: eval "$(make set-target-paths)".

MLIR dialect input (quake or catalyst-quantum)

Here is the Bell-State circuit in the Quake MLIR dialect:

module attributes {cc.sizeof_string = 24 : i64, llvm.data_layout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", llvm.triple = "aarch64-unknown-linux-gnu", quake.mangled_name_map = {__nvqpp__mlirgen__bellILm2EE = "_ZN4bellILm2EEclEv"}} {
  func.func @__nvqpp__mlirgen__bellILm2EE() attributes {"cudaq-entrypoint", "cudaq-kernel"} {
    %0 = quake.alloca !quake.veq<2>
    %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref
    quake.h %1 : (!quake.ref) -> ()
    %2 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref
    %3 = quake.extract_ref %0[1] : (!quake.veq<2>) -> !quake.ref
    quake.x [%2] %3 : (!quake.ref, !quake.ref) -> ()
    %q0 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref
    %q1 = quake.extract_ref %0[1] : (!quake.veq<2>) -> !quake.ref
    %m0 = quake.mz %q0 : (!quake.ref) -> !quake.measure
    %m1 = quake.mz %q1 : (!quake.ref) -> !quake.measure
    return
  }
}

Following command shows an example of how passes can be invoked on this circuit (assuming the dialect is saved as bell_state.qke):

mqss-opt bell-state.qke --cse --canonicalize --BasisConversionPass=gates=phased_rx,cz

The output is the same input bell-state.qke dialect but with transformations. In this case, the hadamard and CNOT gates in the input dialect quake.h and quake.x will be decomposed to the phased_rx and cz gates. Similarly, one can invoke passes on the catalyst-quantum mlir dialect by just replacing the quake dialect input with the catalyst-quantum input.

Using mqss-cc script (Frontend test)

Note: Before running a Frontend test, make sure you follow the installation instructions within build.
The driver script for running example circuits (in c++/python) is mqss-cc. After the targets are generated this script is installed within the INSTALL_DIR and should be on the $PATH environment variable for your bash shell. Check by running the command:

$mqss-cc -h

If nothing prints, run the command eval "$(make set-target-paths)" from the root directory once again.

C++ test circuits

The compilation suite accepts c++ circuits written using cudaq. Following is an example:

#include <cudaq.h>
#include <fstream>
#include <iostream>

template <std::size_t N> struct test {
  auto operator()() __qpu__ {

    // Compile-time sized array like std::array
    cudaq::qarray<N> q;
    x<cudaq::ctrl>(q[0], q[1]);
    x(q[2]);
    rx(2.4, q[1]);

    x<cudaq::ctrl>(q[1], q[0]);
    rx(3.1416, q[1]);

    x<cudaq::ctrl>(q[0], q[1]);
    x(q[1]);
    rx(5.1416, q[1]);

    mz(q[0]);
    mz(q[1]);
  }
};

int main() {
  auto kernel = test<3>{};
  auto counts = cudaq::sample(kernel);
  counts.dump();
  return 0;
}

To run the above test circuit using mqss-cc use the following command:

mqss-cc test.cpp --out-dir output/ --passes=CommonGateCancellationPass=mode=CancelGate

The Commutation Optimization pass is applied to commute CNOT and RX gates. The output in this case will be QIR since the emit-qir flag is enabled.

Note: One can use cudaq to write quantum circuits in python. But this is not supported yet within mqss-cc.

Python test circuits

The compilation suite accepts python circuits written using catalyst. Following is an example:


from catalyst import qjit
import pennylane as qml

dev = qml.device("lightning.qubit", wires=3)

@qjit(keep_intermediate=True)
@qml.set_shots(1000)
@qml.qnode(dev)
def circuit_CommuteCNOTRx():
    qml.CNOT(wires=[0, 1])
    qml.PauliX(wires=2)
    qml.RX(2.4, wires=1)

    qml.CNOT(wires=[1, 0])
    qml.RX(3.1416, wires=1)

    qml.CNOT(wires=[0, 1])
    qml.PauliX(wires=1)
    qml.RX(5.1416, wires=1)

    return qml.counts()

mqss-cc test.py --function circuit \
           --out-dir output/ --passes=CommonGateCancellationPass=mode=CancelGate

Do Not forget to mention the function to compile after the --function flag. Refer to Passes for a list of all available MLIR passes.