Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel
- ✨ Add conversions between `jeff` and QCO ([#1479], [#1548], [#1565], [#1637], [#1676], [#1706]) ([**@denialhaag**], [**@burgholzer**])
- ✨ Add a `place-and-route` pass for mapping circuits to architectures with restricted topologies ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588], [#1600], [#1664], [#1709], [#1716], [#1748]) ([**@MatthiasReumann**], [**@burgholzer**])
- ✨ Add initial infrastructure for new QC and QCO MLIR dialects
([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1717], [#1728], [#1730], [#1749], [#1762])
([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1717], [#1728], [#1730], [#1749], [#1762], [#1765])
([**@burgholzer**], [**@denialhaag**], [**@taminob**], [**@DRovara**], [**@li-mingbao**], [**@Ectras**], [**@MatthiasReumann**], [**@simon1hofmann**])

### Changed
Expand Down Expand Up @@ -402,6 +402,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool

<!-- PR links -->

[#1765]: https://github.com/munich-quantum-toolkit/core/pull/1765
[#1762]: https://github.com/munich-quantum-toolkit/core/pull/1762
[#1749]: https://github.com/munich-quantum-toolkit/core/pull/1749
[#1748]: https://github.com/munich-quantum-toolkit/core/pull/1748
Expand Down
140 changes: 70 additions & 70 deletions mlir/tools/mqt-cc/mqt-cc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,53 +39,56 @@
#include <string>
#include <utility>

using namespace llvm;
using namespace mlir;

// Command-line options
static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input .mlir/.qasm file>"),
cl::init("-"));
static llvm::cl::opt<std::string>
inputFilename(llvm::cl::Positional,
llvm::cl::desc("<input .mlir/.qasm file>"),
llvm::cl::init("-"));

static cl::opt<std::string> outputFilename("o", cl::desc("Output filename"),
cl::value_desc("filename"),
cl::init("-"));
static llvm::cl::opt<std::string>
outputFilename("o", llvm::cl::desc("Output filename"),
llvm::cl::value_desc("filename"), llvm::cl::init("-"));

static cl::opt<bool> convertToQIR("emit-qir",
cl::desc("Convert to QIR at the end"),
cl::init(false));
static llvm::cl::opt<bool>
convertToQIR("emit-qir", llvm::cl::desc("Convert to QIR at the end"),
llvm::cl::init(false));

static cl::opt<bool> recordIntermediates(
static llvm::cl::opt<bool> recordIntermediates(
"record-intermediates",
cl::desc("Record intermediate IR after each compiler stage"),
cl::init(false));
llvm::cl::desc("Record intermediate IR after each compiler stage"),
llvm::cl::init(false));

static cl::opt<bool> enableTiming("mlir-timing",
cl::desc("Enable pass timing statistics"),
cl::init(false));
static llvm::cl::opt<bool>
enableTiming("mlir-timing", llvm::cl::desc("Enable pass timing statistics"),
llvm::cl::init(false));

static cl::opt<bool> enableStatistics("mlir-statistics",
cl::desc("Enable pass statistics"),
cl::init(false));
static llvm::cl::opt<bool>
enableStatistics("mlir-statistics",
llvm::cl::desc("Enable pass statistics"),
llvm::cl::init(false));

static cl::opt<bool>
static llvm::cl::opt<bool>
printIRAfterAllStages("mlir-print-ir-after-all-stages",
cl::desc("Print IR after each compiler stage"),
cl::init(false));
llvm::cl::desc("Print IR after each compiler stage"),
llvm::cl::init(false));

static cl::opt<bool> disableMergeSingleQubitRotationGates(
static llvm::cl::opt<bool> disableMergeSingleQubitRotationGates(
"disable-merge-single-qubit-rotation-gates",
cl::desc("Disable quaternion-based single-qubit rotation gate merging"),
cl::init(false));
llvm::cl::desc(
"Disable quaternion-based single-qubit rotation gate merging"),
llvm::cl::init(false));

static cl::opt<bool> enableHadamardLifting(
"hadamard-lifting", cl::desc("Apply Hadamard lifting during optimization"),
cl::init(false));
static llvm::cl::opt<bool> enableHadamardLifting(
"hadamard-lifting",
llvm::cl::desc("Apply Hadamard lifting during optimization"),
llvm::cl::init(false));

/**
* @brief Load and parse a .qasm file
*/
static OwningOpRef<ModuleOp> loadQASMFile(StringRef filename,
static OwningOpRef<ModuleOp> loadQASMFile(llvm::StringRef filename,
MLIRContext* context) {
try {
// Parse the input QASM file
Expand All @@ -94,43 +97,44 @@ static OwningOpRef<ModuleOp> loadQASMFile(StringRef filename,
// Translate to MLIR dialect QC
return translateQuantumComputationToQC(context, qc);
} catch (const qasm3::CompilerError& exception) {
errs() << "Failed to parse QASM file '" << filename << "': '"
<< exception.what() << "'\n";
llvm::errs() << "Failed to parse QASM file '" << filename << "': '"
<< exception.what() << "'\n";
} catch (const std::exception& exception) {
errs() << "Failed to load QASM file '" << filename << "': '"
<< exception.what() << "'\n";
llvm::errs() << "Failed to load QASM file '" << filename << "': '"
<< exception.what() << "'\n";
}
return nullptr;
}

/**
* @brief Load and parse a .mlir file
*/
static OwningOpRef<ModuleOp> loadMLIRFile(StringRef filename,
static OwningOpRef<ModuleOp> loadMLIRFile(llvm::StringRef filename,
MLIRContext* context) {
// Set up the input file
std::string errorMessage;
auto file = openInputFile(filename, &errorMessage);
if (!file) {
errs() << "Failed to load file '" << filename << "': '" << errorMessage
<< "'\n";
llvm::errs() << "Failed to load file '" << filename << "': '"
<< errorMessage << "'\n";
return nullptr;
}

// Parse the input MLIR
SourceMgr sourceMgr;
llvm::SourceMgr sourceMgr;
sourceMgr.AddNewSourceBuffer(std::move(file), SMLoc());
return parseSourceFile<ModuleOp>(sourceMgr, context);
}

/**
* @brief Write the module to the output file
*/
static mlir::LogicalResult writeOutput(ModuleOp module, StringRef filename) {
static mlir::LogicalResult writeOutput(ModuleOp module,
llvm::StringRef filename) {
std::string errorMessage;
const auto output = openOutputFile(filename, &errorMessage);
if (!output) {
errs() << errorMessage << "\n";
llvm::errs() << errorMessage << "\n";
return mlir::failure();
}

Expand All @@ -140,22 +144,17 @@ static mlir::LogicalResult writeOutput(ModuleOp module, StringRef filename) {
}

int main(int argc, char** argv) {
const InitLLVM y(argc, argv);
const llvm::InitLLVM y(argc, argv);

// Parse command-line options; exit on error and print to stderr
cl::ParseCommandLineOptions(argc, argv, "MQT Core Compiler Driver\n");
llvm::cl::ParseCommandLineOptions(argc, argv, "MQT Core Compiler Driver\n");

// Set up MLIR context with all required dialects
DialectRegistry registry;
registry.insert<mlir::qc::QCDialect>();
registry.insert<qco::QCODialect>();
registry.insert<arith::ArithDialect>();
registry.insert<cf::ControlFlowDialect>();
registry.insert<func::FuncDialect>();
registry.insert<scf::SCFDialect>();
registry.insert<LLVM::LLVMDialect>();
registry.insert<mlir::memref::MemRefDialect>();
registry.insert<qtensor::QTensorDialect>();
registry
.insert<arith::ArithDialect, cf::ControlFlowDialect, func::FuncDialect,
LLVM::LLVMDialect, memref::MemRefDialect, mlir::qc::QCDialect,
qco::QCODialect, qtensor::QTensorDialect, scf::SCFDialect>();

MLIRContext context(registry);
context.loadAllAvailableDialects();
Expand Down Expand Up @@ -188,34 +187,35 @@ int main(int argc, char** argv) {
pipeline
.runPipeline(module.get(), recordIntermediates ? &record : nullptr)
.failed()) {
errs() << "Compilation pipeline failed\n";
llvm::errs() << "Compilation pipeline failed\n";
return 1;
}

if (recordIntermediates) {
outs() << "=== Compilation Record ===\n";
outs() << "After QC Import:\n" << record.afterQCImport << "\n";
outs() << "After Initial QC Canonicalization:\n"
<< record.afterInitialCanon << "\n";
outs() << "After QC-to-QCO Conversion:\n"
<< record.afterQCOConversion << "\n";
outs() << "After Initial QCO Canonicalization:\n"
<< record.afterQCOCanon << "\n";
outs() << "After Optimization:\n" << record.afterOptimization << "\n";
outs() << "After Final QCO Canonicalization:\n"
<< record.afterOptimizationCanon << "\n";
outs() << "After QCO-to-QC Conversion:\n"
<< record.afterQCConversion << "\n";
outs() << "After Final QC Canonicalization:\n"
<< record.afterQCCanon << "\n";
outs() << "After QC-to-QIR Conversion:\n"
<< record.afterQIRConversion << "\n";
outs() << "After QIR Canonicalization:\n" << record.afterQIRCanon << "\n";
llvm::outs() << "=== Compilation Record ===\n";
llvm::outs() << "After QC Import:\n" << record.afterQCImport << "\n";
llvm::outs() << "After Initial QC Canonicalization:\n"
<< record.afterInitialCanon << "\n";
llvm::outs() << "After QC-to-QCO Conversion:\n"
<< record.afterQCOConversion << "\n";
llvm::outs() << "After Initial QCO Canonicalization:\n"
<< record.afterQCOCanon << "\n";
llvm::outs() << "After Optimization:\n" << record.afterOptimization << "\n";
llvm::outs() << "After Final QCO Canonicalization:\n"
<< record.afterOptimizationCanon << "\n";
llvm::outs() << "After QCO-to-QC Conversion:\n"
<< record.afterQCConversion << "\n";
llvm::outs() << "After Final QC Canonicalization:\n"
<< record.afterQCCanon << "\n";
llvm::outs() << "After QC-to-QIR Conversion:\n"
<< record.afterQIRConversion << "\n";
llvm::outs() << "After QIR Canonicalization:\n"
<< record.afterQIRCanon << "\n";
}

// Write the output
if (writeOutput(module.get(), outputFilename).failed()) {
errs() << "Failed to write output file: " << outputFilename << "\n";
llvm::errs() << "Failed to write output file: " << outputFilename << "\n";
return 1;
}

Expand Down
Loading