Skip to content

Commit d78b3dd

Browse files
[Backport 3.10]Update parameter/constant op handling for performance (#335) (#337)
This PR updates how parameters are handled. They are now directly read from "parameter_load" ops which removes the need for QUIR variable analysis and casting which significantly improves performance of large parameter programs by reducing the total number of operations in the program. This also cuts down on the total number of arguments to each circuit/sequence by storing the parameter loads/constants directly in the sequence itself For example before for the program below ```qasm OPENQASM 3; qubit $0; qubit $1; qubit $2; gate sx q { } gate rz(phi) q { } input float[64] theta = 3.14159265358979; input angle phi; sx $0; rz(theta) $0; sx $0; rz(phi) $1; rz(3.141592) $1; rz(theta) $2; rz(phi) $2; bit b; b = measure $0; ``` The MLIR generated is now: ```mlir module { func.func @sx(%arg0: !quir.qubit<1>) attributes {quir.classicalOnly = false} { return } func.func @rz(%arg0: !quir.qubit<1>, %arg1: !quir.angle<64>) attributes {quir.classicalOnly = false} { return } quir.circuit @circuit_0(%arg0: !quir.qubit<1> {quir.physicalId = 0 : i32}, %arg1: !quir.qubit<1> {quir.physicalId = 1 : i32}, %arg2: !quir.qubit<1> {quir.physicalId = 2 : i32}) -> i1 attributes {quir.classicalOnly = false, quir.physicalIds = [0 : i32, 1 : i32, 2 : i32]} { quir.call_gate @sx(%arg0) : (!quir.qubit<1>) -> () %0 = qcs.parameter_load "theta" : !quir.angle<64> {initialValue = 3.14159265358979 : f64} quir.call_gate @rz(%arg0, %0) : (!quir.qubit<1>, !quir.angle<64>) -> () quir.call_gate @sx(%arg0) : (!quir.qubit<1>) -> () %1 = qcs.parameter_load "phi" : !quir.angle<64> quir.call_gate @rz(%arg1, %1) : (!quir.qubit<1>, !quir.angle<64>) -> () %angle = quir.constant #quir.angle<3.1415920000000002> : !quir.angle<64> quir.call_gate @rz(%arg1, %angle) : (!quir.qubit<1>, !quir.angle<64>) -> () %2 = qcs.parameter_load "theta" : !quir.angle<64> {initialValue = 3.14159265358979 : f64} quir.call_gate @rz(%arg2, %2) : (!quir.qubit<1>, !quir.angle<64>) -> () %3 = qcs.parameter_load "phi" : !quir.angle<64> quir.call_gate @rz(%arg2, %3) : (!quir.qubit<1>, !quir.angle<64>) -> () %4 = quir.measure(%arg0) {quir.noFastPathComm, quir.noJunoComm, quir.noJunoUse} : (!quir.qubit<1>) -> i1 quir.return %4 : i1 } func.func @main() -> i32 attributes {quir.classicalOnly = false} { %c0_i32 = arith.constant 0 : i32 %dur = quir.constant #quir.duration<4.500000e+06> : !quir.duration<dt> %c1 = arith.constant 1 : index %c1000 = arith.constant 1000 : index %c0 = arith.constant 0 : index qcs.init scf.for %arg0 = %c0 to %c1000 step %c1 { quir.delay %dur, () : !quir.duration<dt>, () -> () qcs.shot_init {qcs.num_shots = 1000 : i32} %0 = quir.declare_qubit {id = 0 : i32} : !quir.qubit<1> %1 = quir.declare_qubit {id = 1 : i32} : !quir.qubit<1> %2 = quir.declare_qubit {id = 2 : i32} : !quir.qubit<1> %3 = quir.call_circuit @circuit_0(%0, %1, %2) : (!quir.qubit<1>, !quir.qubit<1>, !quir.qubit<1>) -> i1 } {qcs.shot_loop, quir.classicalOnly = false, quir.physicalIds = [0 : i32, 1 : i32, 2 : i32]} qcs.finalize return %c0_i32 : i32 } } ``` Co-authored-by: Thomas Alexander <[email protected]>
1 parent a6a85ff commit d78b3dd

25 files changed

+261
-247
lines changed

conan/qasm/conandata.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
sources:
2-
hash: "f6d695fd9f18462e65f6290d05ccb4ccb371b288"
2+
hash: "ec7731bf645240a597cd9ebb2c395b114f155ed2"
33
requirements:
44
- "gmp/6.3.0"
55
- "mpfr/4.1.0"

conan/qasm/conanfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
class QasmConan(ConanFile):
1919
name = "qasm"
20-
version = "0.3.2"
20+
version = "0.3.3"
2121
url = "https://github.com/openqasm/qe-qasm.git"
2222
settings = "os", "compiler", "build_type", "arch"
2323
options = {"shared": [True, False], "examples": [True, False]}

conandata.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ requirements:
77
- pybind11/2.11.1
88
- clang-tools-extra/17.0.5-0@
99
- llvm/17.0.5-0@
10-
- qasm/0.3.2@qss/stable
10+
- qasm/0.3.3@qss/stable

include/Conversion/QUIRToPulse/QUIRToPulse.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ struct QUIRToPulsePass
127127
mlir::func::FuncOp &mainFunc);
128128
// map of the hashed location of quir angle/duration ops to their converted
129129
// pulse ops
130-
std::unordered_map<std::string, mlir::Value>
130+
std::unordered_map<Operation *, mlir::Value>
131131
classicalQUIROpLocToConvertedPulseOpMap;
132132

133133
// port name to Port_CreateOp map

include/Dialect/QUIR/Transforms/ExtractCircuits.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
#include "Utils/SymbolCacheAnalysis.h"
2626

2727
#include "mlir/IR/BuiltinAttributes.h"
28+
#include "mlir/IR/IRMapping.h"
2829
#include "mlir/IR/PatternMatch.h"
2930
#include "mlir/Pass/Pass.h"
3031

31-
#include "llvm/ADT/SmallVector.h"
32-
32+
#include <set>
3333
#include <unordered_map>
3434

3535
namespace mlir::quir {
@@ -49,14 +49,14 @@ struct ExtractCircuitsPass
4949
OpBuilder circuitBuilder);
5050
OpBuilder startCircuit(mlir::Location location, OpBuilder topLevelBuilder);
5151
void endCircuit(mlir::Operation *firstOp, mlir::Operation *lastOp,
52-
OpBuilder topLevelBuilder, OpBuilder circuitBuilder,
53-
llvm::SmallVector<Operation *> &eraseList);
54-
void addToCircuit(mlir::Operation *currentOp, OpBuilder circuitBuilder,
55-
llvm::SmallVector<Operation *> &eraseList);
52+
OpBuilder topLevelBuilder, OpBuilder circuitBuilder);
53+
void addToCircuit(mlir::Operation *currentOp, OpBuilder circuitBuilder);
54+
5655
uint64_t circuitCount = 0;
5756
qssc::utils::SymbolCacheAnalysis *symbolCache{nullptr};
5857

5958
mlir::quir::CircuitOp currentCircuitOp = nullptr;
59+
mlir::IRMapping currentCircuitMapper;
6060
mlir::quir::CallCircuitOp newCallCircuitOp;
6161

6262
llvm::SmallVector<Type> inputTypes;
@@ -68,6 +68,8 @@ struct ExtractCircuitsPass
6868

6969
std::unordered_map<Operation *, uint32_t> circuitOperands;
7070
llvm::SmallVector<OpResult> originalResults;
71+
std::set<Operation *> eraseConstSet;
72+
std::set<Operation *> eraseOpSet;
7173

7274
}; // struct ExtractCircuitsPass
7375
} // namespace mlir::quir

include/Frontend/OpenQASM3/QUIRGenQASM3Visitor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ class QUIRGenQASM3Visitor : public BaseQASM3Visitor {
321321
mlir::Type getQUIRTypeFromDeclaration(const QASM::ASTDeclarationNode *);
322322

323323
bool enableParametersWarningEmitted = false;
324+
325+
/// Cached dummy value for error handling
326+
mlir::Value voidValue;
324327
};
325328

326329
} // namespace qssc::frontend::openqasm3

include/Frontend/OpenQASM3/QUIRVariableBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class QUIRVariableBuilder {
6868

6969
mlir::Value generateParameterLoad(mlir::Location location,
7070
llvm::StringRef variableName,
71-
mlir::Value assignedValue);
71+
double initialValue);
7272

7373
/// Generate code for declaring an array (at the builder's current insertion
7474
/// point).

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void LoadPulseCalsPass::loadPulseCals(CallCircuitOp callCircuitOp,
152152
LLVM_DEBUG(llvm::dbgs() << "no pulse cal loading needed for " << op);
153153
assert((!op->hasTrait<mlir::quir::UnitaryOp>() and
154154
!op->hasTrait<mlir::quir::CPTPOp>()) &&
155-
"unkown operation");
155+
"unknown operation");
156156
}
157157
});
158158
}

lib/Conversion/QUIRToPulse/QUIRToPulse.cpp

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ void QUIRToPulsePass::runOnOperation() {
100100
moduleOp->walk([&](CallCircuitOp callCircOp) {
101101
if (isa<CircuitOp>(callCircOp->getParentOp()))
102102
return;
103+
103104
auto convertedPulseCallSequenceOp =
104105
convertCircuitToSequence(callCircOp, mainFunc, moduleOp);
106+
105107
if (!callCircOp->use_empty())
106108
callCircOp->replaceAllUsesWith(convertedPulseCallSequenceOp);
107109
callCircOp->erase();
@@ -229,8 +231,9 @@ QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp &callCircuitOp,
229231
auto *newDelayCyclesOp = builder.clone(*quirOp);
230232
newDelayCyclesOp->moveAfter(callCircuitOp);
231233
} else
232-
assert(((isa<quir::ConstantOp>(quirOp) or isa<quir::ReturnOp>(quirOp) or
233-
isa<quir::CircuitOp>(quirOp))) &&
234+
assert(((isa<quir::ConstantOp>(quirOp) ||
235+
isa<qcs::ParameterLoadOp>(quirOp) ||
236+
isa<quir::ReturnOp>(quirOp) || isa<quir::CircuitOp>(quirOp))) &&
234237
"quir op is not allowed in this pass.");
235238
});
236239

@@ -251,6 +254,7 @@ QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp &callCircuitOp,
251254
convertedPulseSequenceOp,
252255
convertedPulseSequenceOpArgs);
253256
convertedPulseCallSequenceOp->moveAfter(callCircuitOp);
257+
254258
return convertedPulseCallSequenceOp;
255259
}
256260

@@ -286,7 +290,7 @@ void QUIRToPulsePass::processCircuitArgs(
286290
} else if (argumentType.isa<mlir::quir::QubitType>()) {
287291
auto *qubitOp = callCircuitOp.getOperand(cnt).getDefiningOp();
288292
} else
289-
llvm_unreachable("unkown circuit argument.");
293+
llvm_unreachable("unknown circuit argument.");
290294
}
291295
}
292296

@@ -339,7 +343,7 @@ void QUIRToPulsePass::processPulseCalArgs(
339343
} else if (argumentType.isa<FloatType>()) {
340344
assert(argAttr[index].dyn_cast<StringAttr>().getValue().str() ==
341345
"angle" &&
342-
"unkown argument.");
346+
"unknown argument.");
343347
assert(angleOperands.size() && "no angle operand found.");
344348
auto nextAngle = angleOperands.front();
345349
LLVM_DEBUG(llvm::dbgs() << "angle argument ");
@@ -350,7 +354,7 @@ void QUIRToPulsePass::processPulseCalArgs(
350354
} else if (argumentType.isa<IntegerType>()) {
351355
assert(argAttr[index].dyn_cast<StringAttr>().getValue().str() ==
352356
"duration" &&
353-
"unkown argument.");
357+
"unknown argument.");
354358
assert(durationOperands.size() && "no duration operand found.");
355359
auto nextDuration = durationOperands.front();
356360
LLVM_DEBUG(llvm::dbgs() << "duration argument ");
@@ -359,7 +363,7 @@ void QUIRToPulsePass::processPulseCalArgs(
359363
pulseCalSequenceArgs, builder);
360364
durationOperands.pop();
361365
} else
362-
llvm_unreachable("unkown argument type.");
366+
llvm_unreachable("unknown argument type.");
363367
}
364368
}
365369

@@ -379,12 +383,13 @@ void QUIRToPulsePass::getQUIROpClassicalOperands(
379383
}
380384

381385
for (auto operand : classicalOperands)
382-
if (operand.getType().isa<mlir::quir::AngleType>())
386+
if (operand.getType().isa<mlir::quir::AngleType>() ||
387+
operand.getType().isa<FloatType>())
383388
angleOperands.push(operand);
384389
else if (operand.getType().isa<mlir::quir::DurationType>())
385390
durationOperands.push(operand);
386391
else
387-
llvm_unreachable("unkown operand.");
392+
llvm_unreachable("unknown operand.");
388393
}
389394

390395
void QUIRToPulsePass::processMixFrameOpArg(
@@ -463,21 +468,38 @@ void QUIRToPulsePass::processAngleArg(Value nextAngleOperand,
463468
pulseCalSequenceArgs.push_back(
464469
convertedPulseSequenceOp
465470
.getArguments()[circuitArgToConvertedSequenceArgMap[circNum]]);
466-
} else {
467-
auto angleOp = nextAngleOperand.getDefiningOp<mlir::quir::ConstantOp>();
468-
std::string const angleLocHash =
469-
std::to_string(mlir::hash_value(angleOp->getLoc()));
470-
if (classicalQUIROpLocToConvertedPulseOpMap.find(angleLocHash) ==
471+
} else if (auto angleOp =
472+
nextAngleOperand.getDefiningOp<mlir::quir::ConstantOp>()) {
473+
auto *op = angleOp.getOperation();
474+
if (classicalQUIROpLocToConvertedPulseOpMap.find(op) ==
471475
classicalQUIROpLocToConvertedPulseOpMap.end()) {
472476
double const angleVal =
473477
angleOp.getAngleValueFromConstant().convertToDouble();
474478
auto f64Angle = entryBuilder.create<mlir::arith::ConstantOp>(
475479
angleOp.getLoc(), entryBuilder.getFloatAttr(entryBuilder.getF64Type(),
476480
llvm::APFloat(angleVal)));
477-
classicalQUIROpLocToConvertedPulseOpMap[angleLocHash] = f64Angle;
481+
classicalQUIROpLocToConvertedPulseOpMap[op] = f64Angle;
478482
}
479-
pulseCalSequenceArgs.push_back(
480-
classicalQUIROpLocToConvertedPulseOpMap[angleLocHash]);
483+
pulseCalSequenceArgs.push_back(classicalQUIROpLocToConvertedPulseOpMap[op]);
484+
} else if (auto paramOp =
485+
nextAngleOperand.getDefiningOp<mlir::qcs::ParameterLoadOp>()) {
486+
auto *op = paramOp.getOperation();
487+
if (classicalQUIROpLocToConvertedPulseOpMap.find(op) ==
488+
classicalQUIROpLocToConvertedPulseOpMap.end()) {
489+
490+
auto newParam = entryBuilder.create<qcs::ParameterLoadOp>(
491+
paramOp->getLoc(), entryBuilder.getF64Type(),
492+
paramOp.getParameterName());
493+
if (paramOp->hasAttr("initialValue")) {
494+
auto initAttr = paramOp->getAttr("initialValue").dyn_cast<FloatAttr>();
495+
if (initAttr)
496+
newParam->setAttr("initialValue", initAttr);
497+
}
498+
499+
classicalQUIROpLocToConvertedPulseOpMap[op] = newParam;
500+
}
501+
502+
pulseCalSequenceArgs.push_back(classicalQUIROpLocToConvertedPulseOpMap[op]);
481503
}
482504
}
483505

@@ -501,25 +523,23 @@ void QUIRToPulsePass::processDurationArg(
501523
TimeUnits::dt &&
502524
"this pass only accepts durations with dt unit");
503525

504-
if (classicalQUIROpLocToConvertedPulseOpMap.find(durLocHash) ==
526+
auto *op = durationOp.getOperation();
527+
if (classicalQUIROpLocToConvertedPulseOpMap.find(op) ==
505528
classicalQUIROpLocToConvertedPulseOpMap.end()) {
506529
auto dur64 = entryBuilder.create<mlir::arith::ConstantOp>(
507530
durationOp.getLoc(),
508531
entryBuilder.getIntegerAttr(entryBuilder.getI64Type(),
509532
uint64_t(durVal)));
510-
classicalQUIROpLocToConvertedPulseOpMap[durLocHash] = dur64;
533+
classicalQUIROpLocToConvertedPulseOpMap[op] = dur64;
511534
}
512-
pulseCalSequenceArgs.push_back(
513-
classicalQUIROpLocToConvertedPulseOpMap[durLocHash]);
535+
pulseCalSequenceArgs.push_back(classicalQUIROpLocToConvertedPulseOpMap[op]);
514536
}
515537
}
516538

517539
mlir::Value QUIRToPulsePass::convertAngleToF64(Operation *angleOp,
518540
mlir::OpBuilder &builder) {
519541
assert(angleOp && "angle op is null");
520-
std::string const angleLocHash =
521-
std::to_string(mlir::hash_value(angleOp->getLoc()));
522-
if (classicalQUIROpLocToConvertedPulseOpMap.find(angleLocHash) ==
542+
if (classicalQUIROpLocToConvertedPulseOpMap.find(angleOp) ==
523543
classicalQUIROpLocToConvertedPulseOpMap.end()) {
524544
if (auto castOp = dyn_cast<quir::ConstantOp>(angleOp)) {
525545
double const angleVal =
@@ -528,41 +548,46 @@ mlir::Value QUIRToPulsePass::convertAngleToF64(Operation *angleOp,
528548
castOp->getLoc(),
529549
builder.getFloatAttr(builder.getF64Type(), llvm::APFloat(angleVal)));
530550
f64Angle->moveAfter(castOp);
531-
classicalQUIROpLocToConvertedPulseOpMap[angleLocHash] = f64Angle;
551+
classicalQUIROpLocToConvertedPulseOpMap[angleOp] = f64Angle;
532552
} else if (auto castOp = dyn_cast<qcs::ParameterLoadOp>(angleOp)) {
533-
auto angleCastedOp = builder.create<oq3::CastOp>(
534-
castOp->getLoc(), builder.getF64Type(), castOp.getRes());
535-
angleCastedOp->moveAfter(castOp);
536-
classicalQUIROpLocToConvertedPulseOpMap[angleLocHash] = angleCastedOp;
553+
// Just convert to an f64 directly
554+
auto newParam = builder.create<qcs::ParameterLoadOp>(
555+
angleOp->getLoc(), builder.getF64Type(), castOp.getParameterName());
556+
if (castOp->hasAttr("initialValue")) {
557+
auto initAttr = castOp->getAttr("initialValue").dyn_cast<FloatAttr>();
558+
if (initAttr)
559+
newParam->setAttr("initialValue", initAttr);
560+
}
561+
newParam->moveAfter(castOp);
562+
563+
classicalQUIROpLocToConvertedPulseOpMap[angleOp] = newParam;
537564
} else if (auto castOp = dyn_cast<oq3::CastOp>(angleOp)) {
538565
auto castOpArg = castOp.getArg();
539566
if (auto paramCastOp =
540567
dyn_cast<qcs::ParameterLoadOp>(castOpArg.getDefiningOp())) {
541568
auto angleCastedOp = builder.create<oq3::CastOp>(
542569
paramCastOp->getLoc(), builder.getF64Type(), paramCastOp.getRes());
543570
angleCastedOp->moveAfter(paramCastOp);
544-
classicalQUIROpLocToConvertedPulseOpMap[angleLocHash] = angleCastedOp;
571+
classicalQUIROpLocToConvertedPulseOpMap[angleOp] = angleCastedOp;
545572
} else if (auto constOp =
546573
dyn_cast<arith::ConstantOp>(castOpArg.getDefiningOp())) {
547574
// if cast from float64 then use directly
548575
assert(constOp.getType() == builder.getF64Type() &&
549576
"expected angle type to be float 64");
550-
classicalQUIROpLocToConvertedPulseOpMap[angleLocHash] = constOp;
577+
classicalQUIROpLocToConvertedPulseOpMap[angleOp] = constOp;
551578
} else
552579
llvm_unreachable("castOp arg unknown");
553580
} else
554581
llvm_unreachable("angleOp unknown");
555582
}
556-
return classicalQUIROpLocToConvertedPulseOpMap[angleLocHash];
583+
return classicalQUIROpLocToConvertedPulseOpMap[angleOp];
557584
}
558585

559586
mlir::Value QUIRToPulsePass::convertDurationToI64(
560587
mlir::quir::CallCircuitOp &callCircuitOp, Operation *durationOp, uint &cnt,
561588
mlir::OpBuilder &builder, mlir::func::FuncOp &mainFunc) {
562589
assert(durationOp && "duration op is null");
563-
std::string const durLocHash =
564-
std::to_string(mlir::hash_value(durationOp->getLoc()));
565-
if (classicalQUIROpLocToConvertedPulseOpMap.find(durLocHash) ==
590+
if (classicalQUIROpLocToConvertedPulseOpMap.find(durationOp) ==
566591
classicalQUIROpLocToConvertedPulseOpMap.end()) {
567592
if (auto castOp = dyn_cast<quir::ConstantOp>(durationOp)) {
568593
auto durVal =
@@ -575,11 +600,11 @@ mlir::Value QUIRToPulsePass::convertDurationToI64(
575600
castOp->getLoc(),
576601
builder.getIntegerAttr(builder.getI64Type(), uint64_t(durVal)));
577602
I64Dur->moveAfter(castOp);
578-
classicalQUIROpLocToConvertedPulseOpMap[durLocHash] = I64Dur;
603+
classicalQUIROpLocToConvertedPulseOpMap[durationOp] = I64Dur;
579604
} else
580-
llvm_unreachable("unkown duration op");
605+
llvm_unreachable("unknown duration op");
581606
}
582-
return classicalQUIROpLocToConvertedPulseOpMap[durLocHash];
607+
return classicalQUIROpLocToConvertedPulseOpMap[durationOp];
583608
}
584609

585610
mlir::pulse::Port_CreateOp

lib/Dialect/Pulse/IR/PulseOps.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "Dialect/Pulse/IR/PulseOps.h"
1818

1919
#include "Dialect/Pulse/IR/PulseTraits.h"
20+
#include "Dialect/QCS/IR/QCSOps.h"
2021
#include "Dialect/QUIR/IR/QUIROps.h"
2122

2223
#include "mlir/Dialect/Arith/IR/Arith.h"
@@ -356,8 +357,9 @@ LogicalResult verifyClassical_(SequenceOp op) {
356357
mlir::Operation *classicalOp = nullptr;
357358
WalkResult const result = op->walk([&](Operation *subOp) {
358359
if (isa<mlir::arith::ConstantOp>(subOp) || isa<quir::ConstantOp>(subOp) ||
359-
isa<CallSequenceOp>(subOp) || isa<pulse::ReturnOp>(subOp) ||
360-
isa<SequenceOp>(subOp) || isa<mlir::complex::CreateOp>(subOp) ||
360+
isa<qcs::ParameterLoadOp>(subOp) || isa<CallSequenceOp>(subOp) ||
361+
isa<pulse::ReturnOp>(subOp) || isa<SequenceOp>(subOp) ||
362+
isa<mlir::complex::CreateOp>(subOp) ||
361363
subOp->hasTrait<mlir::pulse::SequenceAllowed>() ||
362364
subOp->hasTrait<mlir::pulse::SequenceRequired>())
363365
return WalkResult::advance();

lib/Dialect/Pulse/Transforms/Scheduling.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ void QuantumCircuitPulseSchedulingPass::scheduleAlap(
112112
opEnd = quantumCircuitSequenceOpBlock->rend();
113113
opIt != opEnd; ++opIt) {
114114
auto &op = *opIt;
115+
115116
if (auto quantumGateCallSequenceOp =
116117
dyn_cast<mlir::pulse::CallSequenceOp>(op)) {
117118
// find quantum gate SequenceOp

lib/Dialect/QUIR/IR/QUIROps.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,9 @@ LogicalResult verifyClassical_(CircuitOp op) {
380380
mlir::Operation *classicalOp = nullptr;
381381
WalkResult const result = op->walk([&](Operation *subOp) {
382382
if (isa<mlir::arith::ConstantOp>(subOp) || isa<quir::ConstantOp>(subOp) ||
383-
isa<CallCircuitOp>(subOp) || isa<quir::ReturnOp>(subOp) ||
384-
isa<CircuitOp>(subOp) || subOp->hasTrait<mlir::quir::UnitaryOp>() ||
383+
isa<qcs::ParameterLoadOp>(subOp) || isa<CallCircuitOp>(subOp) ||
384+
isa<quir::ReturnOp>(subOp) || isa<CircuitOp>(subOp) ||
385+
subOp->hasTrait<mlir::quir::UnitaryOp>() ||
385386
subOp->hasTrait<mlir::quir::CPTPOp>())
386387
return WalkResult::advance();
387388
classicalOp = subOp;

0 commit comments

Comments
 (0)