@@ -106,14 +106,37 @@ impl QSystemPass {
106
106
self . validation_level . run_validated_pass ( hugr, |hugr, _| {
107
107
force_order ( hugr, hugr. root ( ) , |hugr, node| {
108
108
let optype = hugr. get_optype ( node) ;
109
- if optype. cast :: < Tk2Op > ( ) . is_some ( ) || optype. cast :: < QSystemOp > ( ) . is_some ( ) {
110
- // quantum ops are lifted as early as possible
109
+
110
+ let is_quantum =
111
+ optype. cast :: < Tk2Op > ( ) . is_some ( ) || optype. cast :: < QSystemOp > ( ) . is_some ( ) ;
112
+ let is_qalloc =
113
+ matches ! ( optype. cast( ) , Some ( Tk2Op :: QAlloc ) | Some ( Tk2Op :: TryQAlloc ) )
114
+ || optype. cast ( ) == Some ( QSystemOp :: TryQAlloc ) ;
115
+ let is_qfree =
116
+ optype. cast ( ) == Some ( Tk2Op :: QFree ) || optype. cast ( ) == Some ( QSystemOp :: QFree ) ;
117
+ let is_read = optype. cast ( ) == Some ( FutureOpDef :: Read ) ;
118
+
119
+ // HACK: for now qallocs and qfrees are not adequately ordered,
120
+ // see <https://github.com/CQCL/guppylang/issues/778>. To
121
+ // mitigate this we push qfrees as early as possible and qallocs
122
+ // as late as possible
123
+ //
124
+ // To maximise lazyness we push quantum ops (including
125
+ // LazyMeasure) as early as possible and Future::Read as late as
126
+ // possible.
127
+ if is_qfree {
128
+ -3
129
+ } else if is_quantum && !is_qalloc {
130
+ // non-qalloc quantum ops
131
+ -2
132
+ } else if is_qalloc {
111
133
-1
112
- } else if let Some ( FutureOpDef :: Read ) = hugr. get_optype ( node) . cast ( ) {
113
- // read ops are sunk as late as possible
114
- 1
115
- } else {
134
+ } else if !is_read {
135
+ // all other ops
116
136
0
137
+ } else {
138
+ // Future::Read ops
139
+ 1
117
140
}
118
141
} ) ?;
119
142
Ok :: < _ , QSystemPassError > ( ( ) )
0 commit comments