From 2969ad397aeee0a533869b2285b1ae80f8671794 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Thu, 25 Feb 2021 14:26:50 -0800 Subject: [PATCH 1/3] Added PauliArrayAsInt() and tests. --- .../test/QIR-static/qir-test-other.cpp | 15 ++++++++++- .../test/QIR-static/qsharp/qir-test-arrays.qs | 2 ++ .../test/QIR-static/qsharp/qir-test-other.qs | 25 +++++++++++++++++-- .../QSharpFoundation/Convert/Convert.qs | 19 ++++++++++++-- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/QirRuntime/test/QIR-static/qir-test-other.cpp b/src/QirRuntime/test/QIR-static/qir-test-other.cpp index 41bd6b4b530..d77225ed86d 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-other.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-other.cpp @@ -3,7 +3,20 @@ #include "catch.hpp" -extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Other__ParityTest__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Other__ParityTest__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Other__PauliArrayAsIntTest__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Other__PauliArrayAsIntFailTest__body(); // NOLINT + +TEST_CASE("QIR: Other.PauliArrayAsIntFail", "[qir.Other][qir.Other.PauliArrayAsIntFail]") +{ + REQUIRE_THROWS(Microsoft__Quantum__Testing__QIR__Other__PauliArrayAsIntFailTest__body()); +} + +TEST_CASE("QIR: Other.PauliArrayAsInt", "[qir.Other][qir.Other.PauliArrayAsInt]") +{ + REQUIRE(0 == Microsoft__Quantum__Testing__QIR__Other__PauliArrayAsIntTest__body()); +} + TEST_CASE("QIR: Other.Parity", "[qir.Other][qir.Other.Parity]") { diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs index 195e9905ec1..efe2e706db7 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs @@ -55,6 +55,8 @@ namespace Microsoft.Quantum.Testing.QIR { let res17 = ArcCosTest(); let res18 = ArcTanTest(); let res19 = ParityTest(); + let res20 = PauliArrayAsIntTest(); + let res21 = PauliArrayAsIntFailTest(); MessageTest("Test"); // Conditionals: diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs index efb30081098..e30e839ff09 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs @@ -4,10 +4,32 @@ namespace Microsoft.Quantum.Testing.QIR.Other { open Microsoft.Quantum.Bitwise; + open Microsoft.Quantum.Convert; + + function PauliArrayAsIntTest() : Int { + if 0 != PauliArrayAsInt([PauliI]) { return 1; } // The return value indicates which test case has failed. + if 1 != PauliArrayAsInt([PauliX]) { return 2; } + if 3 != PauliArrayAsInt([PauliY]) { return 3; } + if 2 != PauliArrayAsInt([PauliZ]) { return 4; } + + if 0x2310 != PauliArrayAsInt( + [PauliI, PauliI, PauliX, PauliI, PauliY, PauliI, PauliZ, PauliI]) { return 5; } + + // The Pauli array items are default-initialized to PauliI. + if 0 != PauliArrayAsInt(new Pauli[31]) { return 6; } + + if 0x3000000000000000 != PauliArrayAsInt(new Pauli[31] w/ 30 <- PauliY) { return 7; } + + return 0; + } + + function PauliArrayAsIntFailTest() : Int { + return PauliArrayAsInt(new Pauli[32]); // Must fail/throw. + } function ParityTest() : Int { //function Parity (a : Int) : Int - if 0 != Parity(0) { return 1; } + if 0 != Parity(0) { return 1; } // The return value indicates which test case has failed. if 1 != Parity(1) { return 2; } if 1 != Parity(2) { return 3; } if 0 != Parity(3) { return 4; } @@ -23,5 +45,4 @@ namespace Microsoft.Quantum.Testing.QIR.Other { return 0; } - } diff --git a/src/Simulation/QSharpFoundation/Convert/Convert.qs b/src/Simulation/QSharpFoundation/Convert/Convert.qs index 2a7451174fc..9fb543b4f03 100644 --- a/src/Simulation/QSharpFoundation/Convert/Convert.qs +++ b/src/Simulation/QSharpFoundation/Convert/Convert.qs @@ -154,7 +154,7 @@ namespace Microsoft.Quantum.Convert { /// Each Pauli operator can be encoded using two bits: /// $$ /// \begin{align} - /// \boldone \mapsto 00, \quad X \mapsto 01, \quad Y \mapsto 11, + /// \quad I \mapsto 00, \quad X \mapsto 01, \quad Y \mapsto 11, /// \quad Z \mapsto 10. /// \end{align} /// $$ @@ -164,7 +164,22 @@ namespace Microsoft.Quantum.Convert { /// the mappings of each Pauli operator in big-endian order /// `bits(Pn) ... bits(P0)`. function PauliArrayAsInt(paulis : Pauli[]) : Int { - body intrinsic; + let len = Length(paulis); + if len > 31 { + fail $"Cannot pack bits of Pauli array longer than 31 (got {len})."; + } + + mutable result = 0; + for index in (len-1)..-1..0 { + let p = paulis[index]; + set result <<<= 2; + if p == PauliI { set result += 0; } + elif p == PauliX { set result += 1; } + elif p == PauliY { set result += 3; } + elif p == PauliZ { set result += 2; } + else { fail $"Unexpected Pauli value {p}."; } + } + return result; } } From e52d61f26a46eff3db3667fc4f1218cf3625a520 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Tue, 2 Mar 2021 17:14:53 -0800 Subject: [PATCH 2/3] CR changes. --- src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs | 2 +- src/Simulation/QSharpFoundation/Convert/Convert.qs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs index e30e839ff09..88150a8da11 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-other.qs @@ -16,7 +16,7 @@ namespace Microsoft.Quantum.Testing.QIR.Other { [PauliI, PauliI, PauliX, PauliI, PauliY, PauliI, PauliZ, PauliI]) { return 5; } // The Pauli array items are default-initialized to PauliI. - if 0 != PauliArrayAsInt(new Pauli[31]) { return 6; } + if 0 != PauliArrayAsInt(new Pauli[31]) { return 6; } // Todo: Replace `new Pauli[31]` with `[PauliI, size=31]` when that is implemented. if 0x3000000000000000 != PauliArrayAsInt(new Pauli[31] w/ 30 <- PauliY) { return 7; } diff --git a/src/Simulation/QSharpFoundation/Convert/Convert.qs b/src/Simulation/QSharpFoundation/Convert/Convert.qs index 9fb543b4f03..fb501496b73 100644 --- a/src/Simulation/QSharpFoundation/Convert/Convert.qs +++ b/src/Simulation/QSharpFoundation/Convert/Convert.qs @@ -154,7 +154,7 @@ namespace Microsoft.Quantum.Convert { /// Each Pauli operator can be encoded using two bits: /// $$ /// \begin{align} - /// \quad I \mapsto 00, \quad X \mapsto 01, \quad Y \mapsto 11, + /// \boldone \mapsto 00, \quad X \mapsto 01, \quad Y \mapsto 11, /// \quad Z \mapsto 10. /// \end{align} /// $$ @@ -170,8 +170,7 @@ namespace Microsoft.Quantum.Convert { } mutable result = 0; - for index in (len-1)..-1..0 { - let p = paulis[index]; + for p in paulis[(len-1)..-1..0] { set result <<<= 2; if p == PauliI { set result += 0; } elif p == PauliX { set result += 1; } From 4a89a6676c0fb765c4838cc1635ea4e2d89c562a Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Tue, 9 Mar 2021 12:09:19 -0800 Subject: [PATCH 3/3] CR changes. --- .../QSharpFoundation/Convert/Convert.cs | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/src/Simulation/QSharpFoundation/Convert/Convert.cs b/src/Simulation/QSharpFoundation/Convert/Convert.cs index a86ac9dfa39..ffcc86d8b55 100644 --- a/src/Simulation/QSharpFoundation/Convert/Convert.cs +++ b/src/Simulation/QSharpFoundation/Convert/Convert.cs @@ -159,42 +159,4 @@ public Native(IOperationFactory m) : base(m) { } } } - public partial class PauliArrayAsInt - { - public class Native : PauliArrayAsInt - { - static long PauliBitsFunc(IQArray pauli) - { - if (pauli.Length > 31) { throw new ExecutionFailException("Cannot pack bits of Pauli array longer than 31"); } - ulong res = 0; - for (long i = pauli.Length - 1; i >= 0; --i) - { - res <<= 2; - if (pauli[i] == Pauli.PauliZ) - { - res |= 2; - } - else if (pauli[i] == Pauli.PauliX) - { - res |= 1; - } - else if (pauli[i] == Pauli.PauliY) - { - res |= 3; - } - else if (pauli[i] == Pauli.PauliI) - { - } - else - { - System.Diagnostics.Debug.Assert(false, "this line should never be reached"); - } - } - return System.Convert.ToInt64(res); - } - - public Native(IOperationFactory m) : base(m) { } - public override Func, long> __Body__ => PauliBitsFunc; - } - } }