MLIR Passes v1.0
Loading...
Searching...
No Matches
CommutateOperations.hpp
Go to the documentation of this file.
1/* This code and any associated documentation is provided "as is"
2
3Copyright 2025 Munich Quantum Software Stack Project
4
5Licensed under the Apache License, Version 2.0 with LLVM Exceptions (the
6"License"); you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9https://github.com/Munich-Quantum-Software-Stack/passes/blob/develop/LICENSE
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14License for the specific language governing permissions and limitations under
15the License.
16
17SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
18*******************************************************************************
19 author Martin Letras
20 date February 2025
21 version 1.0
22*******************************************************************************
23* This source code and the accompanying materials are made available under *
24* the terms of the Apache License 2.0 which accompanies this distribution. *
25******************************************************************************/
35#pragma once
36
38#include "cudaq/Optimizer/Dialect/Quake/QuakeDialect.h"
39#include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h"
40#include "mlir/Dialect/SCF/IR/SCF.h"
41#include "mlir/Rewrite/FrozenRewritePatternSet.h"
42#include "mlir/Transforms/DialectConversion.h"
43
44#include "llvm/Support/Casting.h"
45#include "llvm/Support/raw_ostream.h"
46
47using namespace mlir;
48using namespace mqss::support::quakeDialect;
49
50namespace mqss::support::transforms {
68template <typename T1, typename T2>
69void commuteOperation(mlir::Operation *currentOp, int nCtrlsOp1, int nTgtsOp1,
70 int nCtrlsOp2, int nTgtsOp2) {
71 auto currentGate = dyn_cast_or_null<T2>(*currentOp);
72 if (!currentGate)
73 return;
74 // check that the current gate is compliant with the number of controls and
75 // targets
76 if (currentGate.getControls().size() != nCtrlsOp2 ||
77 currentGate.getTargets().size() != nTgtsOp2)
78 return;
79 // get the previous operation to check the swap pattern
80 auto prevOp =
81 getPreviousOperationOnTarget(currentGate, currentGate.getTargets()[0]);
82 if (!prevOp)
83 return;
84 auto previousGate = dyn_cast_or_null<T1>(prevOp);
85 if (!previousGate)
86 return;
87 // check that the previous gate is compliant with the number of controls and
88 // targets
89 if (previousGate.getControls().size() != nCtrlsOp1 ||
90 previousGate.getTargets().size() != nTgtsOp1)
91 return; // check both targets are the same
92 int targetPrev = extractIndexFromQuakeExtractRefOp(
93 previousGate.getTargets()[0].getDefiningOp());
94 int targetCurr = extractIndexFromQuakeExtractRefOp(
95 currentGate.getTargets()[0].getDefiningOp());
96 if (targetPrev != targetCurr)
97 return;
98#ifdef DEBUG
99 llvm::outs() << "Current Operation: ";
100 currentGate->print(llvm::outs());
101 llvm::outs() << "\n";
102 llvm::outs() << "Previous Operation: ";
103 previousGate->print(llvm::outs());
104 llvm::outs() << "\n";
105#endif
106 // At this point, I should de able to do the commutation
107 // Swap the two operations by cloning them in reverse order.
108 mlir::IRRewriter rewriter(currentGate->getContext());
109 rewriter.setInsertionPointAfter(currentGate);
110 auto newGate = rewriter.create<T1>(
111 previousGate.getLoc(), previousGate.isAdj(), previousGate.getParameters(),
112 previousGate.getControls(), previousGate.getTargets());
113 rewriter.setInsertionPoint(newGate);
114 rewriter.create<T2>(currentGate.getLoc(), currentGate.isAdj(),
115 currentGate.getParameters(), currentGate.getControls(),
116 currentGate.getTargets());
117 // Erase the original operations
118 rewriter.eraseOp(currentGate);
119 rewriter.eraseOp(previousGate);
120}
121} // namespace mqss::support::transforms
void commuteOperation(mlir::Operation *currentOp, int nCtrlsOp1, int nTgtsOp1, int nCtrlsOp2, int nTgtsOp2)
Commutes two quantum operations if they match a specific pattern.
Definition CommutateOperations.hpp:69
mlir::Operation * getPreviousOperationOnTarget(mlir::Operation *currentOp, mlir::Value targetQubit)
Function get the previous operation on a given target qubit.
int64_t extractIndexFromQuakeExtractRefOp(Operation *op)
Function that extracts an index of a given ExtractRefOp operation.