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=prx,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 prx 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.

Add --mqssci-verify to the command above to automatically check that the decomposition preserved the circuit’s behavior. See Verifying Circuit Correctness for details.

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.