Skip to content

Commit 4d2af1b

Browse files
track with main
2 parents aa16ead + 915a505 commit 4d2af1b

File tree

10 files changed

+50
-32
lines changed

10 files changed

+50
-32
lines changed

.dep-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ enzyme=v0.0.180
1010

1111
# For a custom PL version, update the package version here and at
1212
# 'doc/requirements.txt
13-
pennylane=0.42.0-dev33
13+
pennylane=0.42.0-dev48
1414

1515
# For a custom LQ/LK version, update the package version here and at
1616
# 'doc/requirements.txt'

doc/dev/transforms.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ Let's add the pattern-matching logic to the ``matchAndRewrite`` method:
299299
return failure();
300300
}
301301
302+
// In the line `Operation *parent = qbs[0].getDefiningOp();`,
303+
// we retrived the parent `Operation`, which only has methods on the
304+
// base `Operation` class
305+
// https://mlir.llvm.org/doxygen/classmlir_1_1Operation.html
306+
// To use the specific methods and the auto-generated getters for
307+
// the specific `QubitUnitaryOp`, we need to cast it first.
302308
QubitUnitaryOp parentOp = cast<QubitUnitaryOp>(parent);
303309
ValueRange parentQbs = parentOp.getOutQubits();
304310
@@ -308,10 +314,11 @@ Let's add the pattern-matching logic to the ``matchAndRewrite`` method:
308314
return failure();
309315
}
310316
311-
for (auto [qb1, qb2] : llvm::zip(qbs, parentQbs))
317+
for (auto [qb1, qb2] : llvm::zip(qbs, parentQbs)) {
312318
if (qb1 != qb2) {
313319
return failure();
314320
}
321+
}
315322
316323
// Rewrite logic
317324
// ... We have matched the pattern, now rewrite the IR here
@@ -370,9 +377,9 @@ In C++ it will look as follows:
370377
// Pattern matching logic
371378
// ... match the pattern
372379
380+
//////////////////////////////////////////////////
381+
373382
// Rewrite logic
374-
ValueRange qbs = op.getInQubits();
375-
QubitUnitaryOp parentOp = cast<QubitUnitaryOp>(qbs[0].getDefiningOp());
376383
377384
// In the tablegen definition of `QubitUnitaryOp`, there is a
378385
// field called `$matrix`, storing the matrix for the unitary gate.
@@ -536,7 +543,7 @@ fixed point is reached.
536543

537544
If you are encoutering issues, or would like to quickly try out the merge unitary pass described in this
538545
section, you can have a look at or cherry-pick this commit which includes all changes described
539-
in this section: https://github.com/PennyLaneAI/catalyst/commit/9afcc3500e12e5a51b78dda76cd4d27bdf4c8905
546+
in this section: https://github.com/PennyLaneAI/catalyst/commit/2c84b2402cb67c62a6de5137bbf5b41afaa5a328
540547

541548

542549
Writing more general transformations

doc/releases/changelog-dev.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@
218218
* `make all` now correctly compiles the standalone plugin with the same compiler used to compile LLVM and MLIR.
219219
[(#1768)](https://github.com/PennyLaneAI/catalyst/pull/1768)
220220

221+
* Stacked python decorators for built-in catalyst passes are now applied in the correct order.
222+
[(#1798)](https://github.com/PennyLaneAI/catalyst/pull/1798)
223+
221224
<h3>Internal changes ⚙️</h3>
222225

223226
* `null.qubit` can now support an optional `track_resources` argument which allows it to record which gates are executed.

doc/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ lxml_html_clean
3333
--extra-index-url https://test.pypi.org/simple/
3434
pennylane-lightning-kokkos==0.42.0-dev16
3535
pennylane-lightning==0.42.0-dev16
36-
pennylane==0.42.0-dev33
36+
pennylane==0.42.0-dev48

frontend/catalyst/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
Version number (major.minor.patch[-label])
1717
"""
1818

19-
__version__ = "0.12.0-dev50"
19+
__version__ = "0.12.0-dev53"

frontend/catalyst/passes/pass_api.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ def __init__(self, qnode, pass_name_or_pipeline, *flags, **valued_options):
7272
def __call__(self, *args, **kwargs):
7373
if EvaluationContext.is_tracing():
7474
pass_pipeline = kwargs.pop("pass_pipeline", [])
75-
pass_pipeline += dictionary_to_list_of_passes(
76-
self.pass_name_or_pipeline, *self.flags, **self.valued_options
75+
pass_pipeline = (
76+
dictionary_to_list_of_passes(
77+
self.pass_name_or_pipeline, *self.flags, **self.valued_options
78+
)
79+
+ pass_pipeline
7780
)
7881
kwargs["pass_pipeline"] = pass_pipeline
7982
return super().__call__(*args, **kwargs)

frontend/test/lit/test_peephole_optimizations.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,10 @@ def test_chained_pipeline_lowering():
278278
"""
279279
pipeline1 = {
280280
"cancel_inverses": {},
281-
"merge_rotations": {},
282281
}
283282
pipeline2 = {
284283
"cancel_inverses": {},
284+
"merge_rotations": {},
285285
}
286286

287287
@qjit()
@@ -343,8 +343,8 @@ def test_chained_pipeline_lowering_keep_original_workflow(x: float):
343343
# COM: The qnode after pipeline2
344344
# CHECK: transform.named_sequence @__transform_main
345345
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
346-
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
347346
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "merge-rotations" to {{%.+}}
347+
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
348348
# CHECK-NEXT: transform.yield
349349
print(test_chained_pipeline_lowering_keep_original_workflow.mlir)
350350

@@ -358,8 +358,8 @@ def test_chained_apply_passes():
358358
"""
359359

360360
@qjit()
361-
@apply_pass("remove-chained-self-inverse")
362361
@apply_pass("merge-rotations")
362+
@apply_pass("remove-chained-self-inverse")
363363
@qml.qnode(qml.device("lightning.qubit", wires=2))
364364
def test_chained_apply_passes_workflow(x: float):
365365
qml.Hadamard(wires=[1])
@@ -406,8 +406,8 @@ def test_chained_apply_passes_keep_original_workflow(x: float):
406406
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
407407
# COM: The qnode after merge_rotations
408408
# CHECK: transform.named_sequence @__transform_main
409-
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "merge-rotations" to {{%.+}}
410409
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
410+
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "merge-rotations" to {{%.+}}
411411
# CHECK-NEXT: transform.yield
412412
print(test_chained_apply_passes_keep_original_workflow.mlir)
413413

@@ -421,8 +421,8 @@ def test_chained_peephole_passes():
421421
"""
422422

423423
@qjit()
424-
@cancel_inverses
425424
@merge_rotations
425+
@cancel_inverses
426426
@qml.qnode(qml.device("lightning.qubit", wires=2))
427427
def test_chained_peephole_passes_workflow(x: float):
428428
qml.Hadamard(wires=[1])
@@ -469,8 +469,8 @@ def test_chained_peephole_passes_keep_original_workflow(x: float):
469469
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
470470
# COM: The qnode after merge_rotations
471471
# CHECK: transform.named_sequence @__transform_main
472-
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "merge-rotations" to {{%.+}}
473472
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
473+
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "merge-rotations" to {{%.+}}
474474
# CHECK-NEXT: transform.yield
475475
print(test_chained_peephole_passes_keep_original_workflow.mlir)
476476

@@ -569,8 +569,8 @@ def test_stacked_pass_for_loop_autograph():
569569
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "remove-chained-self-inverse" to {{%.+}}
570570
# CHECK-NEXT: {{%.+}} = transform.apply_registered_pass "merge-rotations" to {{%.+}}
571571
# CHECK-NEXT: transform.yield
572-
@cancel_inverses
573572
@merge_rotations
573+
@cancel_inverses
574574
@qml.qnode(qml.device("null.qubit", wires=1))
575575
def circuit(n_iter: int):
576576
for _ in range(n_iter):

frontend/test/lit/test_ppr_ppm.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ def test_commute_ppr():
6060
pipe = [("pipe", ["enforce-runtime-invariants-pipeline"])]
6161

6262
@qjit(pipelines=pipe, target="mlir")
63-
@to_ppr
6463
@commute_ppr
64+
@to_ppr
6565
@qml.qnode(qml.device("null.qubit", wires=2))
6666
def cir_commute_ppr():
6767
qml.H(0)
@@ -91,8 +91,8 @@ def test_commute_ppr_max_pauli_size():
9191
pipe = [("pipe", ["enforce-runtime-invariants-pipeline"])]
9292

9393
@qjit(pipelines=pipe, target="mlir")
94-
@to_ppr
9594
@commute_ppr(max_pauli_size=2)
95+
@to_ppr
9696
@qml.qnode(qml.device("null.qubit", wires=2))
9797
def cir_commute_ppr_max_pauli_size():
9898
qml.CNOT([0, 2])
@@ -122,8 +122,8 @@ def test_merge_ppr_ppm():
122122
pipe = [("pipe", ["enforce-runtime-invariants-pipeline"])]
123123

124124
@qjit(pipelines=pipe, target="mlir")
125-
@to_ppr
126125
@merge_ppr_ppm
126+
@to_ppr
127127
@qml.qnode(qml.device("null.qubit", wires=2))
128128
def cir_merge_ppr_ppm():
129129
qml.H(0)
@@ -150,8 +150,8 @@ def test_merge_ppr_ppm_max_pauli_size():
150150
pipe = [("pipe", ["enforce-runtime-invariants-pipeline"])]
151151

152152
@qjit(pipelines=pipe, target="mlir")
153-
@to_ppr
154153
@merge_ppr_ppm(max_pauli_size=1)
154+
@to_ppr
155155
@qml.qnode(qml.device("null.qubit", wires=2))
156156
def cir_merge_ppr_ppm_max_pauli_size():
157157
qml.CNOT([0, 2])
@@ -182,14 +182,14 @@ def test_ppr_to_ppm():
182182
@qjit(pipelines=pipe, target="mlir")
183183
def circuit_ppr_to_ppm():
184184

185-
@to_ppr
186185
@ppr_to_ppm
186+
@to_ppr
187187
@qml.qnode(device)
188188
def cir_default():
189189
qml.S(0)
190190

191-
@to_ppr
192191
@ppr_to_ppm(decompose_method="clifford-corrected", avoid_y_measure=True)
192+
@to_ppr
193193
@qml.qnode(device)
194194
def cir_inject_magic_state():
195195
qml.T(0)

frontend/test/pytest/test_peephole_optimizations.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ def test_chained_passes():
173173
"""
174174

175175
@qjit()
176-
@cancel_inverses
177176
@merge_rotations
177+
@cancel_inverses
178178
@qml.qnode(qml.device("lightning.qubit", wires=2))
179179
def test_chained_apply_passes_workflow(x: float):
180180
qml.Hadamard(wires=[1])
@@ -217,8 +217,8 @@ def test_commute_ppr():
217217
@qjit(pipelines=pipe, target="mlir")
218218
def test_commute_ppr_workflow():
219219

220-
@to_ppr
221220
@commute_ppr
221+
@to_ppr
222222
@qml.qnode(qml.device("lightning.qubit", wires=2))
223223
def f():
224224
qml.H(0)
@@ -243,8 +243,8 @@ def test_merge_ppr_ppm():
243243
@qjit(pipelines=pipe, target="mlir")
244244
def test_merge_ppr_ppm_workflow():
245245

246-
@to_ppr
247246
@merge_ppr_ppm
247+
@to_ppr
248248
@qml.qnode(qml.device("lightning.qubit", wires=2))
249249
def f():
250250
qml.H(0)
@@ -268,8 +268,8 @@ def test_ppr_to_ppm():
268268
@qjit(pipelines=pipe, target="mlir")
269269
def test_ppr_to_ppm_workflow():
270270

271-
@to_ppr
272271
@ppr_to_ppm
272+
@to_ppr
273273
@qml.qnode(qml.device("lightning.qubit", wires=2))
274274
def f():
275275
qml.H(0)
@@ -303,8 +303,8 @@ def test_ppr_to_ppm_inject_magic_state():
303303
@qjit(pipelines=pipe, target="mlir")
304304
def test_ppr_to_ppm_workflow():
305305

306-
@to_ppr
307306
@ppr_to_ppm(decompose_method="clifford-corrected", avoid_y_measure=True)
307+
@to_ppr
308308
@qml.qnode(qml.device("lightning.qubit", wires=2))
309309
def f():
310310
qml.H(0)
@@ -336,18 +336,18 @@ def test_convert_clifford_to_ppr_workflow():
336336

337337
device = qml.device("lightning.qubit", wires=2)
338338

339-
@to_ppr
340-
@commute_ppr(max_pauli_size=2)
341339
@merge_ppr_ppm
340+
@commute_ppr(max_pauli_size=2)
341+
@to_ppr
342342
@qml.qnode(device)
343343
def f():
344344
qml.CNOT([0, 2])
345345
qml.T(0)
346346
return measure(0), measure(1)
347347

348-
@to_ppr
349-
@commute_ppr
350348
@merge_ppr_ppm(max_pauli_size=1)
349+
@commute_ppr
350+
@to_ppr
351351
@qml.qnode(device)
352352
def g():
353353
qml.CNOT([0, 2])

frontend/test/pytest/test_quantum_control.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,17 +850,22 @@ def test_flatten_unflatten(self):
850850
control_wires = qml.wires.Wires((1, 2))
851851
control_values = (False, False) # (0, 0)
852852
work_wires = qml.wires.Wires(3)
853+
# A work_wire_type will be kept until dynamic qubit allocation is supported in PL
854+
# Default value is "dirty"
855+
# https://github.com/PennyLaneAI/pennylane/pull/7612
856+
work_wire_type = "dirty"
853857

854858
op = C_ctrl(target, control_wires, control_values=control_values, work_wires=work_wires)
855859

856860
data, metadata = op._flatten()
857861
assert data[0] is target
858862
assert len(data) == 1
859863

860-
assert len(metadata) == 3
864+
assert len(metadata) == 4
861865
assert metadata[0] == control_wires
862866
assert metadata[1] == control_values
863867
assert metadata[2] == work_wires
868+
assert metadata[3] == work_wire_type
864869

865870
assert hash(metadata)
866871

0 commit comments

Comments
 (0)