Loading mlir/tools/qcor-mlir-tool.cpp +6 −4 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ cl::opt<bool> mlir_quantum_opt( "q-optimize", cl::desc("Turn on MLIR-level quantum instruction optimizations.")); cl::opt<bool> mlir_quantum_validate( "q-validate", cl::desc("Turn on MLIR-level validation transformation.")); cl::opt<std::string> mlir_specified_func_name( "internal-func-name", cl::desc("qcor provided function name")); Loading Loading @@ -153,10 +156,9 @@ int main(int argc, char **argv) { std::string RED = "\033[91m"; std::string CLEAR = "\033[0m"; if (qoptimizations) { // Add optimization passes qcor::configureOptimizationPasses(pm); } // Add optimization passes and/or validation passes qcor::configureOptimizationPasses(pm, {qoptimizations, mlir_quantum_validate}); if (emitAction == Action::DumpMLIR) { if (qoptimizations) { Loading mlir/transforms/CMakeLists.txt +1 −1 Original line number Diff line number Diff line set(LIBRARY_NAME quantum-to-llvm-lowering) file(GLOB SRC *.cpp lowering/*.cpp optimizations/*.cpp) file(GLOB SRC *.cpp lowering/*.cpp optimizations/*.cpp validation/*.cpp) add_subdirectory(optimizations/utils) Loading mlir/transforms/pass_manager.hpp +43 −30 Original line number Diff line number Diff line Loading @@ -20,16 +20,23 @@ #include "optimizations/ModifierBlockInliner.hpp" #include "quantum_to_llvm.hpp" #include "lowering/ModifierRegionLowering.hpp" #include "validation/MirrorCircuitPass.hpp" // Construct QCOR MLIR pass manager: // Make sure we use the same set of passes and configs // across different use cases of MLIR compilation. namespace qcor { void configureOptimizationPasses(mlir::PassManager &passManager) { struct PassOptions { bool Optimize = true; bool Validate = false; }; void configureOptimizationPasses(mlir::PassManager &passManager, const PassOptions &opts = PassOptions()) { if (opts.Optimize) { // Try inline both before and after loop unroll. passManager.addPass(mlir::createInlinerPass()); passManager.addPass(std::make_unique<ModifierBlockInlinerPass>()); auto loop_unroller = mlir::createLoopUnrollPass(/*unrollFactor*/-1, /*unrollUpToFactor*/ false, /*unrollFull*/true); auto loop_unroller = mlir::createLoopUnrollPass( /*unrollFactor*/ -1, /*unrollUpToFactor*/ false, /*unrollFull*/ true); // Nest a pass manager that operates on functions within the one which // operates on ModuleOp. OpPassManager &nestedFunctionPM = passManager.nest<mlir::FuncOp>(); Loading @@ -42,7 +49,8 @@ void configureOptimizationPasses(mlir::PassManager &passManager) { constexpr int N_REPS = 10; for (int i = 0; i < N_REPS; ++i) { // Simple Identity pair removals passManager.addPass(std::make_unique<SingleQubitIdentityPairRemovalPass>()); passManager.addPass( std::make_unique<SingleQubitIdentityPairRemovalPass>()); passManager.addPass(std::make_unique<CNOTIdentityPairRemovalPass>()); passManager.addPass(std::make_unique<DuplicateResetRemovalPass>()); Loading @@ -59,4 +67,9 @@ void configureOptimizationPasses(mlir::PassManager &passManager) { // Remove dead code passManager.addPass(std::make_unique<RemoveUnusedQIRCallsPass>()); } if (opts.Validate) { passManager.addPass(std::make_unique<MirrorCircuitTransformPass>()); } } } // namespace qcor No newline at end of file mlir/transforms/validation/MirrorCircuitPass.cpp 0 → 100644 +23 −0 Original line number Diff line number Diff line #include "MirrorCircuitPass.hpp" #include "Quantum/QuantumOps.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" #include "mlir/IR/Matchers.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassManager.h" #include "mlir/Target/LLVMIR.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" #include <iostream> namespace qcor { void MirrorCircuitTransformPass::getDependentDialects( DialectRegistry ®istry) const { registry.insert<LLVM::LLVMDialect>(); } void MirrorCircuitTransformPass::runOnOperation() { // TODO } } // namespace qcor No newline at end of file mlir/transforms/validation/MirrorCircuitPass.hpp 0 → 100644 +19 −0 Original line number Diff line number Diff line #pragma once #include "Quantum/QuantumOps.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassManager.h" #include "mlir/Target/LLVMIR.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" using namespace mlir; namespace qcor { // A pass to add mirror circuits to the IR struct MirrorCircuitTransformPass : public PassWrapper<MirrorCircuitTransformPass, OperationPass<ModuleOp>> { void getDependentDialects(DialectRegistry ®istry) const override; void runOnOperation() final; MirrorCircuitTransformPass() {} }; } // namespace qcor No newline at end of file Loading
mlir/tools/qcor-mlir-tool.cpp +6 −4 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ cl::opt<bool> mlir_quantum_opt( "q-optimize", cl::desc("Turn on MLIR-level quantum instruction optimizations.")); cl::opt<bool> mlir_quantum_validate( "q-validate", cl::desc("Turn on MLIR-level validation transformation.")); cl::opt<std::string> mlir_specified_func_name( "internal-func-name", cl::desc("qcor provided function name")); Loading Loading @@ -153,10 +156,9 @@ int main(int argc, char **argv) { std::string RED = "\033[91m"; std::string CLEAR = "\033[0m"; if (qoptimizations) { // Add optimization passes qcor::configureOptimizationPasses(pm); } // Add optimization passes and/or validation passes qcor::configureOptimizationPasses(pm, {qoptimizations, mlir_quantum_validate}); if (emitAction == Action::DumpMLIR) { if (qoptimizations) { Loading
mlir/transforms/CMakeLists.txt +1 −1 Original line number Diff line number Diff line set(LIBRARY_NAME quantum-to-llvm-lowering) file(GLOB SRC *.cpp lowering/*.cpp optimizations/*.cpp) file(GLOB SRC *.cpp lowering/*.cpp optimizations/*.cpp validation/*.cpp) add_subdirectory(optimizations/utils) Loading
mlir/transforms/pass_manager.hpp +43 −30 Original line number Diff line number Diff line Loading @@ -20,16 +20,23 @@ #include "optimizations/ModifierBlockInliner.hpp" #include "quantum_to_llvm.hpp" #include "lowering/ModifierRegionLowering.hpp" #include "validation/MirrorCircuitPass.hpp" // Construct QCOR MLIR pass manager: // Make sure we use the same set of passes and configs // across different use cases of MLIR compilation. namespace qcor { void configureOptimizationPasses(mlir::PassManager &passManager) { struct PassOptions { bool Optimize = true; bool Validate = false; }; void configureOptimizationPasses(mlir::PassManager &passManager, const PassOptions &opts = PassOptions()) { if (opts.Optimize) { // Try inline both before and after loop unroll. passManager.addPass(mlir::createInlinerPass()); passManager.addPass(std::make_unique<ModifierBlockInlinerPass>()); auto loop_unroller = mlir::createLoopUnrollPass(/*unrollFactor*/-1, /*unrollUpToFactor*/ false, /*unrollFull*/true); auto loop_unroller = mlir::createLoopUnrollPass( /*unrollFactor*/ -1, /*unrollUpToFactor*/ false, /*unrollFull*/ true); // Nest a pass manager that operates on functions within the one which // operates on ModuleOp. OpPassManager &nestedFunctionPM = passManager.nest<mlir::FuncOp>(); Loading @@ -42,7 +49,8 @@ void configureOptimizationPasses(mlir::PassManager &passManager) { constexpr int N_REPS = 10; for (int i = 0; i < N_REPS; ++i) { // Simple Identity pair removals passManager.addPass(std::make_unique<SingleQubitIdentityPairRemovalPass>()); passManager.addPass( std::make_unique<SingleQubitIdentityPairRemovalPass>()); passManager.addPass(std::make_unique<CNOTIdentityPairRemovalPass>()); passManager.addPass(std::make_unique<DuplicateResetRemovalPass>()); Loading @@ -59,4 +67,9 @@ void configureOptimizationPasses(mlir::PassManager &passManager) { // Remove dead code passManager.addPass(std::make_unique<RemoveUnusedQIRCallsPass>()); } if (opts.Validate) { passManager.addPass(std::make_unique<MirrorCircuitTransformPass>()); } } } // namespace qcor No newline at end of file
mlir/transforms/validation/MirrorCircuitPass.cpp 0 → 100644 +23 −0 Original line number Diff line number Diff line #include "MirrorCircuitPass.hpp" #include "Quantum/QuantumOps.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" #include "mlir/IR/Matchers.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassManager.h" #include "mlir/Target/LLVMIR.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" #include <iostream> namespace qcor { void MirrorCircuitTransformPass::getDependentDialects( DialectRegistry ®istry) const { registry.insert<LLVM::LLVMDialect>(); } void MirrorCircuitTransformPass::runOnOperation() { // TODO } } // namespace qcor No newline at end of file
mlir/transforms/validation/MirrorCircuitPass.hpp 0 → 100644 +19 −0 Original line number Diff line number Diff line #pragma once #include "Quantum/QuantumOps.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassManager.h" #include "mlir/Target/LLVMIR.h" #include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/Passes.h" using namespace mlir; namespace qcor { // A pass to add mirror circuits to the IR struct MirrorCircuitTransformPass : public PassWrapper<MirrorCircuitTransformPass, OperationPass<ModuleOp>> { void getDependentDialects(DialectRegistry ®istry) const override; void runOnOperation() final; MirrorCircuitTransformPass() {} }; } // namespace qcor No newline at end of file