diff --git a/doc/releases/changelog-0.14.0.md b/doc/releases/changelog-0.14.0.md index a344c0af85..384a8483c8 100644 --- a/doc/releases/changelog-0.14.0.md +++ b/doc/releases/changelog-0.14.0.md @@ -650,6 +650,9 @@ * Adding the measurement type into the MLIR assembly format for `qec.ppm` and `qec.select.ppm` [(#2347)](https://github.com/PennyLaneAI/catalyst/pull/2347) +* Remove duplicate code for canonicalization and verification of Pauli Product Rotation operations. + [(#2313)](https://github.com/PennyLaneAI/catalyst/pull/2313) +

Documentation 📝

* A new statevector simulator ``lightning.amdgpu`` has been added for optimized performance on AMD GPUs. diff --git a/mlir/lib/QEC/IR/QECOps.cpp b/mlir/lib/QEC/IR/QECOps.cpp index 691e05f7f1..d3c1383e8a 100644 --- a/mlir/lib/QEC/IR/QECOps.cpp +++ b/mlir/lib/QEC/IR/QECOps.cpp @@ -35,37 +35,45 @@ using namespace catalyst::qec; #include "QEC/IR/QECOps.cpp.inc" //===----------------------------------------------------------------------===// -// QEC op verifiers. +// QEC op canonicalizers/verifiers helper methods. //===----------------------------------------------------------------------===// -LogicalResult PPRotationOp::verify() +template LogicalResult canonicalizePPROp(OpType op, PatternRewriter &rewriter) { - size_t numPauliProduct = getPauliProduct().size(); - - if (numPauliProduct == 0) { - return emitOpError("Pauli string must be non-empty"); - } + bool allIdentity = llvm::all_of(op.getPauliProduct(), [](mlir::Attribute attr) { + auto pauliStr = llvm::cast(attr); + return pauliStr.getValue() == "I"; + }); - if (numPauliProduct != getInQubits().size()) { - return emitOpError("Number of qubits must match number of pauli operators"); + if (allIdentity) { + rewriter.replaceOp(op, op.getInQubits()); + return mlir::success(); } - return mlir::success(); + return mlir::failure(); } -LogicalResult PPRotationArbitraryOp::verify() +template LogicalResult verifyPPROp(OpType op) { - size_t numPauliProduct = getPauliProduct().size(); + size_t numPauliProduct = op.getPauliProduct().size(); if (numPauliProduct == 0) { - return emitOpError("Pauli string must be non-empty"); + return op.emitOpError("Pauli string must be non-empty"); } - if (numPauliProduct != getInQubits().size()) { - return emitOpError("Number of qubits must match number of pauli operators"); + if (numPauliProduct != op.getInQubits().size()) { + return op.emitOpError("Number of qubits must match number of pauli operators"); } return mlir::success(); } +//===----------------------------------------------------------------------===// +// QEC op verifiers. +//===----------------------------------------------------------------------===// + +LogicalResult PPRotationOp::verify() { return verifyPPROp(*this); } + +LogicalResult PPRotationArbitraryOp::verify() { return verifyPPROp(*this); } + LogicalResult PPMeasurementOp::verify() { if (getInQubits().size() != getPauliProduct().size()) { @@ -105,35 +113,13 @@ LogicalResult FabricateOp::verify() LogicalResult PPRotationOp::canonicalize(PPRotationOp op, PatternRewriter &rewriter) { - auto pauliProduct = op.getPauliProduct(); - - bool allIdentity = llvm::all_of(pauliProduct, [](mlir::Attribute attr) { - auto pauliStr = llvm::cast(attr); - return pauliStr.getValue() == "I"; - }); - - if (allIdentity) { - rewriter.replaceOp(op, op.getInQubits()); - return mlir::success(); - } - return mlir::failure(); + return canonicalizePPROp(op, rewriter); } LogicalResult PPRotationArbitraryOp::canonicalize(PPRotationArbitraryOp op, PatternRewriter &rewriter) { - auto pauliProduct = op.getPauliProduct(); - - bool allIdentity = llvm::all_of(pauliProduct, [](mlir::Attribute attr) { - auto pauliStr = llvm::cast(attr); - return pauliStr.getValue() == "I"; - }); - - if (allIdentity) { - rewriter.replaceOp(op, op.getInQubits()); - return mlir::success(); - } - return mlir::failure(); + return canonicalizePPROp(op, rewriter); } void LayerOp::build(OpBuilder &builder, OperationState &result, ValueRange inValues,