From e0c1bed4d0490a31dbac4400a4d6fb51c4632c7b Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Mon, 1 Jun 2020 16:54:29 -0400 Subject: [PATCH 1/7] Change to allow relese of qubit if measured --- src/Simulation/Core/Qubit.cs | 2 ++ .../Circuits/CoreOperations.qs | 18 +++++++--- .../QuantumSimulatorTests/QubitReleaseTest.cs | 34 +++++++++++++++++++ .../Simulators.Tests/ToffoliSimulatorTests.cs | 4 +-- .../Simulators/QuantumSimulator/M.cs | 4 ++- .../Simulators/QuantumSimulator/Measure.cs | 6 ++-- .../QuantumSimulator/QuantumSimulator.cs | 5 +++ .../QuantumSimulator/QubitManager.cs | 4 ++- 8 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs diff --git a/src/Simulation/Core/Qubit.cs b/src/Simulation/Core/Qubit.cs index 61f912fd5b6..ec1e0d40125 100644 --- a/src/Simulation/Core/Qubit.cs +++ b/src/Simulation/Core/Qubit.cs @@ -32,6 +32,8 @@ public Qubit(int id) this.Id = id; } + public bool IsMeasured { get; set; } = false; + public int Id { get; private set; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] diff --git a/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs b/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs index 78e9e2fc0af..af6587c40eb 100644 --- a/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs +++ b/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs @@ -540,7 +540,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { return Foo(3); } - operation ToffoliUsingQubitCheck () : Unit + operation UsingQubitCheck () : Unit { using (q = Qubit()) { @@ -549,15 +549,25 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { } } - operation ToffoliBorrowingQubitCheck () : Unit + operation UsingMeasuredQubitCheck () : Unit { using (q = Qubit()) { - ToffoliBorrower(); + X(q); + let r = M(q); + // Should not raise an exception + } + } + + operation BorrowingQubitCheck () : Unit + { + using (q = Qubit()) + { + QubitBorrower(); } } - operation ToffoliBorrower() : Unit + operation QubitBorrower() : Unit { borrowing (q = Qubit()) { diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs new file mode 100644 index 00000000000..c003960a97c --- /dev/null +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators.Exceptions; +using Microsoft.Quantum.Simulation.Simulators.Tests.Circuits; +using Xunit; + +namespace Microsoft.Quantum.Simulation.Simulators.Tests +{ + public partial class QuantumSimulatorTests + { + [Fact] + public async Task ZeroStateQubitReleaseTest() + { + var sim = new QuantumSimulator(); + + await Assert.ThrowsAsync(() => UsingQubitCheck.Run(sim)); + } + + [Fact] + public async Task MeasuredQubitReleaseTest() + { + var sim = new QuantumSimulator(); + + //should not throw an exception + await UsingMeasuredQubitCheck.Run(sim); + } + } +} diff --git a/src/Simulation/Simulators.Tests/ToffoliSimulatorTests.cs b/src/Simulation/Simulators.Tests/ToffoliSimulatorTests.cs index a3638cb332a..9e805f8d22c 100644 --- a/src/Simulation/Simulators.Tests/ToffoliSimulatorTests.cs +++ b/src/Simulation/Simulators.Tests/ToffoliSimulatorTests.cs @@ -156,7 +156,7 @@ public async Task ToffoliUsingCheck() { var sim = new ToffoliSimulator(); - await Assert.ThrowsAsync(() => ToffoliUsingQubitCheck.Run(sim)); + await Assert.ThrowsAsync(() => UsingQubitCheck.Run(sim)); } [Fact] @@ -164,7 +164,7 @@ public async Task ToffoliBorrowingCheck() { var sim = new ToffoliSimulator(); - await Assert.ThrowsAsync(() => ToffoliBorrowingQubitCheck.Run(sim)); + await Assert.ThrowsAsync(() => BorrowingQubitCheck.Run(sim)); } [Fact] diff --git a/src/Simulation/Simulators/QuantumSimulator/M.cs b/src/Simulation/Simulators/QuantumSimulator/M.cs index 3ea3717fd63..55a896f03a9 100644 --- a/src/Simulation/Simulators/QuantumSimulator/M.cs +++ b/src/Simulation/Simulators/QuantumSimulator/M.cs @@ -27,7 +27,9 @@ public QSimM(QuantumSimulator m) : base(m) public override Func Body => (q) => { Simulator.CheckQubit(q); - + q.IsMeasured = true; + //MeasurableQubit qubit = (MeasurableQubit)q; + //qubit.IsMeasured = true; return M(Simulator.Id, (uint)q.Id).ToResult(); }; } diff --git a/src/Simulation/Simulators/QuantumSimulator/Measure.cs b/src/Simulation/Simulators/QuantumSimulator/Measure.cs index 853b61ac8a5..11aa6916976 100644 --- a/src/Simulation/Simulators/QuantumSimulator/Measure.cs +++ b/src/Simulation/Simulators/QuantumSimulator/Measure.cs @@ -27,12 +27,14 @@ public QSimMeasure(QuantumSimulator m) : base(m) var (paulis, qubits) = _args; Simulator.CheckQubits(qubits); - if (paulis.Length != qubits.Length) { throw new InvalidOperationException($"Both input arrays for {this.GetType().Name} (paulis,qubits), must be of same size"); } - + foreach (Qubit q in qubits) + { + q.IsMeasured = true; + } return Measure(Simulator.Id, (uint)paulis.Length, paulis.ToArray(), qubits.GetIds()).ToResult(); }; } diff --git a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs index 478f511b756..100f049ee65 100644 --- a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs +++ b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs @@ -93,6 +93,7 @@ static void CheckAngle(double angle) void CheckQubit(Qubit q1) { if (q1 == null) throw new ArgumentNullException(nameof(q1), "Trying to perform a primitive operation on a null Qubit"); + q1.IsMeasured = false; } /// @@ -105,12 +106,14 @@ bool[] CheckQubits(IQArray ctrls, Qubit q1) bool[] used = new bool[((QSimQubitManager)QubitManager).MaxId]; CheckQubitInUse(q1, used); + q1.IsMeasured = false; if (ctrls != null && ctrls.Length > 0) { foreach (var q in ctrls) { CheckQubitInUse(q, used); + q.IsMeasured = false; } } @@ -133,6 +136,7 @@ bool[] CheckQubits(IQArray targets) foreach (var q in targets) { CheckQubitInUse(q, used); + q.IsMeasured = false; } return used; @@ -152,6 +156,7 @@ bool[] CheckQubits(IQArray ctrls, IQArray targets) foreach (var q in ctrls) { CheckQubitInUse(q, used); + q.IsMeasured = false; } } diff --git a/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs b/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs index 58ff574fc34..2d592d93d5a 100644 --- a/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs +++ b/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs @@ -64,12 +64,14 @@ protected override void ReleaseOneQubit(Qubit qubit, bool usedOnlyForBorrowing) if (qubit != null) { bool areAllReleasedQubitsZero = ReleaseOne(this.SimulatorId, (uint)qubit.Id); - if (!areAllReleasedQubitsZero && throwOnReleasingQubitsNotInZeroState) + bool isQubitMeasured = qubit.IsMeasured; + if (!(areAllReleasedQubitsZero || isQubitMeasured) && throwOnReleasingQubitsNotInZeroState) { throw new ReleasedQubitsAreNotInZeroState(); } } } } + } } From 205a3868853fa0840d50211be48fabfd11028370 Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Mon, 1 Jun 2020 17:23:26 -0400 Subject: [PATCH 2/7] added comments to change to allow relese of qubit if measured --- .../QuantumSimulatorTests/QubitReleaseTest.cs | 2 ++ src/Simulation/Simulators/QuantumSimulator/M.cs | 3 +-- src/Simulation/Simulators/QuantumSimulator/Measure.cs | 1 + .../Simulators/QuantumSimulator/QuantumSimulator.cs | 4 ++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs index c003960a97c..ebf4d6c3cc7 100644 --- a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs @@ -14,6 +14,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests { public partial class QuantumSimulatorTests { + //test to check that qubit cannot be released if it is not in zero state [Fact] public async Task ZeroStateQubitReleaseTest() { @@ -22,6 +23,7 @@ public async Task ZeroStateQubitReleaseTest() await Assert.ThrowsAsync(() => UsingQubitCheck.Run(sim)); } + //test to check that qubit can be released if measured [Fact] public async Task MeasuredQubitReleaseTest() { diff --git a/src/Simulation/Simulators/QuantumSimulator/M.cs b/src/Simulation/Simulators/QuantumSimulator/M.cs index 55a896f03a9..6f2766ea333 100644 --- a/src/Simulation/Simulators/QuantumSimulator/M.cs +++ b/src/Simulation/Simulators/QuantumSimulator/M.cs @@ -27,9 +27,8 @@ public QSimM(QuantumSimulator m) : base(m) public override Func Body => (q) => { Simulator.CheckQubit(q); + //setting qubit as measured to allow for release q.IsMeasured = true; - //MeasurableQubit qubit = (MeasurableQubit)q; - //qubit.IsMeasured = true; return M(Simulator.Id, (uint)q.Id).ToResult(); }; } diff --git a/src/Simulation/Simulators/QuantumSimulator/Measure.cs b/src/Simulation/Simulators/QuantumSimulator/Measure.cs index 11aa6916976..40661c9b4d9 100644 --- a/src/Simulation/Simulators/QuantumSimulator/Measure.cs +++ b/src/Simulation/Simulators/QuantumSimulator/Measure.cs @@ -33,6 +33,7 @@ public QSimMeasure(QuantumSimulator m) : base(m) } foreach (Qubit q in qubits) { + //setting qubit as measured to allow for release q.IsMeasured = true; } return Measure(Simulator.Id, (uint)paulis.Length, paulis.ToArray(), qubits.GetIds()).ToResult(); diff --git a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs index 100f049ee65..a990e75c247 100644 --- a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs +++ b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs @@ -93,6 +93,7 @@ static void CheckAngle(double angle) void CheckQubit(Qubit q1) { if (q1 == null) throw new ArgumentNullException(nameof(q1), "Trying to perform a primitive operation on a null Qubit"); + //setting qubit as not measured to not allow release in case of gate operation on qubit q1.IsMeasured = false; } @@ -113,6 +114,7 @@ bool[] CheckQubits(IQArray ctrls, Qubit q1) foreach (var q in ctrls) { CheckQubitInUse(q, used); + //setting qubit as not measured to not allow release in case of gate operation on qubit q.IsMeasured = false; } } @@ -136,6 +138,7 @@ bool[] CheckQubits(IQArray targets) foreach (var q in targets) { CheckQubitInUse(q, used); + //setting qubit as not measured to not allow release in case of gate operation on qubit q.IsMeasured = false; } @@ -156,6 +159,7 @@ bool[] CheckQubits(IQArray ctrls, IQArray targets) foreach (var q in ctrls) { CheckQubitInUse(q, used); + //setting qubit as not measured to not allow release in case of gate operation on qubit q.IsMeasured = false; } } From 2dd367242b905cb20dfca30430a237c74a37f6f2 Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Mon, 8 Jun 2020 21:02:34 -0400 Subject: [PATCH 3/7] Changes to reflect PR review --- .../Simulators/QuantumSimulator/Assert.cs | 2 +- .../Simulators/QuantumSimulator/AssertProb.cs | 2 +- .../Simulators/QuantumSimulator/Dump.cs | 2 +- .../QuantumSimulator/QuantumSimulator.cs | 21 +++++++++++++++++++ .../QuantumSimulator/QubitManager.cs | 5 ++--- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Simulation/Simulators/QuantumSimulator/Assert.cs b/src/Simulation/Simulators/QuantumSimulator/Assert.cs index 50f198d01c7..d0936509470 100644 --- a/src/Simulation/Simulators/QuantumSimulator/Assert.cs +++ b/src/Simulation/Simulators/QuantumSimulator/Assert.cs @@ -28,7 +28,7 @@ public QSimAssert(QuantumSimulator m) : base(m) { var (paulis, qubits, result, msg) = _args; - this.Simulator.CheckQubits(qubits); + this.Simulator.CheckAndPreserveQubits(qubits); if (paulis.Length != qubits.Length) { diff --git a/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs b/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs index cec9be07f3a..8f93eea3b31 100644 --- a/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs +++ b/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs @@ -29,7 +29,7 @@ public QSimAssertProb(QuantumSimulator m) : base(m) { var (paulis, qubits, result, expectedPr, msg, tol) = _args; - Simulator.CheckQubits(qubits); + Simulator.CheckAndPreserveQubits(qubits); if (paulis.Length != qubits.Length) { diff --git a/src/Simulation/Simulators/QuantumSimulator/Dump.cs b/src/Simulation/Simulators/QuantumSimulator/Dump.cs index ce83a813525..5845114baf4 100644 --- a/src/Simulation/Simulators/QuantumSimulator/Dump.cs +++ b/src/Simulation/Simulators/QuantumSimulator/Dump.cs @@ -96,7 +96,7 @@ public QSimDumpRegister(QuantumSimulator m) : base(m) var (location, qubits) = __in; if (location == null) { throw new ArgumentNullException(nameof(location)); } - Simulator.CheckQubits(qubits); + Simulator.CheckAndPreserveQubits(qubits); return Simulator.Dump(location, qubits); }; diff --git a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs index a990e75c247..ec0a161310e 100644 --- a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs +++ b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs @@ -145,6 +145,27 @@ bool[] CheckQubits(IQArray targets) return used; } + /// + /// Intended to be used with simulator functions like Dump, Assert, AssertProb + /// Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that + /// - none of the qubits are null + /// - there are no duplicated qubits + /// + bool[] CheckAndPreserveQubits(IQArray targets) + { + if (targets == null) throw new ArgumentNullException(nameof(targets), "Trying to perform an intrinsic operation on a null Qubit array."); + if (targets.Length == 0) throw new ArgumentNullException(nameof(targets), "Trying to perform an intrinsic operation on an empty Qubit array."); + + bool[] used = new bool[((QSimQubitManager)QubitManager).MaxId]; + + foreach (var q in targets) + { + CheckQubitInUse(q, used); + } + + return used; + } + /// /// Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that /// - none of the qubits are null diff --git a/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs b/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs index 2d592d93d5a..7b45f3f9ba4 100644 --- a/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs +++ b/src/Simulation/Simulators/QuantumSimulator/QubitManager.cs @@ -63,9 +63,8 @@ protected override void ReleaseOneQubit(Qubit qubit, bool usedOnlyForBorrowing) base.ReleaseOneQubit(qubit, usedOnlyForBorrowing); if (qubit != null) { - bool areAllReleasedQubitsZero = ReleaseOne(this.SimulatorId, (uint)qubit.Id); - bool isQubitMeasured = qubit.IsMeasured; - if (!(areAllReleasedQubitsZero || isQubitMeasured) && throwOnReleasingQubitsNotInZeroState) + bool isReleasedQubitZero = ReleaseOne(this.SimulatorId, (uint)qubit.Id); + if (!(isReleasedQubitZero || qubit.IsMeasured) && throwOnReleasingQubitsNotInZeroState) { throw new ReleasedQubitsAreNotInZeroState(); } From 2cf468a933908cf31a1318091872f66ea51be389 Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Mon, 8 Jun 2020 21:05:05 -0400 Subject: [PATCH 4/7] Changes to add documentation as per PR review --- .../Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs index ebf4d6c3cc7..288b82e2c73 100644 --- a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs @@ -29,7 +29,7 @@ public async Task MeasuredQubitReleaseTest() { var sim = new QuantumSimulator(); - //should not throw an exception + //should not throw an exception, as Measured qubits are allowed to be released, and the release aspect is handled in the C++ code await UsingMeasuredQubitCheck.Run(sim); } } From 806a638177571aaa9c9c0b041dedf4b16f248196 Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Tue, 9 Jun 2020 10:44:02 -0400 Subject: [PATCH 5/7] Test renamed to reflect PR review --- src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs | 2 +- .../Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs b/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs index af6587c40eb..75898a27657 100644 --- a/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs +++ b/src/Simulation/Simulators.Tests/Circuits/CoreOperations.qs @@ -549,7 +549,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { } } - operation UsingMeasuredQubitCheck () : Unit + operation ReleaseMeasuredQubitCheck () : Unit { using (q = Qubit()) { diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs index 288b82e2c73..543b8ec69bf 100644 --- a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs @@ -30,7 +30,7 @@ public async Task MeasuredQubitReleaseTest() var sim = new QuantumSimulator(); //should not throw an exception, as Measured qubits are allowed to be released, and the release aspect is handled in the C++ code - await UsingMeasuredQubitCheck.Run(sim); + await ReleaseMeasuredQubitCheck.Run(sim); } } } From 90aa8c9556136e32fd918f07e5c5d76e2d426dbc Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Mon, 15 Jun 2020 21:53:47 -0400 Subject: [PATCH 6/7] Updated summary of CheckQubit functions to reflect change in isMeasured flag --- .../Simulators/QuantumSimulator/QuantumSimulator.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs index ec0a161310e..e073a4ac39b 100644 --- a/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs +++ b/src/Simulation/Simulators/QuantumSimulator/QuantumSimulator.cs @@ -89,6 +89,7 @@ static void CheckAngle(double angle) /// /// Makes sure the target qubit of an operation is valid. In particular it checks that the qubit instance is not null. + /// Also sets the isMeasured flag to false for each qubit /// void CheckQubit(Qubit q1) { @@ -101,6 +102,7 @@ void CheckQubit(Qubit q1) /// Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that /// - none of the qubits are null /// - there are no duplicated qubits + /// Also sets the isMeasured flag to false for each qubit /// bool[] CheckQubits(IQArray ctrls, Qubit q1) { @@ -127,6 +129,7 @@ bool[] CheckQubits(IQArray ctrls, Qubit q1) /// Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that /// - none of the qubits are null /// - there are no duplicated qubits + /// Also sets the isMeasured flag to false for each qubit /// bool[] CheckQubits(IQArray targets) { @@ -170,6 +173,7 @@ bool[] CheckAndPreserveQubits(IQArray targets) /// Makes sure all qubits are valid as parameter of an intrinsic quantum operation. In particular it checks that /// - none of the qubits are null /// - there are no duplicated qubits + /// Also sets the isMeasured flag to false for each qubit /// bool[] CheckQubits(IQArray ctrls, IQArray targets) { From fe2a1aa710f906b6e48c0dd737f6fcfeb59b0d5c Mon Sep 17 00:00:00 2001 From: Aniket Dalvi Date: Wed, 17 Jun 2020 14:21:46 -0400 Subject: [PATCH 7/7] Added test for checking state of reallocated qubit --- .../QuantumSimulatorTests/QubitReleaseTest.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs index 543b8ec69bf..a267a719274 100644 --- a/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs +++ b/src/Simulation/Simulators.Tests/QuantumSimulatorTests/QubitReleaseTest.cs @@ -32,5 +32,33 @@ public async Task MeasuredQubitReleaseTest() //should not throw an exception, as Measured qubits are allowed to be released, and the release aspect is handled in the C++ code await ReleaseMeasuredQubitCheck.Run(sim); } + + //test to check that qubit that is released and reallocated is in state |0> + [Fact] + public async Task ReallocateQubitInGroundStateTest() + { + var sim = new QuantumSimulator(); + var allocate = sim.Get(); + var release = sim.Get(); + var q1 = allocate.Apply(1); + var q1Id = q1[0].Id; + var gate = sim.Get(); + var measure = sim.Get(); + gate.Apply(q1[0]); + var result1 = measure.Apply(q1[0]); + //Check X operation + Assert.Equal(result1, Result.One); + release.Apply(q1[0]); + var q2 = allocate.Apply(1); + var q2Id = q2[0].Id; + //Assert reallocated qubit has the same id as the one released + Assert.Equal(q1Id, q2Id); + var result2 = measure.Apply(q2[0]); + //Assert reallocated qubit has is initialized in state |0> + Assert.Equal(result2, Result.Zero); + + + + } } }