Skip to content

Commit 0ff678b

Browse files
committed
migrate pass & solver to ID
1 parent ce8ab1d commit 0ff678b

10 files changed

Lines changed: 143 additions & 280 deletions

File tree

doc/releases/changelog-dev.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@
313313
[(#2983)](https://github.com/PennyLaneAI/catalyst/pull/2983)
314314
[(#3022)](https://github.com/PennyLaneAI/catalyst/pull/3022)
315315
[(#3039)](https://github.com/PennyLaneAI/catalyst/pull/3039)
316+
[(#3046)](https://github.com/PennyLaneAI/catalyst/pull/3046)
316317

317318
* The `graph-decomposition` pass eliminates three redundant IR manipulations:
318319
the cloning, removal, and re-insertion of user rules. This optimization is particularly

mlir/lib/Quantum/Transforms/GraphDecomposition/DecompGraphSolver/DGBuilder.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,23 @@
1818

1919
#include "DGBuilder.hpp"
2020

21+
#include <cstddef>
2122
#include <cstdint>
2223
#include <iostream>
24+
#include <memory>
25+
#include <unordered_map>
26+
#include <unordered_set>
27+
#include <utility>
2328
#include <variant>
29+
#include <vector>
2430

25-
#include "DGUtils.hpp"
31+
#include "boost/graph/adjacency_list.hpp"
32+
#include "boost/graph/detail/adjacency_list.hpp"
33+
#include "boost/graph/graph_selectors.hpp"
34+
#include "boost/graph/graph_traits.hpp"
2635

27-
#include <boost/graph/adjacency_list.hpp>
36+
#include "DGTypes.hpp"
37+
#include "DGUtils.hpp"
2838

2939
using namespace DecompGraph::Core;
3040

mlir/lib/Quantum/Transforms/GraphDecomposition/DecompGraphSolver/DGBuilder.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#pragma once
2626

27+
#include <cstddef>
2728
#include <memory>
2829
#include <vector>
2930

mlir/lib/Quantum/Transforms/GraphDecomposition/DecompGraphSolver/DGSolver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818

1919
#include "DGSolver.hpp"
2020

21-
#include <algorithm>
2221
#include <optional>
22+
#include <string>
2323
#include <unordered_set>
24+
#include <utility>
2425
#include <vector>
2526

2627
#include "DGTypes.hpp"
28+
#include "DGUtils.hpp"
2729

2830
using namespace DecompGraph::Core;
2931

mlir/lib/Quantum/Transforms/GraphDecomposition/DecompGraphSolver/DGSolver.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@
2525

2626
#pragma once
2727

28-
#include <optional>
2928
#include <unordered_map>
3029
#include <unordered_set>
3130
#include <vector>
3231

3332
#include "DGBuilder.hpp"
3433
#include "DGTypes.hpp"
35-
#include "DGUtils.hpp"
3634

3735
namespace DecompGraph::Solver {
3836

mlir/lib/Quantum/Transforms/GraphDecomposition/DecompGraphSolver/DGTypes.hpp

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -53,39 +53,16 @@ namespace DecompGraph::Core {
5353
* when adding support for operators with dynamic numbers of wires/params.
5454
*/
5555
struct OperatorNode {
56-
std::string name;
57-
int numWires{-1};
58-
int numParams{-1};
56+
std::string id;
5957
bool adjoint{false};
6058

61-
// Optional static arguments for operators that require additional data.
59+
// optional params, primarily for debug use
60+
std::string name{""};
61+
int numWires{-1};
62+
int numParams{-1};
6263
std::unordered_map<std::string, std::string> staticNamedArgs{};
63-
std::string id{""};
6464

65-
bool operator==(const OperatorNode &other) const
66-
{
67-
// id match
68-
if (!id.empty() && !other.id.empty() && id == other.id) {
69-
return true;
70-
}
71-
// legacy fallback if either op is missing ID
72-
73-
// For equality, we consider numWires and numParams conditionally equal
74-
// if they are not set to -1 (which indicates a wildcard that can match any value).
75-
const bool default_wires =
76-
(numWires == -1 || other.numWires == -1 || numWires == other.numWires);
77-
const bool default_params =
78-
(numParams == -1 || other.numParams == -1 || numParams == other.numParams);
79-
80-
// Static arguments are optional: if either side has no static args, they
81-
// are treated as matching (wildcard). When both sides provide entries, the maps must
82-
// be equal element-wise for the operators to be considered equivalent.
83-
const bool static_args_match = staticNamedArgs.empty() || other.staticNamedArgs.empty() ||
84-
staticNamedArgs == other.staticNamedArgs;
85-
86-
return name == other.name && default_wires && default_params && adjoint == other.adjoint &&
87-
static_args_match;
88-
}
65+
bool operator==(const OperatorNode &other) const { return id == other.id; }
8966
bool operator!=(const OperatorNode &other) const { return !(*this == other); }
9067
};
9168

@@ -107,45 +84,24 @@ struct OperatorNode {
10784
struct OperatorNodeHash {
10885
std::size_t operator()(const OperatorNode &node) const
10986
{
110-
// prefer id if available
111-
if (!node.id.empty()) {
112-
return std::hash<std::string>{}(node.id);
113-
}
114-
return std::hash<std::string>{}(node.name);
87+
return std::hash<std::string>{}(node.id);
11588
}
11689
};
11790

11891
/**
11992
* @brief This represents the weighted target gateset for the graph decomposition problem.
12093
*/
12194
struct WeightedGateset {
95+
// TODO: using ID here mandates that gatesets specify all legal IDs, rather than generic class
96+
// like "PauliRot". This should be updated to work on generic names
12297
std::unordered_map<OperatorNode, double, OperatorNodeHash> ops;
12398

124-
[[nodiscard]] bool contains(const OperatorNode &op) const
125-
{
126-
// hash match
127-
if (ops.find(op) != ops.end()) {
128-
return true;
129-
}
130-
131-
// use op-matching if hashes failed (could be id vs name)
132-
for (auto [gatesetOp, cost] : ops) {
133-
if (gatesetOp == op) {
134-
return true;
135-
}
136-
}
137-
138-
return false;
139-
}
99+
[[nodiscard]] bool contains(const OperatorNode &op) const { return ops.find(op) != ops.end(); }
140100

141101
[[nodiscard]] double getCost(const OperatorNode &op) const
142102
{
143103
auto it = ops.find(op);
144-
if (it != ops.end()) {
145-
return it->second;
146-
}
147-
148-
return std::numeric_limits<double>::infinity();
104+
return it != ops.end() ? it->second : std::numeric_limits<double>::infinity();
149105
}
150106
};
151107

mlir/lib/Quantum/Transforms/GraphDecomposition/DecompGraphSolver/DGUtils.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <sstream>
2626
#include <stdexcept>
2727
#include <string>
28+
#include <utility>
2829
#include <vector>
2930

3031
#include "DGTypes.hpp"

mlir/lib/Quantum/Transforms/GraphDecomposition/graph_decomposition.cpp

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -422,28 +422,16 @@ struct GraphDecompositionPass : public impl::GraphDecompositionPassBase<GraphDec
422422
// dialect.
423423
// The interface will provide one unified way of generating operator nodes from operations,
424424
// with consistent getter methods for all relevant data fields.
425-
getOperation().walk([&](quantum::QuantumGate op) {
425+
getOperation().walk([&](DecomposableGate op) {
426426
if (DecompUtils::isInDecompRule(op)) {
427427
return;
428428
}
429429
OperatorNode node;
430430
node.numWires = op.getNonCtrlQubitOperands().size();
431431
node.adjoint = op.getAdjointFlag();
432432

433-
if (auto customOp = llvm::dyn_cast<quantum::CustomOp>(op.getOperation())) {
434-
node.name = customOp.getGateName().str();
435-
}
436-
// Name handling for non-custom ops
437-
else {
438-
std::string name = op->getName().stripDialect().str();
439-
if (name == "gphase") {
440-
name = "GlobalPhase";
441-
}
442-
else if (name == "paulirot") {
443-
name = cast<DecomposableGate>(op.getOperation()).getGraphOpId();
444-
}
445-
node.name = name;
446-
}
433+
node.name = op.getOperatorName();
434+
node.id = op.getGraphOpId();
447435

448436
if (auto paramOp =
449437
llvm::dyn_cast<catalyst::quantum::ParametrizedGate>(op.getOperation())) {
@@ -453,10 +441,6 @@ struct GraphDecompositionPass : public impl::GraphDecompositionPassBase<GraphDec
453441
node.numParams = 0;
454442
}
455443

456-
if (auto decompGate = dyn_cast<DecomposableGate>(op.getOperation())) {
457-
node.id = decompGate.getGraphOpId();
458-
}
459-
460444
operators.push_back(node);
461445
});
462446
}

0 commit comments

Comments
 (0)