Skip to content
Draft
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
15 changes: 11 additions & 4 deletions mlir/include/mlir/Compiler/CompilerPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ struct QuantumCompilerConfig {

/// Disable quaternion-based single-qubit rotation gate merging
bool disableMergeSingleQubitRotationGates = false;

/// (TODO:) Pointer to a QDMI device
void* device = nullptr;
};

/**
Expand All @@ -60,6 +63,8 @@ struct CompilationRecord {
std::string afterQCOCanon;
std::string afterOptimization;
std::string afterOptimizationCanon;
std::string afterTranspilation;
std::string afterTranspilationCanon;
std::string afterQCConversion;
std::string afterQCCanon;
std::string afterQIRConversion;
Expand All @@ -80,10 +85,12 @@ struct CompilationRecord {
* 4. QCO cleanup pipeline
* 5. Quantum optimization passes
* 6. QCO cleanup pipeline
* 7. QC dialect - converted back for backend lowering
* 8. QC cleanup pipeline
* 9. QIR (Quantum Intermediate Representation) - optional final lowering
* 10. QIR cleanup pipeline
* 7. Quantum transpilation passes - optional fit to hardware constraints
* 8. QCO cleanup pipeline
* 9. QC dialect - converted back for backend lowering
* 10. QC cleanup pipeline
* 11. QIR (Quantum Intermediate Representation) - optional final lowering
* 12. QIR cleanup pipeline
*
* Following MLIR best practices, simplification and dead-value cleanup are
* run after each major transformation stage.
Expand Down
44 changes: 38 additions & 6 deletions mlir/lib/Compiler/CompilerPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ QuantumCompilerPipeline::runPipeline(ModuleOp module,
// 8. QC cleanup
// 9. QC-to-QIR conversion (optional)
// 10. QIR cleanup (optional)
auto totalStages = 8;
auto totalStages = 10;
if (config_.convertToQIR) {
totalStages += 2;
}
Expand Down Expand Up @@ -158,11 +158,43 @@ QuantumCompilerPipeline::runPipeline(ModuleOp module,
if (record != nullptr && config_.recordIntermediates) {
record->afterOptimizationCanon = captureIR(module);
if (config_.printIRAfterAllStages) {
prettyPrintStage(module, "Final QCO Cleanup", ++currentStage,
prettyPrintStage(module, "Post-Optimization QCO Cleanup", ++currentStage,
totalStages);
}
}
// Stage 7: QCO-to-QC conversion
// Stage 7: Transpilation passes (optional)
if (config_.device != nullptr) {
if (failed(runStage([&](PassManager& pm) {
/// TODO:
// Individual passes use the device handle to query properties.
// pm.addPass(createNativeGateDecompositionPass(config_.device))
// if (device.hasCouplingMap())
// pm.addPass(createMappingPass(config_.device))
}))) {
return failure();
}
if (record != nullptr && config_.recordIntermediates) {
record->afterTranspilation = captureIR(module);
if (config_.printIRAfterAllStages) {
prettyPrintStage(module, "Transpilation Passes", ++currentStage,
totalStages);
}
}
// Stage 8: QCO cleanup (optional)
if (failed(runStage(
[&](PassManager& pm) { populateQCOCleanupPipeline(pm); }))) {
return failure();
}
if (record != nullptr && config_.recordIntermediates) {
record->afterTranspilationCanon = captureIR(module);
if (config_.printIRAfterAllStages) {
prettyPrintStage(module, "Post-Transpilation QCO Cleanup",
++currentStage, totalStages);
}
}
}

// Stage 9: QCO-to-QC conversion
if (failed(runStage([&](PassManager& pm) { pm.addPass(createQCOToQC()); }))) {
return failure();
}
Expand All @@ -173,7 +205,7 @@ QuantumCompilerPipeline::runPipeline(ModuleOp module,
totalStages);
}
}
// Stage 8: QC cleanup
// Stage 10: QC cleanup
if (failed(
runStage([&](PassManager& pm) { populateQCCleanupPipeline(pm); }))) {
return failure();
Expand All @@ -184,7 +216,7 @@ QuantumCompilerPipeline::runPipeline(ModuleOp module,
prettyPrintStage(module, "Final QC Cleanup", ++currentStage, totalStages);
}
}
// Stage 9: QC-to-QIR conversion (optional)
// Stage 11: QC-to-QIR conversion (optional)
if (config_.convertToQIR) {
if (failed(
runStage([&](PassManager& pm) { pm.addPass(createQCToQIR()); }))) {
Expand All @@ -197,7 +229,7 @@ QuantumCompilerPipeline::runPipeline(ModuleOp module,
totalStages);
}
}
// Stage 10: QIR cleanup (optional)
// Stage 12: QIR cleanup (optional)
if (failed(runStage(
[&](PassManager& pm) { populateQIRCleanupPipeline(pm); }))) {
return failure();
Expand Down
17 changes: 17 additions & 0 deletions mlir/tools/mqt-cc/mqt-cc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,18 @@
#include <mlir/Support/LogicalResult.h>

#include <exception>
#include <optional>
#include <string>
#include <utility>

using namespace llvm;
using namespace mlir;

// Command-line options
static cl::opt<std::optional<std::string>>
arch("arch", cl::desc("Specify the target architecture"),
cl::init(std::nullopt));

static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input .mlir/.qasm file>"),
cl::init("-"));
Expand Down Expand Up @@ -177,6 +182,18 @@ int main(int argc, char** argv) {
config.disableMergeSingleQubitRotationGates =
disableMergeSingleQubitRotationGates;

if (arch != std::nullopt) {
/// TODO:
// 1) Load the dynamic device libraries with the given name
// e.g. <arch>_device.dylib
// or raise error if the library is not found.
// 2) Set the device handle in the QuantumCompilerConfig
// Individual passes use the device handle to query properties.
//
// Also: Make sure that everything still works if the arch options isn't
// supplied.
}

// Run the compilation pipeline
CompilationRecord record;
if (const QuantumCompilerPipeline pipeline(config);
Expand Down
Loading