Skip to content

Commit ee0fc7f

Browse files
authored
Use CCNOT instead of AND for multi-controlled operations (#2807)
This avoids the measurement-based uncomputation in the intrinsic `AND` operation in favor of just using `CCNOT` when decomposing multiple controls on `Std.Intrinsic` gates. This leaves optimization of resulting QIR ccx to the program author or the backend that receives the QIR. This makes the behavior of most code more predictable and straightforward, and avoids special (often expensive) adaptive behavior being triggered automatically/enexpectedly by use of multi-controlled gates. Other libraries still use the existing `AND` with it's alternate approach, such as the arithmetic libraries, which keeps the behavior and resource estimates of those more advanced programs largely the same.
1 parent 4d196c1 commit ee0fc7f

File tree

5 files changed

+126
-281
lines changed

5 files changed

+126
-281
lines changed

library/std/src/Std/InternalHelpers.qs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,21 @@ internal operation EntangleForJointMeasure(basis : Pauli, aux : Qubit, qubit : Q
109109
internal operation CollectControls(ctls : Qubit[], aux : Qubit[], adjustment : Int) : Unit is Adj {
110110
// First collect the controls into the first part of the auxiliary list.
111111
for i in 0..2..(Length(ctls) - 2) {
112-
AND(ctls[i], ctls[i + 1], aux[i / 2]);
112+
CCNOT(ctls[i], ctls[i + 1], aux[i / 2]);
113113
}
114114
// Then collect the auxiliary qubits in the first part of the list forward into the last
115115
// qubit of the auxiliary list. The adjustment is used to allow the caller to reduce or increase
116116
// the number of times this is run based on the eventual number of control qubits needed.
117117
for i in 0..((Length(ctls) / 2) - 2 - adjustment) {
118-
AND(aux[i * 2], aux[(i * 2) + 1], aux[i + Length(ctls) / 2]);
118+
CCNOT(aux[i * 2], aux[(i * 2) + 1], aux[i + Length(ctls) / 2]);
119119
}
120120
}
121121

122122
/// When collecting controls, if there is an uneven number of original control qubits then the
123123
/// last control and the second to last auxiliary will be collected into the last auxiliary.
124124
internal operation AdjustForSingleControl(ctls : Qubit[], aux : Qubit[]) : Unit is Adj {
125125
if Length(ctls) % 2 != 0 {
126-
AND(ctls[Length(ctls) - 1], aux[Length(ctls) - 3], aux[Length(ctls) - 2]);
126+
CCNOT(ctls[Length(ctls) - 1], aux[Length(ctls) - 3], aux[Length(ctls) - 2]);
127127
}
128128
}
129129

0 commit comments

Comments
 (0)