Using MQSSCI as a Library¶
The Passes page shows how to run passes through the mqss-opt/mqss-cc command-line
tools. This page is for the case where you don’t want a separate command-line step at all — you want
your own C++ program to load an MLIR module and run MQSSCI passes on it directly.
The two are not different features: mqss-opt itself is just a small C++ program that does exactly
what’s shown below. Calling it from your own code gives you the same passes, without shelling out to
a separate binary.
Before You Start¶
Your project needs to link against the MQSSCI library first. That’s a one-time CMake setup step —
see
Integrating the MQSS Quantum Compilation Suite within your project
for how to fetch MQSSCI with FetchContent and link your target against mqss-ci::mqss-ci. The
rest of this page assumes that step is done and focuses purely on the C++ side.
A Minimal Example¶
Here’s the smallest useful program: load an MLIR file, run the O1 preset pipeline on it, then
lower the result to OpenQASM 2.
#include "Passes/Transforms/Dialects.h"
#include "Passes/Transforms/Pipelines.h"
// 1. Tell MLIR about the dialects MQSSCI's passes need (Quake, Catalyst-quantum, etc.)
mlir::DialectRegistry registry;
mqss::opt::registerMQSSDialects(registry);
mlir::MLIRContext context(registry);
context.loadAllAvailableDialects();
// 2. Parse your MLIR file into a module
auto module = mlir::parseSourceFile<mlir::ModuleOp>(src_path, &context);
if (!module) {
llvm::errs() << "failed to parse MLIR file\n";
}
// 3. Build a pass manager and add a preset optimization pipeline
mlir::PassManager pm(&context);
mqss::opt::O1(pm);
if (mlir::failed(pm.run(*module))) {
llvm::errs() << "Compiler: Pipeline failed\n";
}
// 4. Lower the optimized module to OpenQASM 2
pm.addPass(mqss::opt::QuakeToQASM2Pass());
if (mlir::failed(pm.run(*module))) {
llvm::errs() << "Compiler: Conversion of Quake to QASM2 failed\n";
}
Walking through it:
registerMQSSDialectsfills in aDialectRegistrywith every MLIR dialect the passes operate on or lower into. Do this before parsing anything — the parser needs to recognize the dialect operations in your input.mlir::parseSourceFilereads your MLIR/Quake/Catalyst-quantum source file into an in-memory module.mqss::opt::O1(pm)appends the wholeO1preset pipeline to the pass manager in one call.O2andO3work the same way. See Pass Pipelines for what each preset includes.mqss::opt::QuakeToQASM2Pass()is a code-generation pass — it’s added and run separately from the optimization pipeline, same as chaining--O1 --quake-to-qasm2on themqss-optcommand line.
If you’d rather capture the OpenQASM output in a string instead of printing it, QuakeToQASM2Pass
also accepts an llvm::raw_ostream&:
std::string qasm;
llvm::raw_string_ostream os(qasm);
pm.addPass(mqss::opt::QuakeToQASM2Pass(os));
Invoking Passes: Same Rules as the Developer Guide¶
Everything beyond this minimal example — running individual passes instead of a preset, passing
options to a pass (e.g. CommonGateCancellationPassOptions), or assembling a fully custom pipeline
— works exactly as described in
Integrating the MQSS Quantum Compilation Suite within your project.
There’s no separate API for library users: whether you’re writing a pass yourself or just consuming
the library, you build the same mlir::OpPassManager and call the same factory functions from
Passes/Transforms/Transforms.h.
For the full list of available passes, their options, and valid option values, see Passes.