Skip to content

Commit c94336b

Browse files
reza-jbcdonovan
andauthored
cleaning up QUIRToPulse pass (#213)
This PR includes some clean up for QUIRToPulse pass. 1) it erases ALL the DeclareQubitOp at the end of the pass (including the ones not used in the input program) 2) it erases quir barriers before erasing their operands. Currently, barriers can reside outside the circuits and need to be removed before removing the DeclareQubitOps (which are operands to quir barriers). --------- Co-authored-by: Brian Donovan <[email protected]>
1 parent cbdbeb0 commit c94336b

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

lib/Conversion/QUIRToPulse/QUIRToPulse.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,20 @@ void QUIRToPulsePass::runOnOperation() {
110110
op->erase();
111111
}
112112

113+
// erase quir barriers before erasing the operands
114+
moduleOp->walk([&](mlir::quir::BarrierOp barrierOp) { barrierOp->erase(); });
115+
113116
// erase the quir circuit operands
114117
LLVM_DEBUG(llvm::dbgs() << "\nErasing quir circuit operands:\n");
115118
for (auto *op : quirCircuitOperandEraseList) {
116119
LLVM_DEBUG(op->dump());
117120
op->erase();
118121
}
122+
123+
// erase the rest of quir.declare_qubits (unused in the input program)
124+
moduleOp->walk([&](mlir::quir::DeclareQubitOp declareQubitOp) {
125+
declareQubitOp->erase();
126+
});
119127
}
120128

121129
void QUIRToPulsePass::convertCircuitToSequence(CallCircuitOp callCircuitOp,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- |
4+
Support for handling quir.barriers is added to quirToPulse pass.
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// RUN: qss-compiler %s --quir-to-pulse | FileCheck %s
2+
3+
//
4+
// This code is part of Qiskit.
5+
//
6+
// (C) Copyright IBM 2023.
7+
//
8+
// This code is licensed under the Apache License, Version 2.0 with LLVM
9+
// Exceptions. You may obtain a copy of this license in the LICENSE.txt
10+
// file in the root directory of this source tree.
11+
//
12+
// Any modifications or derivative works of this code must retain this
13+
// copyright notice, and modified files need to carry a notice indicating
14+
// that they have been altered from the originals.
15+
16+
module {
17+
quir.circuit @circuit_0_q5_q3_circuit_1_q5(%arg0: !quir.qubit<1> {quir.physicalId = 5 : i32}, %arg1: !quir.qubit<1> {quir.physicalId = 3 : i32}) -> (i1, i1) attributes {quir.classicalOnly = false, quir.physicalIds = [3 : i32, 5 : i32]} {
18+
// CHECK-NOT: quir.circuit @circuit_0_q5_q3_circuit_1_q5(%arg0: !quir.qubit<1> {quir.physicalId = 5 : i32}, %arg1: !quir.qubit<1> {quir.physicalId = 3 : i32}) -> (i1, i1) attributes {quir.classicalOnly = false, quir.physicalIds = [3 : i32, 5 : i32]} {
19+
quir.call_gate @x(%arg1) {pulse.calName = "x_3"} : (!quir.qubit<1>) -> ()
20+
quir.call_gate @sx(%arg0) {pulse.calName = "sx_5"} : (!quir.qubit<1>) -> ()
21+
%0:2 = quir.measure(%arg1, %arg0) {pulse.calName = "measure_3_5"} : (!quir.qubit<1>, !quir.qubit<1>) -> (i1, i1)
22+
quir.return %0#0, %0#1 : i1, i1
23+
}
24+
quir.circuit @circuit_2_q5_q3_circuit_3_q5(%arg0: !quir.qubit<1> {quir.physicalId = 5 : i32}, %arg1: !quir.qubit<1> {quir.physicalId = 3 : i32}) -> (i1, i1) attributes {quir.classicalOnly = false, quir.physicalIds = [3 : i32, 5 : i32]} {
25+
// CHECK-NOT: quir.circuit @circuit_2_q5_q3_circuit_3_q5(%arg0: !quir.qubit<1> {quir.physicalId = 5 : i32}, %arg1: !quir.qubit<1> {quir.physicalId = 3 : i32}) -> (i1, i1) attributes {quir.classicalOnly = false, quir.physicalIds = [3 : i32, 5 : i32]} {
26+
%angle = quir.constant #quir.angle<1.5707963267948966> : !quir.angle<64>
27+
quir.call_gate @rz(%arg0, %angle) {pulse.calName = "rz_5"} : (!quir.qubit<1>, !quir.angle<64>) -> ()
28+
quir.call_gate @sx(%arg0) {pulse.calName = "sx_5"} : (!quir.qubit<1>) -> ()
29+
quir.call_gate @rz(%arg0, %angle) {pulse.calName = "rz_5"} : (!quir.qubit<1>, !quir.angle<64>) -> ()
30+
quir.builtin_CX {pulse.calName = "cx_5_3"} %arg0, %arg1 : !quir.qubit<1>, !quir.qubit<1>
31+
%0:2 = quir.measure(%arg1, %arg0) {pulse.calName = "measure_3_5"} : (!quir.qubit<1>, !quir.qubit<1>) -> (i1, i1)
32+
quir.return %0#0, %0#1 : i1, i1
33+
}
34+
pulse.sequence @x_3(%arg0: !pulse.mixed_frame) -> i1 attributes {pulse.argPorts = ["q3-drive-port"], pulse.args = ["q3-drive-mixframe"]} {
35+
%x3_pulse = pulse.create_waveform {pulse.waveformName = "x3_pulse"} dense<[[0.0, 1.0], [0.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, -1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, -1.0]]> : tensor<16x2xf64> -> !pulse.waveform
36+
pulse.play {pulse.duration = 16 : i64, pulse.timepoint = 0 : i64}(%arg0, %x3_pulse) : (!pulse.mixed_frame, !pulse.waveform)
37+
%false = arith.constant false
38+
pulse.return %false : i1
39+
}
40+
pulse.sequence @measure_3_5(%arg0: !pulse.mixed_frame, %arg2: !pulse.mixed_frame,%arg4: !pulse.mixed_frame, %arg6: !pulse.mixed_frame) -> (i1, i1)
41+
attributes {pulse.argPorts = ["q3-readout-port", "q3-capture-port", "q5-readout-port", "q5-capture-port"],
42+
pulse.args = ["q3-readout-mixframe", "q3-capture-mixframe", "q5-readout-mixframe", "q5-capture-mixframe"]} {
43+
%q3_readout = pulse.create_waveform {pulse.waveformName = "q3_readout_pulse"} dense<[[0.0, 1.0], [0.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, -1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, -1.0]]> : tensor<16x2xf64> -> !pulse.waveform
44+
%q5_readout = pulse.create_waveform {pulse.waveformName = "q5_readout_pulse"} dense<[[0.0, 1.0], [0.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, -1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, -1.0]]> : tensor<16x2xf64> -> !pulse.waveform
45+
pulse.play {pulse.duration = 16 : i64, pulse.timepoint = 0 : i64}(%arg0, %q3_readout) : (!pulse.mixed_frame, !pulse.waveform)
46+
pulse.play {pulse.duration = 16 : i64, pulse.timepoint = 0 : i64}(%arg4, %q5_readout) : (!pulse.mixed_frame, !pulse.waveform)
47+
%0 = pulse.capture {pulse.duration = 1024 : i64, pulse.timepoint = 272 : i64}(%arg2) : (!pulse.mixed_frame) -> i1
48+
%1 = pulse.capture {pulse.duration = 1024 : i64, pulse.timepoint = 272 : i64}(%arg6) : (!pulse.mixed_frame) -> i1
49+
pulse.return %0, %1 : i1, i1
50+
}
51+
pulse.sequence @rz_5(%arg0: f64, %arg1: !pulse.mixed_frame) -> i1
52+
attributes {pulse.argPorts = ["", "q5-drive-port"], pulse.args = ["angle", "q5-drive-mixframe"]} {
53+
pulse.shift_phase {pulse.timepoint = 0 : i64}(%arg1, %arg0) : (!pulse.mixed_frame, f64)
54+
%false = arith.constant false
55+
pulse.return %false : i1
56+
}
57+
pulse.sequence @sx_5(%arg0: !pulse.mixed_frame) -> i1
58+
attributes {pulse.argPorts = ["q5-drive-port"], pulse.args = ["q5-drive-mixframe"]} {
59+
%sx5_pulse = pulse.create_waveform {pulse.waveformName = "sx5_pulse"} dense<[[0.0, 1.0], [0.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, -1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, -1.0]]> : tensor<16x2xf64> -> !pulse.waveform
60+
pulse.play {pulse.duration = 16 : i64, pulse.timepoint = 0 : i64}(%arg0, %sx5_pulse) : (!pulse.mixed_frame, !pulse.waveform)
61+
%false = arith.constant false
62+
pulse.return %false : i1
63+
}
64+
pulse.sequence @cx_5_3(%arg0: !pulse.mixed_frame, %arg1: !pulse.mixed_frame) -> i1
65+
attributes {pulse.argPorts = ["q3-drive-port", "q5-drive-port"],
66+
pulse.args = ["q3-5-cx-mixframe", "q5-3-cx-mixframe"]} {
67+
%cx_5_3_pulse = pulse.create_waveform {pulse.waveformName = "cx_5_3_pulse"} dense<[[0.0, 1.0], [0.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, -1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, -1.0]]> : tensor<16x2xf64> -> !pulse.waveform
68+
%cst_0 = arith.constant 1.5707963267948966 : f64
69+
pulse.shift_phase {pulse.timepoint = 0 : i64}(%arg0, %cst_0) : (!pulse.mixed_frame, f64)
70+
pulse.play {pulse.duration = 16 : i64, pulse.timepoint = 0 : i64}(%arg1, %cx_5_3_pulse) : (!pulse.mixed_frame, !pulse.waveform)
71+
%false = arith.constant false
72+
pulse.return %false : i1
73+
}
74+
// CHECK: pulse.sequence @circuit_0_q5_q3_circuit_1_q5_sequence(%arg0: !pulse.mixed_frame, %arg1: !pulse.mixed_frame, %arg2: !pulse.mixed_frame, %arg3: !pulse.mixed_frame, %arg4: !pulse.mixed_frame, %arg5: !pulse.mixed_frame) -> (i1, i1, i1, i1) attributes {pulse.args = ["q3-drive-mixframe", "q5-drive-mixframe", "q3-readout-mixframe", "q3-capture-mixframe", "q5-readout-mixframe", "q5-capture-mixframe"]} {
75+
// CHECK: %0 = pulse.call_sequence @x_3(%arg0) {{{.*}} : (!pulse.mixed_frame) -> i1
76+
// CHECK: %1 = pulse.call_sequence @sx_5(%arg1) {{{.*}} : (!pulse.mixed_frame) -> i1
77+
// CHECK: %2:2 = pulse.call_sequence @measure_3_5(%arg2, %arg3, %arg4, %arg5) {{{.*}} : (!pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame) -> (i1, i1)
78+
// CHECK: pulse.return %0, %1, %2#0, %2#1 : i1, i1, i1, i1
79+
80+
// CHECK: pulse.sequence @circuit_2_q5_q3_circuit_3_q5_sequence(%arg0: !pulse.mixed_frame, %arg1: !pulse.mixed_frame, %arg2: !pulse.mixed_frame, %arg3: !pulse.mixed_frame, %arg4: !pulse.mixed_frame, %arg5: !pulse.mixed_frame, %arg6: !pulse.mixed_frame) -> (i1, i1, i1, i1, i1, i1) attributes {pulse.args = ["q5-drive-mixframe", "q3-5-cx-mixframe", "q5-3-cx-mixframe", "q3-readout-mixframe", "q3-capture-mixframe", "q5-readout-mixframe", "q5-capture-mixframe"]} {
81+
// CHECK: %cst = arith.constant 1.5707963267948966 : f64
82+
// CHECK: %0 = pulse.call_sequence @rz_5(%cst, %arg0) {{{.*}} : (f64, !pulse.mixed_frame) -> i1
83+
// CHECK: %1 = pulse.call_sequence @sx_5(%arg0) {{{.*}} : (!pulse.mixed_frame) -> i1
84+
// CHECK: %2 = pulse.call_sequence @rz_5(%cst, %arg0) {{{.*}} : (f64, !pulse.mixed_frame) -> i1
85+
// CHECK: %3 = pulse.call_sequence @cx_5_3(%arg1, %arg2) {{{.*}} : (!pulse.mixed_frame, !pulse.mixed_frame) -> i1
86+
// CHECK: %4:2 = pulse.call_sequence @measure_3_5(%arg3, %arg4, %arg5, %arg6) {{{.*}} : (!pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame) -> (i1, i1)
87+
// CHECK: pulse.return %0, %1, %2, %3, %4#0, %4#1 : i1, i1, i1, i1, i1, i1
88+
89+
func.func @main() -> i32 attributes {quir.classicalOnly = false} {
90+
// CHECK: %0 = "pulse.create_port"() {uid = "q3-drive-port"} : () -> !pulse.port
91+
// CHECK: %1 = "pulse.mix_frame"(%0) {uid = "q3-drive-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
92+
// CHECK: %2 = "pulse.create_port"() {uid = "q5-drive-port"} : () -> !pulse.port
93+
// CHECK: %3 = "pulse.mix_frame"(%2) {uid = "q5-drive-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
94+
// CHECK: %4 = "pulse.create_port"() {uid = "q3-readout-port"} : () -> !pulse.port
95+
// CHECK: %5 = "pulse.mix_frame"(%4) {uid = "q3-readout-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
96+
// CHECK: %6 = "pulse.create_port"() {uid = "q3-capture-port"} : () -> !pulse.port
97+
// CHECK: %7 = "pulse.mix_frame"(%6) {uid = "q3-capture-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
98+
// CHECK: %8 = "pulse.create_port"() {uid = "q5-readout-port"} : () -> !pulse.port
99+
// CHECK: %9 = "pulse.mix_frame"(%8) {uid = "q5-readout-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
100+
// CHECK: %10 = "pulse.create_port"() {uid = "q5-capture-port"} : () -> !pulse.port
101+
// CHECK: %11 = "pulse.mix_frame"(%10) {uid = "q5-capture-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
102+
// CHECK: %12 = "pulse.mix_frame"(%0) {uid = "q3-5-cx-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
103+
// CHECK: %13 = "pulse.mix_frame"(%2) {uid = "q5-3-cx-mixframe"} : (!pulse.port) -> !pulse.mixed_frame
104+
%c0_i32 = arith.constant 0 : i32
105+
%c1 = arith.constant 1 : index
106+
%c1000 = arith.constant 1000 : index
107+
%c0 = arith.constant 0 : index
108+
scf.for %arg0 = %c0 to %c1000 step %c1 {
109+
qcs.shot_init {qcs.num_shots = 1000 : i32}
110+
%0 = quir.declare_qubit {id = 0 : i32} : !quir.qubit<1>
111+
// CHECK-NOT: %0 = quir.declare_qubit {id = 0 : i32} : !quir.qubit<1>
112+
%1 = quir.declare_qubit {id = 1 : i32} : !quir.qubit<1>
113+
// CHECK-NOT: %1 = quir.declare_qubit {id = 1 : i32} : !quir.qubit<1>
114+
%2 = quir.declare_qubit {id = 2 : i32} : !quir.qubit<1>
115+
// CHECK-NOT: %2 = quir.declare_qubit {id = 2 : i32} : !quir.qubit<1>
116+
%3 = quir.declare_qubit {id = 3 : i32} : !quir.qubit<1>
117+
// CHECK-NOT: %3 = quir.declare_qubit {id = 3 : i32} : !quir.qubit<1>
118+
%4 = quir.declare_qubit {id = 4 : i32} : !quir.qubit<1>
119+
// CHECK-NOT: %4 = quir.declare_qubit {id = 4 : i32} : !quir.qubit<1>
120+
%5 = quir.declare_qubit {id = 5 : i32} : !quir.qubit<1>
121+
// CHECK-NOT: %5 = quir.declare_qubit {id = 5 : i32} : !quir.qubit<1>
122+
%7:2 = quir.call_circuit @circuit_0_q5_q3_circuit_1_q5(%5, %3) : (!quir.qubit<1>, !quir.qubit<1>) -> (i1, i1)
123+
// CHECK-NOT: %7:2 = quir.call_circuit @circuit_0_q5_q3_circuit_1_q5(%5, %3) : (!quir.qubit<1>, !quir.qubit<1>) -> (i1, i1)
124+
// CHECK: %14:4 = pulse.call_sequence @circuit_0_q5_q3_circuit_1_q5_sequence(%1, %3, %5, %7, %9, %11) {{{.*}} : (!pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame) -> (i1, i1, i1, i1)
125+
quir.barrier %3, %5 : (!quir.qubit<1>, !quir.qubit<1>) -> ()
126+
// CHECK-NOT: %quir.barrier %3, %5 : (!quir.qubit<1>, !quir.qubit<1>) -> ()
127+
%8:2 = quir.call_circuit @circuit_2_q5_q3_circuit_3_q5(%5, %3) : (!quir.qubit<1>, !quir.qubit<1>) -> (i1, i1)
128+
// CHECK-NOT: %8:2 = quir.call_circuit @circuit_2_q5_q3_circuit_3_q5(%5, %3) : (!quir.qubit<1>, !quir.qubit<1>) -> (i1, i1)
129+
// CHECK: %15:6 = pulse.call_sequence @circuit_2_q5_q3_circuit_3_q5_sequence(%3, %12, %13, %5, %7, %9, %11) {{{.*}} : (!pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame, !pulse.mixed_frame) -> (i1, i1, i1, i1, i1, i1)
130+
} {qcs.shot_loop}
131+
return %c0_i32 : i32
132+
}
133+
}

0 commit comments

Comments
 (0)