diff --git a/CHANGELOG.md b/CHANGELOG.md index 5519b06b6..4609b4da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel ### Added -- ✨ Add initial infrastructure for new QC and QCO MLIR dialects ([#1264]) ([**@burgholzer**], [**@denialhaag**]) +- ✨ Add initial infrastructure for new QC and QCO MLIR dialects ([#1264], [#1402]) ([**@burgholzer**], [**@denialhaag**]) - ✨ Return device handle from `add_dynamic_device_library` for direct backend creation ([#1381]) ([**@marcelwa**]) - ✨ Add IQM JSON support for job submission in Qiskit-QDMI Backend ([#1375], [#1382]) ([**@marcelwa**], [**@burgholzer**]) - ✨ Add authentication support for QDMI sessions with token, username/password, auth file, auth URL, and project ID parameters ([#1355]) ([**@marcelwa**]) @@ -286,6 +286,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool +[#1402]: https://github.com/munich-quantum-toolkit/core/pull/1402 [#1385]: https://github.com/munich-quantum-toolkit/core/pull/1385 [#1384]: https://github.com/munich-quantum-toolkit/core/pull/1384 [#1383]: https://github.com/munich-quantum-toolkit/core/pull/1383 diff --git a/mlir/include/mlir/Dialect/QC/Builder/QCProgramBuilder.h b/mlir/include/mlir/Dialect/QC/Builder/QCProgramBuilder.h index 288740561..918e33d1f 100644 --- a/mlir/include/mlir/Dialect/QC/Builder/QCProgramBuilder.h +++ b/mlir/include/mlir/Dialect/QC/Builder/QCProgramBuilder.h @@ -833,7 +833,7 @@ class QCProgramBuilder final : public OpBuilder { * * @par Example: * ```c++ - * builder.ctrl(q0, [&](auto& b) { b.x(q1); }); + * builder.ctrl(q0, [&] { builder.x(q1); }); * ``` * ```mlir * qc.ctrl(%q0) { @@ -842,7 +842,7 @@ class QCProgramBuilder final : public OpBuilder { * ``` */ QCProgramBuilder& ctrl(ValueRange controls, - const std::function& body); + const std::function& body); //===--------------------------------------------------------------------===// // Deallocation diff --git a/mlir/include/mlir/Dialect/QC/IR/QCOps.td b/mlir/include/mlir/Dialect/QC/IR/QCOps.td index 7ed127dbf..62fd7059f 100644 --- a/mlir/include/mlir/Dialect/QC/IR/QCOps.td +++ b/mlir/include/mlir/Dialect/QC/IR/QCOps.td @@ -966,7 +966,7 @@ def CtrlOp : QCOp<"ctrl", let builders = [ OpBuilder<(ins "ValueRange":$controls, "UnitaryOpInterface":$bodyUnitary)>, - OpBuilder<(ins "ValueRange":$controls, "const std::function&":$bodyBuilder)> + OpBuilder<(ins "ValueRange":$controls, "const std::function&":$bodyBuilder)> ]; let hasCanonicalizer = 1; diff --git a/mlir/include/mlir/Dialect/QCO/Builder/QCOProgramBuilder.h b/mlir/include/mlir/Dialect/QCO/Builder/QCOProgramBuilder.h index cd5f4ae89..04cff8cc3 100644 --- a/mlir/include/mlir/Dialect/QCO/Builder/QCOProgramBuilder.h +++ b/mlir/include/mlir/Dialect/QCO/Builder/QCOProgramBuilder.h @@ -987,10 +987,11 @@ class QCOProgramBuilder final : public OpBuilder { * * @par Example: * ```c++ - * {controls_out, targets_out} = builder.ctrl(q0_in, q1_in, [&](auto& b) { - * auto q1_res = b.x(q1_in); - * return {q1_res}; - * }); + * {controls_out, targets_out} = + * builder.ctrl(q0_in, q1_in, [&](ValueRange targets) { + * auto q1_res = builder.x(targets[0]); + * return {q1_res}; + * }); * ``` * ```mlir * %controls_out, %targets_out = qco.ctrl(%q0_in) %q1_in { @@ -1001,7 +1002,7 @@ class QCOProgramBuilder final : public OpBuilder { */ std::pair ctrl(ValueRange controls, ValueRange targets, - const std::function& body); + const std::function& body); //===--------------------------------------------------------------------===// // Deallocation diff --git a/mlir/include/mlir/Dialect/QCO/IR/QCOOps.td b/mlir/include/mlir/Dialect/QCO/IR/QCOOps.td index 69f89eb5e..1dea491ab 100644 --- a/mlir/include/mlir/Dialect/QCO/IR/QCOOps.td +++ b/mlir/include/mlir/Dialect/QCO/IR/QCOOps.td @@ -1099,7 +1099,7 @@ def CtrlOp : QCOOp<"ctrl", traits = build($_builder, $_state, controls.getTypes(), targets.getTypes(), controls, targets); }]>, OpBuilder<(ins "ValueRange":$controls, "ValueRange":$targets, "UnitaryOpInterface":$bodyUnitary)>, - OpBuilder<(ins "ValueRange":$controls, "ValueRange":$targets, "const std::function&":$bodyBuilder)> + OpBuilder<(ins "ValueRange":$controls, "ValueRange":$targets, "const std::function&":$bodyBuilder)> ]; let hasCanonicalizer = 1; diff --git a/mlir/lib/Dialect/QC/Builder/QCProgramBuilder.cpp b/mlir/lib/Dialect/QC/Builder/QCProgramBuilder.cpp index f9139835f..470a5af4d 100644 --- a/mlir/lib/Dialect/QC/Builder/QCProgramBuilder.cpp +++ b/mlir/lib/Dialect/QC/Builder/QCProgramBuilder.cpp @@ -166,7 +166,7 @@ QCProgramBuilder& QCProgramBuilder::reset(Value qubit) { const std::variant&(PARAM), ValueRange controls) { \ checkFinalized(); \ CtrlOp::create(*this, loc, controls, \ - [&](OpBuilder& b) { OP_CLASS::create(b, loc, PARAM); }); \ + [&] { OP_CLASS::create(*this, loc, PARAM); }); \ return *this; \ } @@ -191,7 +191,7 @@ DEFINE_ZERO_TARGET_ONE_PARAMETER(GPhaseOp, gphase, theta) Value target) { \ checkFinalized(); \ CtrlOp::create(*this, loc, controls, \ - [&](OpBuilder& b) { OP_CLASS::create(b, loc, target); }); \ + [&] { OP_CLASS::create(*this, loc, target); }); \ return *this; \ } @@ -228,9 +228,8 @@ DEFINE_ONE_TARGET_ZERO_PARAMETER(SXdgOp, sxdg) const std::variant&(PARAM), ValueRange controls, \ Value target) { \ checkFinalized(); \ - CtrlOp::create(*this, loc, controls, [&](OpBuilder& b) { \ - OP_CLASS::create(b, loc, target, PARAM); \ - }); \ + CtrlOp::create(*this, loc, controls, \ + [&] { OP_CLASS::create(*this, loc, target, PARAM); }); \ return *this; \ } @@ -263,8 +262,8 @@ DEFINE_ONE_TARGET_ONE_PARAMETER(POp, p, theta) const std::variant&(PARAM2), ValueRange controls, \ Value target) { \ checkFinalized(); \ - CtrlOp::create(*this, loc, controls, [&](OpBuilder& b) { \ - OP_CLASS::create(b, loc, target, PARAM1, PARAM2); \ + CtrlOp::create(*this, loc, controls, [&] { \ + OP_CLASS::create(*this, loc, target, PARAM1, PARAM2); \ }); \ return *this; \ } @@ -300,8 +299,8 @@ DEFINE_ONE_TARGET_TWO_PARAMETER(U2Op, u2, phi, lambda) const std::variant&(PARAM3), ValueRange controls, \ Value target) { \ checkFinalized(); \ - CtrlOp::create(*this, loc, controls, [&](OpBuilder& b) { \ - OP_CLASS::create(b, loc, target, PARAM1, PARAM2, PARAM3); \ + CtrlOp::create(*this, loc, controls, [&] { \ + OP_CLASS::create(*this, loc, target, PARAM1, PARAM2, PARAM3); \ }); \ return *this; \ } @@ -326,9 +325,8 @@ DEFINE_ONE_TARGET_THREE_PARAMETER(UOp, u, theta, phi, lambda) QCProgramBuilder& QCProgramBuilder::mc##OP_NAME( \ ValueRange controls, Value qubit0, Value qubit1) { \ checkFinalized(); \ - CtrlOp::create(*this, loc, controls, [&](OpBuilder& b) { \ - OP_CLASS::create(b, loc, qubit0, qubit1); \ - }); \ + CtrlOp::create(*this, loc, controls, \ + [&] { OP_CLASS::create(*this, loc, qubit0, qubit1); }); \ return *this; \ } @@ -358,8 +356,8 @@ DEFINE_TWO_TARGET_ZERO_PARAMETER(ECROp, ecr) const std::variant&(PARAM), ValueRange controls, \ Value qubit0, Value qubit1) { \ checkFinalized(); \ - CtrlOp::create(*this, loc, controls, [&](OpBuilder& b) { \ - OP_CLASS::create(b, loc, qubit0, qubit1, PARAM); \ + CtrlOp::create(*this, loc, controls, [&] { \ + OP_CLASS::create(*this, loc, qubit0, qubit1, PARAM); \ }); \ return *this; \ } @@ -394,8 +392,8 @@ DEFINE_TWO_TARGET_ONE_PARAMETER(RZZOp, rzz, theta) const std::variant&(PARAM2), ValueRange controls, \ Value qubit0, Value qubit1) { \ checkFinalized(); \ - CtrlOp::create(*this, loc, controls, [&](OpBuilder& b) { \ - OP_CLASS::create(b, loc, qubit0, qubit1, PARAM1, PARAM2); \ + CtrlOp::create(*this, loc, controls, [&] { \ + OP_CLASS::create(*this, loc, qubit0, qubit1, PARAM1, PARAM2); \ }); \ return *this; \ } @@ -417,9 +415,8 @@ QCProgramBuilder& QCProgramBuilder::barrier(ValueRange qubits) { // Modifiers //===----------------------------------------------------------------------===// -QCProgramBuilder& -QCProgramBuilder::ctrl(ValueRange controls, - const std::function& body) { +QCProgramBuilder& QCProgramBuilder::ctrl(ValueRange controls, + const std::function& body) { checkFinalized(); CtrlOp::create(*this, loc, controls, body); return *this; diff --git a/mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp b/mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp index 8651cbb12..66ea97275 100644 --- a/mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp +++ b/mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp @@ -97,8 +97,8 @@ struct CtrlInlineGPhase final : OpRewritePattern { SmallVector newControls(op.getControls()); const auto newTarget = newControls.back(); newControls.pop_back(); - CtrlOp::create(rewriter, op.getLoc(), newControls, [&](OpBuilder& b) { - POp::create(b, op.getLoc(), newTarget, gPhaseOp.getTheta()); + CtrlOp::create(rewriter, op.getLoc(), newControls, [&] { + POp::create(rewriter, op.getLoc(), newTarget, gPhaseOp.getTheta()); }); rewriter.eraseOp(op); @@ -161,14 +161,14 @@ void CtrlOp::build(OpBuilder& odsBuilder, OperationState& odsState, void CtrlOp::build(OpBuilder& odsBuilder, OperationState& odsState, ValueRange controls, - const std::function& bodyBuilder) { + const std::function& bodyBuilder) { const OpBuilder::InsertionGuard guard(odsBuilder); odsState.addOperands(controls); auto* region = odsState.addRegion(); auto& block = region->emplaceBlock(); odsBuilder.setInsertionPointToStart(&block); - bodyBuilder(odsBuilder); + bodyBuilder(); odsBuilder.create(odsState.location); } diff --git a/mlir/lib/Dialect/QCO/Builder/QCOProgramBuilder.cpp b/mlir/lib/Dialect/QCO/Builder/QCOProgramBuilder.cpp index a3fa2123b..43a3694f3 100644 --- a/mlir/lib/Dialect/QCO/Builder/QCOProgramBuilder.cpp +++ b/mlir/lib/Dialect/QCO/Builder/QCOProgramBuilder.cpp @@ -209,24 +209,20 @@ Value QCOProgramBuilder::reset(Value qubit) { const std::variant&(PARAM), Value control) { \ checkFinalized(); \ const auto controlsOut = \ - ctrl(control, {}, \ - [&](OpBuilder& b, ValueRange /*targets*/) -> ValueRange { \ - OP_CLASS::create(b, loc, PARAM); \ - return {}; \ - }) \ - .first; \ + ctrl(control, {}, [&](ValueRange /*targets*/) -> ValueRange { \ + OP_CLASS::create(*this, loc, PARAM); \ + return {}; \ + }).first; \ return controlsOut[0]; \ } \ ValueRange QCOProgramBuilder::mc##OP_NAME( \ const std::variant&(PARAM), ValueRange controls) { \ checkFinalized(); \ const auto controlsOut = \ - ctrl(controls, {}, \ - [&](OpBuilder& b, ValueRange /*targets*/) -> ValueRange { \ - OP_CLASS::create(b, loc, PARAM); \ - return {}; \ - }) \ - .first; \ + ctrl(controls, {}, [&](ValueRange /*targets*/) -> ValueRange { \ + OP_CLASS::create(*this, loc, PARAM); \ + return {}; \ + }).first; \ return controlsOut; \ } @@ -247,9 +243,9 @@ DEFINE_ZERO_TARGET_ONE_PARAMETER(GPhaseOp, gphase, theta) std::pair QCOProgramBuilder::c##OP_NAME(Value control, \ Value target) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = ctrl( \ - control, target, [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0]); \ + const auto [controlsOut, targetsOut] = \ + ctrl(control, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0]); \ return op->getResults(); \ }); \ return {controlsOut[0], targetsOut[0]}; \ @@ -258,11 +254,10 @@ DEFINE_ZERO_TARGET_ONE_PARAMETER(GPhaseOp, gphase, theta) ValueRange controls, Value target) { \ checkFinalized(); \ const auto [controlsOut, targetsOut] = \ - ctrl(controls, target, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0]); \ - return op->getResults(); \ - }); \ + ctrl(controls, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0]); \ + return op->getResults(); \ + }); \ return {controlsOut, targetsOut[0]}; \ } @@ -295,9 +290,9 @@ DEFINE_ONE_TARGET_ZERO_PARAMETER(SXdgOp, sxdg) const std::variant&(PARAM), Value control, \ Value target) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = ctrl( \ - control, target, [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0], PARAM); \ + const auto [controlsOut, targetsOut] = \ + ctrl(control, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0], PARAM); \ return op->getResults(); \ }); \ return {controlsOut[0], targetsOut[0]}; \ @@ -307,11 +302,10 @@ DEFINE_ONE_TARGET_ZERO_PARAMETER(SXdgOp, sxdg) Value target) { \ checkFinalized(); \ const auto [controlsOut, targetsOut] = \ - ctrl(controls, target, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0], PARAM); \ - return op->getResults(); \ - }); \ + ctrl(controls, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0], PARAM); \ + return op->getResults(); \ + }); \ return {controlsOut, targetsOut[0]}; \ } @@ -339,10 +333,10 @@ DEFINE_ONE_TARGET_ONE_PARAMETER(POp, p, phi) const std::variant&(PARAM2), Value control, \ Value target) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = ctrl( \ - control, target, [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ + const auto [controlsOut, targetsOut] = \ + ctrl(control, target, [&](ValueRange targets) -> ValueRange { \ const auto op = \ - OP_CLASS::create(b, loc, targets[0], PARAM1, PARAM2); \ + OP_CLASS::create(*this, loc, targets[0], PARAM1, PARAM2); \ return op->getResults(); \ }); \ return {controlsOut[0], targetsOut[0]}; \ @@ -353,12 +347,11 @@ DEFINE_ONE_TARGET_ONE_PARAMETER(POp, p, phi) Value target) { \ checkFinalized(); \ const auto [controlsOut, targetsOut] = \ - ctrl(controls, target, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = \ - OP_CLASS::create(b, loc, targets[0], PARAM1, PARAM2); \ - return op->getResults(); \ - }); \ + ctrl(controls, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = \ + OP_CLASS::create(*this, loc, targets[0], PARAM1, PARAM2); \ + return op->getResults(); \ + }); \ return {controlsOut, targetsOut[0]}; \ } @@ -387,10 +380,10 @@ DEFINE_ONE_TARGET_TWO_PARAMETER(U2Op, u2, phi, lambda) const std::variant&(PARAM3), Value control, \ Value target) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = ctrl( \ - control, target, [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = \ - OP_CLASS::create(b, loc, targets[0], PARAM1, PARAM2, PARAM3); \ + const auto [controlsOut, targetsOut] = \ + ctrl(control, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0], PARAM1, \ + PARAM2, PARAM3); \ return op->getResults(); \ }); \ return {controlsOut[0], targetsOut[0]}; \ @@ -402,12 +395,11 @@ DEFINE_ONE_TARGET_TWO_PARAMETER(U2Op, u2, phi, lambda) Value target) { \ checkFinalized(); \ const auto [controlsOut, targetsOut] = \ - ctrl(controls, target, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0], PARAM1, \ - PARAM2, PARAM3); \ - return op->getResults(); \ - }); \ + ctrl(controls, target, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0], PARAM1, \ + PARAM2, PARAM3); \ + return op->getResults(); \ + }); \ return {controlsOut, targetsOut[0]}; \ } @@ -431,26 +423,24 @@ DEFINE_ONE_TARGET_THREE_PARAMETER(UOp, u, theta, phi, lambda) std::pair> QCOProgramBuilder::c##OP_NAME( \ Value control, Value qubit0, Value qubit1) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = \ - ctrl(control, {qubit0, qubit1}, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = \ - OP_CLASS::create(b, loc, targets[0], targets[1]); \ - return op->getResults(); \ - }); \ + const auto [controlsOut, targetsOut] = ctrl( \ + control, {qubit0, qubit1}, [&](ValueRange targets) -> ValueRange { \ + const auto op = \ + OP_CLASS::create(*this, loc, targets[0], targets[1]); \ + return op->getResults(); \ + }); \ return {controlsOut[0], {targetsOut[0], targetsOut[1]}}; \ } \ std::pair> \ QCOProgramBuilder::mc##OP_NAME(ValueRange controls, Value qubit0, \ Value qubit1) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = \ - ctrl(controls, {qubit0, qubit1}, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = \ - OP_CLASS::create(b, loc, targets[0], targets[1]); \ - return op->getResults(); \ - }); \ + const auto [controlsOut, targetsOut] = ctrl( \ + controls, {qubit0, qubit1}, [&](ValueRange targets) -> ValueRange { \ + const auto op = \ + OP_CLASS::create(*this, loc, targets[0], targets[1]); \ + return op->getResults(); \ + }); \ return {controlsOut, {targetsOut[0], targetsOut[1]}}; \ } @@ -478,13 +468,12 @@ DEFINE_TWO_TARGET_ZERO_PARAMETER(ECROp, ecr) const std::variant&(PARAM), Value control, Value qubit0, \ Value qubit1) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = \ - ctrl(control, {qubit0, qubit1}, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = \ - OP_CLASS::create(b, loc, targets[0], targets[1], PARAM); \ - return op->getResults(); \ - }); \ + const auto [controlsOut, targetsOut] = ctrl( \ + control, {qubit0, qubit1}, [&](ValueRange targets) -> ValueRange { \ + const auto op = \ + OP_CLASS::create(*this, loc, targets[0], targets[1], PARAM); \ + return op->getResults(); \ + }); \ return {controlsOut[0], {targetsOut[0], targetsOut[1]}}; \ } \ std::pair> \ @@ -492,13 +481,12 @@ DEFINE_TWO_TARGET_ZERO_PARAMETER(ECROp, ecr) const std::variant&(PARAM), ValueRange controls, \ Value qubit0, Value qubit1) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = \ - ctrl(controls, {qubit0, qubit1}, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = \ - OP_CLASS::create(b, loc, targets[0], targets[1], PARAM); \ - return op->getResults(); \ - }); \ + const auto [controlsOut, targetsOut] = ctrl( \ + controls, {qubit0, qubit1}, [&](ValueRange targets) -> ValueRange { \ + const auto op = \ + OP_CLASS::create(*this, loc, targets[0], targets[1], PARAM); \ + return op->getResults(); \ + }); \ return {controlsOut, {targetsOut[0], targetsOut[1]}}; \ } @@ -529,13 +517,12 @@ DEFINE_TWO_TARGET_ONE_PARAMETER(RZZOp, rzz, theta) const std::variant&(PARAM2), Value control, Value qubit0, \ Value qubit1) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = \ - ctrl(control, {qubit0, qubit1}, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0], \ - targets[1], PARAM1, PARAM2); \ - return op->getResults(); \ - }); \ + const auto [controlsOut, targetsOut] = ctrl( \ + control, {qubit0, qubit1}, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0], targets[1], \ + PARAM1, PARAM2); \ + return op->getResults(); \ + }); \ return {controlsOut[0], {targetsOut[0], targetsOut[1]}}; \ } \ std::pair> \ @@ -544,13 +531,12 @@ DEFINE_TWO_TARGET_ONE_PARAMETER(RZZOp, rzz, theta) const std::variant&(PARAM2), ValueRange controls, \ Value qubit0, Value qubit1) { \ checkFinalized(); \ - const auto [controlsOut, targetsOut] = \ - ctrl(controls, {qubit0, qubit1}, \ - [&](OpBuilder& b, ValueRange targets) -> ValueRange { \ - const auto op = OP_CLASS::create(b, loc, targets[0], \ - targets[1], PARAM1, PARAM2); \ - return op->getResults(); \ - }); \ + const auto [controlsOut, targetsOut] = ctrl( \ + controls, {qubit0, qubit1}, [&](ValueRange targets) -> ValueRange { \ + const auto op = OP_CLASS::create(*this, loc, targets[0], targets[1], \ + PARAM1, PARAM2); \ + return op->getResults(); \ + }); \ return {controlsOut, {targetsOut[0], targetsOut[1]}}; \ } @@ -576,9 +562,9 @@ ValueRange QCOProgramBuilder::barrier(ValueRange qubits) { // Modifiers //===----------------------------------------------------------------------===// -std::pair QCOProgramBuilder::ctrl( - ValueRange controls, ValueRange targets, - const std::function& body) { +std::pair +QCOProgramBuilder::ctrl(ValueRange controls, ValueRange targets, + const std::function& body) { checkFinalized(); auto ctrlOp = CtrlOp::create(*this, loc, controls, targets, body); diff --git a/mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp b/mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp index 44a40bd64..0a4b87342 100644 --- a/mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp +++ b/mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp @@ -106,13 +106,12 @@ struct CtrlInlineGPhase final : OpRewritePattern { SmallVector newControls(op.getControlsIn()); const auto newTarget = newControls.back(); newControls.pop_back(); - auto ctrlOp = CtrlOp::create(rewriter, op.getLoc(), newControls, newTarget, - [&](OpBuilder& b, ValueRange targets) { - auto pOp = - POp::create(b, op.getLoc(), targets[0], - gPhaseOp.getTheta()); - return pOp.getQubitOut(); - }); + auto ctrlOp = CtrlOp::create( + rewriter, op.getLoc(), newControls, newTarget, [&](ValueRange targets) { + auto pOp = POp::create(rewriter, op.getLoc(), targets[0], + gPhaseOp.getTheta()); + return pOp.getQubitOut(); + }); rewriter.replaceOp(op, ctrlOp.getResults()); @@ -259,17 +258,16 @@ void CtrlOp::build(OpBuilder& odsBuilder, OperationState& odsState, odsBuilder.create(odsState.location, op->getResults()); } -void CtrlOp::build( - OpBuilder& odsBuilder, OperationState& odsState, ValueRange controls, - ValueRange targets, - const std::function& bodyBuilder) { +void CtrlOp::build(OpBuilder& odsBuilder, OperationState& odsState, + ValueRange controls, ValueRange targets, + const std::function& bodyBuilder) { build(odsBuilder, odsState, controls, targets); auto& block = odsState.regions.front()->emplaceBlock(); // Move the unitary op into the block const OpBuilder::InsertionGuard guard(odsBuilder); odsBuilder.setInsertionPointToStart(&block); - auto targetsOut = bodyBuilder(odsBuilder, targets); + auto targetsOut = bodyBuilder(targets); odsBuilder.create(odsState.location, targetsOut); } diff --git a/mlir/unittests/pipeline/test_compiler_pipeline.cpp b/mlir/unittests/pipeline/test_compiler_pipeline.cpp index 70c32a10c..2b0f1854f 100644 --- a/mlir/unittests/pipeline/test_compiler_pipeline.cpp +++ b/mlir/unittests/pipeline/test_compiler_pipeline.cpp @@ -1583,10 +1583,7 @@ TEST_F(CompilerPipelineTest, MCX) { TEST_F(CompilerPipelineTest, MCXNested) { auto input = buildQCIR([](mlir::qc::QCProgramBuilder& b) { auto reg = b.allocQubitRegister(3, "q"); - b.ctrl(reg[0], [&](OpBuilder& b) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) - static_cast(b).cx(reg[1], reg[2]); - }); + b.ctrl(reg[0], [&] { b.cx(reg[1], reg[2]); }); }); ASSERT_TRUE(runPipeline(input.get()).succeeded());