From 12764a466b3bd51726b8aa0fe15343dbcdc6a2e8 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Thu, 30 Sep 2021 12:47:30 -0700 Subject: [PATCH 1/2] Simply Controlled Paulis in Target Packages This simplifies the use of controlled Pauli gates to allow for programs that make use of singly controlled gates (or CCNOT) to have reasonable decompositoins without incurring array creation or using the controlled specialization. This leads to better compatibility with the draft spec for the QIR base profile. --- .../Decompositions/CCNOTFromCCZ.qs | 2 +- .../TargetDefinitions/Decompositions/CX.qs | 39 +++++++++++++++ .../Decompositions/CYFromCNOT.qs | 43 +++++++++++++++++ .../Decompositions/CZFromSinglyControlled.qs | 47 +++++++++++++++++++ .../TargetDefinitions/Decompositions/Utils.qs | 17 +++++++ .../Decompositions/YFromSinglyControlled.qs | 10 ++-- .../Decompositions/ZFromSinglyControlled.qs | 16 +------ .../TargetPackages/Type1.Package.props | 3 ++ .../TargetPackages/Type3.Package.props | 3 ++ 9 files changed, 158 insertions(+), 22 deletions(-) create mode 100644 src/Simulation/TargetDefinitions/Decompositions/CX.qs create mode 100644 src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs create mode 100644 src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs diff --git a/src/Simulation/TargetDefinitions/Decompositions/CCNOTFromCCZ.qs b/src/Simulation/TargetDefinitions/Decompositions/CCNOTFromCCZ.qs index fcc55c6aaa6..f9082d9e2ee 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/CCNOTFromCCZ.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/CCNOTFromCCZ.qs @@ -26,7 +26,7 @@ namespace Microsoft.Quantum.Intrinsic { H(target); } apply { - Controlled Z([control1, control2], target); + CCZ(control1, control2, target); } } controlled (ctls, ...) { diff --git a/src/Simulation/TargetDefinitions/Decompositions/CX.qs b/src/Simulation/TargetDefinitions/Decompositions/CX.qs new file mode 100644 index 00000000000..6ae090ad7ac --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/CX.qs @@ -0,0 +1,39 @@ +namespace Microsoft.Quantum.Canon { + open Microsoft.Quantum.Intrinsic; + + /// # Summary + /// Applies the controlled-X (CX) gate to a pair of qubits. + /// + /// # Description + /// This operation can be simulated by the unitary matrix + /// $$ + /// \begin{align} + /// \left(\begin{matrix} + /// 1 & 0 & 0 & 0 \\\\ + /// 0 & 1 & 0 & 0 \\\\ + /// 0 & 0 & 0 & 1 \\\\ + /// 0 & 0 & 1 & 0 + /// \end{matrix}\right) + /// \end{align}, + /// $$ + /// where rows and columns are organized as in the quantum concepts guide. + /// + /// # Input + /// ## control + /// Control qubit for the CX gate. + /// ## target + /// Target qubit for the CX gate. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// Controlled X([control], target); + /// ``` + /// and to: + /// ```qsharp + /// CNOT(control, target); + /// ``` + operation CX(control : Qubit, target : Qubit) : Unit is Adj + Ctl{ + CNOT(control, target); + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs b/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs new file mode 100644 index 00000000000..5c8a71a2923 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs @@ -0,0 +1,43 @@ +namespace Microsoft.Quantum.Canon { + open Microsoft.Quantum.Intrinsic; + + /// # Summary + /// Applies the controlled-Y (CY) gate to a pair of qubits. + /// + /// # Description + /// This operation can be simulated by the unitary matrix + /// $$ + /// \begin{align} + /// 1 & 0 & 0 & 0 \\\\ + /// 0 & 1 & 0 & 0 \\\\ + /// 0 & 0 & 0 & -i \\\\ + /// 0 & 0 & i & 0 + /// \end{align}, + /// $$ + /// where rows and columns are organized as in the quantum concepts guide. + /// + /// # Input + /// ## control + /// Control qubit for the CY gate. + /// ## target + /// Target qubit for the CY gate. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// Controlled Y([control], target); + /// ``` + operation CY(control : Qubit, target : Qubit) : Unit { + body (...) { + within { + MapPauli(target, PauliX, PauliY); + } + apply { + CNOT(control, target); + } + } + adjoint self; + controlled distribute; + controlled adjoint self; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs b/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs new file mode 100644 index 00000000000..09065597839 --- /dev/null +++ b/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs @@ -0,0 +1,47 @@ +namespace Microsoft.Quantum.Canon { + open Microsoft.Quantum.Intrinsic; + + /// # Summary + /// Applies the controlled-Z (CZ) gate to a pair of qubits. + /// + /// # Description + /// This operation can be simulated by the unitary matrix + /// $$ + /// \begin{align} + /// 1 & 0 & 0 & 0 \\\\ + /// 0 & 1 & 0 & 0 \\\\ + /// 0 & 0 & 1 & 0 \\\\ + /// 0 & 0 & 0 & -1 + /// \end{align}, + /// $$ + /// where rows and columns are organized as in the quantum concepts guide. + /// + /// # Input + /// ## control + /// Control qubit for the CZ gate. + /// ## target + /// Target qubit for the CZ gate. + /// + /// # Remarks + /// Equivalent to: + /// ```qsharp + /// Controlled Z([control], target); + /// ``` + operation CZ(control : Qubit, target : Qubit) : Unit { + body (...) { + ApplyControlledZ(control, target); + } + controlled (ctls, ...) { + if (Length(ctls) == 0) { + ApplyControlledZ(control, target); + } + elif (Length(ctls) == 1) { + CCZ(ctls[0], control, target); + } + else { + ApplyWithLessControlsA(Controlled CZ, (ctls, (control, target))); + } + } + adjoint self; + } +} \ No newline at end of file diff --git a/src/Simulation/TargetDefinitions/Decompositions/Utils.qs b/src/Simulation/TargetDefinitions/Decompositions/Utils.qs index 32c31472a42..3275be341a0 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/Utils.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/Utils.qs @@ -99,6 +99,23 @@ namespace Microsoft.Quantum.Intrinsic { H(target); } + internal operation CCZ (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj { + // [Page 15 of arXiv:1206.0758v3](https://arxiv.org/pdf/1206.0758v3.pdf#page=15) + Adjoint T(control1); + Adjoint T(control2); + CNOT(target, control1); + T(control1); + CNOT(control2, target); + CNOT(control2, control1); + T(target); + Adjoint T(control1); + CNOT(control2, target); + CNOT(target, control1); + Adjoint T(target); + T(control1); + CNOT(control2, control1); + } + internal function ReducedDyadicFraction (numerator : Int, denominatorPowerOfTwo : Int) : (Int, Int) { if (numerator == 0) { return (0,0); } mutable num = numerator; diff --git a/src/Simulation/TargetDefinitions/Decompositions/YFromSinglyControlled.qs b/src/Simulation/TargetDefinitions/Decompositions/YFromSinglyControlled.qs index 71499ff03ac..95e0cb96740 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/YFromSinglyControlled.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/YFromSinglyControlled.qs @@ -2,6 +2,7 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Canon; /// # Summary /// Applies the Pauli $Y$ gate. @@ -27,19 +28,14 @@ namespace Microsoft.Quantum.Intrinsic { ApplyUncontrolledY(qubit); } elif (Length(ctls) == 1) { - within { - MapPauli(qubit, PauliX, PauliY); - } - apply { - CNOT(ctls[0], qubit); - } + CY(ctls[0], qubit); } elif (Length(ctls) == 2) { within { MapPauli(qubit, PauliZ, PauliY); } apply { - Controlled Z(ctls, qubit); + CCZ(ctls[0], ctls[1], qubit); } } else { diff --git a/src/Simulation/TargetDefinitions/Decompositions/ZFromSinglyControlled.qs b/src/Simulation/TargetDefinitions/Decompositions/ZFromSinglyControlled.qs index 7072a4f17c9..52b8f7d7b00 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/ZFromSinglyControlled.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/ZFromSinglyControlled.qs @@ -2,6 +2,7 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { + open Microsoft.Quantum.Canon; /// # Summary /// Applies the Pauli $Z$ gate. @@ -30,20 +31,7 @@ namespace Microsoft.Quantum.Intrinsic { ApplyControlledZ(ctls[0], qubit); } elif (Length(ctls) == 2) { - // [Page 15 of arXiv:1206.0758v3](https://arxiv.org/pdf/1206.0758v3.pdf#page=15) - Adjoint T(ctls[0]); - Adjoint T(ctls[1]); - CNOT(qubit, ctls[0]); - T(ctls[0]); - CNOT(ctls[1], qubit); - CNOT(ctls[1], ctls[0]); - T(qubit); - Adjoint T(ctls[0]); - CNOT(ctls[1], qubit); - CNOT(qubit, ctls[0]); - Adjoint T(qubit); - T(ctls[0]); - CNOT(ctls[1], ctls[0]); + CCZ(ctls[0], ctls[1], qubit); } else { ApplyWithLessControlsA(Controlled Z, (ctls, qubit)); diff --git a/src/Simulation/TargetDefinitions/TargetPackages/Type1.Package.props b/src/Simulation/TargetDefinitions/TargetPackages/Type1.Package.props index 866fd1f0391..a66eb655be5 100644 --- a/src/Simulation/TargetDefinitions/TargetPackages/Type1.Package.props +++ b/src/Simulation/TargetDefinitions/TargetPackages/Type1.Package.props @@ -26,6 +26,9 @@ + + + diff --git a/src/Simulation/TargetDefinitions/TargetPackages/Type3.Package.props b/src/Simulation/TargetDefinitions/TargetPackages/Type3.Package.props index b0d5d34c908..3dd8eee8145 100644 --- a/src/Simulation/TargetDefinitions/TargetPackages/Type3.Package.props +++ b/src/Simulation/TargetDefinitions/TargetPackages/Type3.Package.props @@ -27,6 +27,9 @@ + + + From cdc49303a6609c479d3db3219744bba225b0d0bf Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Thu, 30 Sep 2021 13:04:17 -0700 Subject: [PATCH 2/2] Updates for PR feedback --- src/Simulation/TargetDefinitions/Decompositions/CX.qs | 3 +++ .../TargetDefinitions/Decompositions/CYFromCNOT.qs | 3 +++ .../Decompositions/CZFromSinglyControlled.qs | 7 +++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Simulation/TargetDefinitions/Decompositions/CX.qs b/src/Simulation/TargetDefinitions/Decompositions/CX.qs index 6ae090ad7ac..f212bb3eced 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/CX.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/CX.qs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Intrinsic; diff --git a/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs b/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs index 5c8a71a2923..364b4d2c573 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/CYFromCNOT.qs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Intrinsic; diff --git a/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs b/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs index 09065597839..80d6000368e 100644 --- a/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs +++ b/src/Simulation/TargetDefinitions/Decompositions/CZFromSinglyControlled.qs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Intrinsic; @@ -32,10 +35,10 @@ namespace Microsoft.Quantum.Canon { ApplyControlledZ(control, target); } controlled (ctls, ...) { - if (Length(ctls) == 0) { + if Length(ctls) == 0 { ApplyControlledZ(control, target); } - elif (Length(ctls) == 1) { + elif Length(ctls) == 1 { CCZ(ctls[0], control, target); } else {