Commit e67b2d8
authored
**Context:** In order to support more general input programs in the
experimental QEC compilation pipeline, we must add support for
control-flow operations.
**Description of the Change:** This PR adds support for `while` loops
(via
[`scf.while`](https://mlir.llvm.org/docs/Dialects/SCFDialect/#scfwhile-scfwhileop)
ops) in the `convert-quantum-to-qecl` pass. For example, an input
program such as
```mlir
func.func @test_program(%arg0: f64) {
%c2 = arith.constant 2.000000e+00 : f64
%c9 = arith.constant 9.000000e+00 : f64
%0 = quantum.alloc(1) : !quantum.reg
%1 = quantum.extract %0[0] : !quantum.reg -> !quantum.bit
%2, %3 = scf.while (%arg1 = %arg0, %arg2 = %1) : (f64, !quantum.bit) -> (f64, !quantum.bit) {
%4 = arith.cmpf olt, %arg1, %c9 : f64
scf.condition(%4) %arg1, %arg2 : f64, !quantum.bit
} do {
^bb0(%arg1_1: f64, %arg2_1: !quantum.bit):
%5 = quantum.custom "PauliX"() %1 : !quantum.bit
%6 = arith.addf %arg1_1, %c2 : f64
scf.yield %6, %5 : f64, !quantum.bit
}
%7 = quantum.insert %0[0], %3 : !quantum.reg, !quantum.bit
quantum.dealloc %7 : !quantum.reg
func.return
}
```
is lowered to
```mlir
func.func @test_program(%arg0: f64) {
%c2 = arith.constant 2.000000e+00 : f64
%c9 = arith.constant 9.000000e+00 : f64
%0 = qecl.alloc() : !qecl.hyperreg<1 x 1>
%1 = arith.constant 0 : index
%2 = arith.constant 1 : index
%3 = arith.constant 1 : index
%4 = scf.for %5 = %1 to %2 step %3 iter_args(%6 = %0) -> (!qecl.hyperreg<1 x 1>) {
%7 = qecl.extract_block %6[%5] : !qecl.hyperreg<1 x 1> -> !qecl.codeblock<1>
%8 = qecl.encode[zero] %7 : !qecl.codeblock<1>
%9 = qecl.insert_block %6[%5], %8 : !qecl.hyperreg<1 x 1>, !qecl.codeblock<1>
scf.yield %9 : !qecl.hyperreg<1 x 1>
}
%10 = qecl.extract_block %4[0] : !qecl.hyperreg<1 x 1> -> !qecl.codeblock<1>
%11 = qecl.qec %10 : !qecl.codeblock<1>
%12, %13 = scf.while (%arg1 = %arg0, %arg2 = %11) : (f64, !qecl.codeblock<1>) -> (f64, !qecl.codeblock<1>) {
%14 = arith.cmpf olt, %arg1, %c9 : f64
scf.condition(%14) %arg1, %arg2 : f64, !qecl.codeblock<1>
} do {
^bb0(%arg1_1: f64, %arg2_1: !qecl.codeblock<1>):
%15 = qecl.x %11[0] : !qecl.codeblock<1>
%16 = qecl.qec %15 : !qecl.codeblock<1>
%17 = arith.addf %arg1_1, %c2 : f64
scf.yield %17, %16 : f64, !qecl.codeblock<1>
}
%18 = qecl.insert_block %4[0], %13 : !qecl.hyperreg<1 x 1>, !qecl.codeblock<1>
qecl.dealloc %18 : !qecl.hyperreg<1 x 1>
func.return
}
```
Support for `scf.while` ops that return `!quantum.reg` values, and a mix
of quantum and classical types, has also been added.
This PR also refactors the other `scf` conversion patterns (for `scf.if`
and `scf.for`) to improve code abstractions and reduce code duplication.
[sc-120267]
1 parent dbb5c2c commit e67b2d8
3 files changed
Lines changed: 351 additions & 121 deletions
File tree
- doc/releases
- frontend
- catalyst/python_interface/transforms/qecl
- test/pytest/python_interface/transforms/qecl
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
313 | 313 | | |
314 | 314 | | |
315 | 315 | | |
| 316 | + | |
| 317 | + | |
316 | 318 | | |
317 | 319 | | |
318 | 320 | | |
| |||
0 commit comments