From 71eda1678b3c2005f0d13f9bad0c3e3299c796dc Mon Sep 17 00:00:00 2001 From: jokar Date: Mon, 26 Feb 2024 12:45:34 -0600 Subject: [PATCH 1/2] copy over measure attributes --- include/Conversion/QUIRToPulse/QUIRToPulse.h | 8 ++-- lib/Conversion/QUIRToPulse/QUIRToPulse.cpp | 43 +++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/include/Conversion/QUIRToPulse/QUIRToPulse.h b/include/Conversion/QUIRToPulse/QUIRToPulse.h index 8c3e748ea..1b07bab9c 100644 --- a/include/Conversion/QUIRToPulse/QUIRToPulse.h +++ b/include/Conversion/QUIRToPulse/QUIRToPulse.h @@ -62,9 +62,9 @@ struct QUIRToPulsePass mlir::Operation *mainFuncFirstOp; // convert quir circuit to pulse sequence - void convertCircuitToSequence(mlir::quir::CallCircuitOp callCircuitOp, - mlir::func::FuncOp &mainFunc, - ModuleOp moduleOp); + mlir::pulse::CallSequenceOp + convertCircuitToSequence(mlir::quir::CallCircuitOp callCircuitOp, + mlir::func::FuncOp &mainFunc, ModuleOp moduleOp); // helper datastructure for converting quir circuit to pulse sequence; these // will be reset every time convertCircuitToSequence is called and will be // used by several functions that are called within that function @@ -149,10 +149,8 @@ struct QUIRToPulsePass mlir::OpBuilder &builder); void addCircuitToEraseList(mlir::Operation *op); - void addCallCircuitToEraseList(mlir::Operation *op); void addCircuitOperandToEraseList(mlir::Operation *op); std::vector quirCircuitEraseList; - std::vector quirCallCircuitEraseList; std::vector quirCircuitOperandEraseList; // parse the waveform containers and add them to pulseNameToWaveformMap diff --git a/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp b/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp index 648919875..831642626 100644 --- a/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp +++ b/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp @@ -26,6 +26,7 @@ #include "Dialect/Pulse/IR/PulseOps.h" #include "Dialect/Pulse/IR/PulseTypes.h" #include "Dialect/QCS/IR/QCSOps.h" +#include "Dialect/QUIR/IR/QUIRDialect.h" #include "Dialect/QUIR/IR/QUIREnums.h" #include "Dialect/QUIR/IR/QUIROps.h" #include "Dialect/QUIR/IR/QUIRTypes.h" @@ -100,16 +101,15 @@ void QUIRToPulsePass::runOnOperation() { // convert all QUIR circuits to Pulse sequences moduleOp->walk([&](CallCircuitOp callCircOp) { - convertCircuitToSequence(callCircOp, mainFunc, moduleOp); + if (isa(callCircOp->getParentOp())) + return; + auto convertedPulseCallSequenceOp = + convertCircuitToSequence(callCircOp, mainFunc, moduleOp); + if (!callCircOp->use_empty()) + callCircOp->replaceAllUsesWith(convertedPulseCallSequenceOp); + callCircOp->erase(); }); - // first erase the quir call circuits - LLVM_DEBUG(llvm::dbgs() << "\nErasing quir call circuits:\n"); - for (auto *op : quirCallCircuitEraseList) { - LLVM_DEBUG(op->dump()); - op->erase(); - } - // erase the quir circuits LLVM_DEBUG(llvm::dbgs() << "\nErasing quir circuits:\n"); for (auto *op : quirCircuitEraseList) { @@ -133,9 +133,10 @@ void QUIRToPulsePass::runOnOperation() { }); } -void QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, - mlir::func::FuncOp &mainFunc, - ModuleOp moduleOp) { +mlir::pulse::CallSequenceOp +QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, + mlir::func::FuncOp &mainFunc, + ModuleOp moduleOp) { mlir::OpBuilder builder(mainFunc); auto circuitOp = getCircuitOp(callCircuitOp); @@ -143,7 +144,6 @@ void QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, LLVM_DEBUG(llvm::dbgs() << "\nConverting QUIR circuit " << circName << ":\n"); assert(callCircuitOp && "callCircuit op is null"); assert(circuitOp && "circuit op is null"); - addCallCircuitToEraseList(callCircuitOp); addCircuitToEraseList(circuitOp); // build an empty pulse sequence @@ -188,6 +188,15 @@ void QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, auto pulseCalCallSequenceOp = entryBuilder.create( quirOp->getLoc(), pulseCalSequenceOp, pulseCalSequenceArgs); + + // copy the quir attributes of measure op (if any) + if (isa(quirOp)) { + for (auto attr : quirOp->getAttrs()) + if (llvm::isa(attr.getNameDialect())) + pulseCalCallSequenceOp->setAttr(attr.getName().str(), + attr.getValue()); + } + pulseCalCallSequenceOp->setAttr( "pulse.operands", pulseCalSequenceOp->getAttrOfType("pulse.args")); @@ -248,6 +257,8 @@ void QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, convertedPulseCallSequenceOp->setAttr( "pulse.operands", builder.getArrayAttr(convertedPulseCallSequenceOpOperandNames)); + + return convertedPulseCallSequenceOp; } void QUIRToPulsePass::processCircuitArgs( @@ -651,14 +662,6 @@ void QUIRToPulsePass::addCircuitToEraseList(mlir::Operation *op) { quirCircuitEraseList.push_back(op); } -void QUIRToPulsePass::addCallCircuitToEraseList(mlir::Operation *op) { - assert(op && "caller requested adding a null op to erase list"); - if (std::find(quirCallCircuitEraseList.begin(), - quirCallCircuitEraseList.end(), - op) == quirCallCircuitEraseList.end()) - quirCallCircuitEraseList.push_back(op); -} - void QUIRToPulsePass::addCircuitOperandToEraseList(mlir::Operation *op) { assert(op && "caller requested adding a null op to erase list"); if (std::find(quirCircuitOperandEraseList.begin(), From 15208bb3af77265a316184fcd683d1acacfd8d8d Mon Sep 17 00:00:00 2001 From: jokar Date: Wed, 6 Mar 2024 12:00:27 -0600 Subject: [PATCH 2/2] address reviews --- include/Conversion/QUIRToPulse/QUIRToPulse.h | 28 ++++++++++---------- lib/Conversion/QUIRToPulse/QUIRToPulse.cpp | 26 +++++++++--------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/Conversion/QUIRToPulse/QUIRToPulse.h b/include/Conversion/QUIRToPulse/QUIRToPulse.h index 1b07bab9c..ae2eda352 100644 --- a/include/Conversion/QUIRToPulse/QUIRToPulse.h +++ b/include/Conversion/QUIRToPulse/QUIRToPulse.h @@ -63,8 +63,8 @@ struct QUIRToPulsePass // convert quir circuit to pulse sequence mlir::pulse::CallSequenceOp - convertCircuitToSequence(mlir::quir::CallCircuitOp callCircuitOp, - mlir::func::FuncOp &mainFunc, ModuleOp moduleOp); + convertCircuitToSequence(mlir::quir::CallCircuitOp &callCircuitOp, + mlir::func::FuncOp &mainFunc, ModuleOp &moduleOp); // helper datastructure for converting quir circuit to pulse sequence; these // will be reset every time convertCircuitToSequence is called and will be // used by several functions that are called within that function @@ -75,17 +75,17 @@ struct QUIRToPulsePass // process the args of the circuit op, and add corresponding args to the // converted pulse sequence op - void processCircuitArgs(mlir::quir::CallCircuitOp callCircuitOp, - mlir::quir::CircuitOp circuitOp, - SequenceOp convertedPulseSequenceOp, + void processCircuitArgs(mlir::quir::CallCircuitOp &callCircuitOp, + mlir::quir::CircuitOp &circuitOp, + SequenceOp &convertedPulseSequenceOp, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder); // process the args of the pulse cal sequence op corresponding to quirOp void processPulseCalArgs(mlir::Operation *quirOp, - SequenceOp pulseCalSequenceOp, + SequenceOp &pulseCalSequenceOp, SmallVector &pulseCalSeqArgs, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder); void getQUIROpClassicalOperands(mlir::Operation *quirOp, @@ -93,33 +93,33 @@ struct QUIRToPulsePass std::queue &durationOperands); void processMixFrameOpArg(std::string const &mixFrameName, std::string const &portName, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &quirOpPulseCalSeqArgs, Value argumentValue, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder); void processPortOpArg(std::string const &portName, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &quirOpPulseCalSeqArgs, Value argumentValue, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder); void processWfrOpArg(std::string const &wfrName, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &quirOpPulseCalSeqArgs, Value argumentValue, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder); void processAngleArg(Value nextAngleOperand, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &quirOpPulseCalSeqArgs, mlir::OpBuilder &builder); void processDurationArg(Value frontDurOperand, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &quirOpPulseCalSeqArgs, mlir::OpBuilder &builder); // convert angle to F64 mlir::Value convertAngleToF64(Operation *angleOp, mlir::OpBuilder &builder); // convert duration to I64 - mlir::Value convertDurationToI64(mlir::quir::CallCircuitOp callCircuitOp, + mlir::Value convertDurationToI64(mlir::quir::CallCircuitOp &callCircuitOp, Operation *durOp, uint &cnt, mlir::OpBuilder &builder, mlir::func::FuncOp &mainFunc); @@ -158,7 +158,7 @@ struct QUIRToPulsePass std::map pulseNameToWaveformMap; llvm::StringMap symbolMap; - mlir::quir::CircuitOp getCircuitOp(mlir::quir::CallCircuitOp callCircuitOp); + mlir::quir::CircuitOp getCircuitOp(mlir::quir::CallCircuitOp &callCircuitOp); mlir::pulse::SequenceOp getSequenceOp(std::string const &symbolName); }; } // namespace mlir::pulse diff --git a/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp b/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp index 831642626..afea2a47c 100644 --- a/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp +++ b/lib/Conversion/QUIRToPulse/QUIRToPulse.cpp @@ -134,9 +134,9 @@ void QUIRToPulsePass::runOnOperation() { } mlir::pulse::CallSequenceOp -QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, +QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp &callCircuitOp, mlir::func::FuncOp &mainFunc, - ModuleOp moduleOp) { + ModuleOp &moduleOp) { mlir::OpBuilder builder(mainFunc); auto circuitOp = getCircuitOp(callCircuitOp); @@ -262,8 +262,8 @@ QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp, } void QUIRToPulsePass::processCircuitArgs( - mlir::quir::CallCircuitOp callCircuitOp, mlir::quir::CircuitOp circuitOp, - SequenceOp convertedPulseSequenceOp, mlir::func::FuncOp &mainFunc, + mlir::quir::CallCircuitOp &callCircuitOp, mlir::quir::CircuitOp &circuitOp, + SequenceOp &convertedPulseSequenceOp, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder) { for (uint cnt = 0; cnt < circuitOp.getNumArguments(); cnt++) { auto arg = circuitOp.getArgument(cnt); @@ -307,9 +307,9 @@ void QUIRToPulsePass::processCircuitArgs( } void QUIRToPulsePass::processPulseCalArgs( - mlir::Operation *quirOp, SequenceOp pulseCalSequenceOp, + mlir::Operation *quirOp, SequenceOp &pulseCalSequenceOp, SmallVector &pulseCalSequenceArgs, - SequenceOp convertedPulseSequenceOp, mlir::func::FuncOp &mainFunc, + SequenceOp &convertedPulseSequenceOp, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder) { // get the classical operands of the quir op @@ -405,7 +405,7 @@ void QUIRToPulsePass::getQUIROpClassicalOperands( void QUIRToPulsePass::processMixFrameOpArg( std::string const &mixFrameName, std::string const &portName, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &pulseCalSequenceArgs, Value argumentValue, mlir::func::FuncOp &mainFunc, mlir::OpBuilder &builder) { auto mixedFrameOp = @@ -433,7 +433,7 @@ void QUIRToPulsePass::processMixFrameOpArg( } void QUIRToPulsePass::processPortOpArg(std::string const &portName, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &pulseCalSequenceArgs, Value argumentValue, mlir::func::FuncOp &mainFunc, @@ -461,7 +461,7 @@ void QUIRToPulsePass::processPortOpArg(std::string const &portName, } void QUIRToPulsePass::processWfrOpArg(std::string const &wfrName, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &pulseCalSequenceArgs, Value argumentValue, mlir::func::FuncOp &mainFunc, @@ -490,7 +490,7 @@ void QUIRToPulsePass::processWfrOpArg(std::string const &wfrName, } void QUIRToPulsePass::processAngleArg(Value nextAngleOperand, - SequenceOp convertedPulseSequenceOp, + SequenceOp &convertedPulseSequenceOp, SmallVector &pulseCalSequenceArgs, mlir::OpBuilder &entryBuilder) { if (nextAngleOperand.isa()) { @@ -518,7 +518,7 @@ void QUIRToPulsePass::processAngleArg(Value nextAngleOperand, } void QUIRToPulsePass::processDurationArg( - Value nextDurationOperand, SequenceOp convertedPulseSequenceOp, + Value nextDurationOperand, SequenceOp &convertedPulseSequenceOp, SmallVector &pulseCalSequenceArgs, mlir::OpBuilder &entryBuilder) { if (nextDurationOperand.isa()) { uint const circNum = @@ -589,7 +589,7 @@ mlir::Value QUIRToPulsePass::convertAngleToF64(Operation *angleOp, } mlir::Value QUIRToPulsePass::convertDurationToI64( - mlir::quir::CallCircuitOp callCircuitOp, Operation *durationOp, uint &cnt, + mlir::quir::CallCircuitOp &callCircuitOp, Operation *durationOp, uint &cnt, mlir::OpBuilder &builder, mlir::func::FuncOp &mainFunc) { assert(durationOp && "duration op is null"); std::string const durLocHash = @@ -694,7 +694,7 @@ void QUIRToPulsePass::parsePulseWaveformContainerOps( } mlir::quir::CircuitOp -QUIRToPulsePass::getCircuitOp(CallCircuitOp callCircuitOp) { +QUIRToPulsePass::getCircuitOp(CallCircuitOp &callCircuitOp) { auto search = symbolMap.find(callCircuitOp.getCallee()); assert(search != symbolMap.end() && "matching circuit not found"); auto circuitOp = dyn_cast(search->second);