示例#1
0
        public override Result Measure(IQArray <Pauli> bases, IQArray <Qubit> qubits)
        {
            if (!bases.TryGetSingleZ(out var idx))
            {
                // throw new UnsupportedOperationException("Not yet implemented.");
                var aux = this.Simulator !.QubitManager?.Allocate();
                if (aux == null)
                {
                    throw new NullReferenceException("Qubit manager was null.");
                }

                try
                {
                    this.WriteToScratch(bases, qubits, aux);
                    return(this.MeasureByIndex(aux.Id));
                }
                finally
                {
                    this.Simulator !.QubitManager?.Release(aux);
                }
            }

            return(this.MeasureByIndex(qubits[idx].Id));
        }
示例#2
0
        public void TestQubitManagerGrowth()
        {
            QubitManager qm = new QubitManager(7, mayExtendCapacity: true, disableBorrowing: false);

            Qubit q1 = qm.Allocate();

            Assert.True(q1.Id == 0);

            IQArray <Qubit> qa1 = qm.Allocate(4);

            Assert.True(qa1.Length == 4);
            Assert.True(qa1[0].Id == 1);
            Assert.True(qa1[1].Id == 2);
            Assert.True(qa1[2].Id == 3);
            Assert.True(qa1[3].Id == 4);

            Qubit q2 = qm.Allocate();

            Assert.True(q2.Id == 5);

            qm.OnOperationStart(null, qa1);

            long qubitsAvailable;

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb1 = qm.Borrow(3);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 1);
            Assert.True(qb1[0].Id == 0);
            Assert.True(qb1[1].Id == 5);
            Assert.True(qb1[2].Id == 6);
            qm.Return(qb1[0]);
            qm.Return(qb1[2]);

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 1);
            IQArray <Qubit> qb2 = qm.Borrow(3); // This should grow qubit capacity

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 6);
            Assert.True(qb2[0].Id == 0);
            Assert.True(qb2[1].Id == 6);
            Assert.True(qb2[2].Id == 7);

            qm.OnOperationEnd(null, null);

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 6);
            IQArray <Qubit> qa2 = qm.Allocate(4);

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 2);
            Assert.True(qa2.Length == 4);
            Assert.True(qa2[0].Id == 8);
            Assert.True(qa2[1].Id == 9);
            Assert.True(qa2[2].Id == 10);
            Assert.True(qa2[3].Id == 11);

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 2);
            qm.Release(qa2[0]);
            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 3);

            IQArray <Qubit> qa3 = qm.Allocate(4); // This should grow qubit capacity

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 13);
            Assert.True(qa3.Length == 4);
            Assert.True(qa3[0].Id == 8);
            Assert.True(qa3[1].Id == 12);
            Assert.True(qa3[2].Id == 13);
            Assert.True(qa3[3].Id == 14);
        }
示例#3
0
        public void TestQubitManagerDisabledBorrowing()
        {
            QubitManager qm = new QubitManager(20, mayExtendCapacity: true, disableBorrowing: true);

            Qubit q1 = qm.Allocate();

            Assert.True(q1.Id == 0);

            IQArray <Qubit> qa1 = qm.Allocate(4);

            Assert.True(qa1.Length == 4);
            Assert.True(qa1[0].Id == 1);
            Assert.True(qa1[1].Id == 2);
            Assert.True(qa1[2].Id == 3);
            Assert.True(qa1[3].Id == 4);

            Qubit q2 = qm.Allocate();

            Assert.True(q2.Id == 5);

            qm.OnOperationStart(null, qa1);

            long qubitsAvailable;

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb1 = qm.Borrow(3);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 3);
            Assert.True(qb1[0].Id == 6);
            Assert.True(qb1[1].Id == 7);
            Assert.True(qb1[2].Id == 8);

            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 11);
            qm.Return(qb1[0]);
            qm.Return(qb1[2]);
            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 13);

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb2 = qm.Borrow(3);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 3);
            Assert.True(qb2[0].Id == 8);
            Assert.True(qb2[1].Id == 6);
            Assert.True(qb2[2].Id == 9);
            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 10);

            {
                qm.OnOperationStart(null, qb2);

                qubitsAvailable = qm.FreeQubitsCount;
                IQArray <Qubit> qb3 = qm.Borrow(3);
                Assert.True(qubitsAvailable - qm.FreeQubitsCount == 3);
                Assert.True(qb3[0].Id == 10);
                Assert.True(qb3[1].Id == 11);
                Assert.True(qb3[2].Id == 12);

                qubitsAvailable = qm.FreeQubitsCount;
                Assert.True(qubitsAvailable == 7);

                qm.OnOperationEnd(null, QVoid.Instance);
            }

            qm.Release(qb2[1]);
            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 8);

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb4 = qm.Borrow(1);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 1);
            Assert.True(qb4[0].Id == 6);
            qubitsAvailable = qm.FreeQubitsCount;
            Assert.True(qubitsAvailable == 7);

            qm.OnOperationEnd(null, QVoid.Instance);
        }
示例#4
0
        public void TestQubitManagerTrackingScope()
        {
            QubitManager qm = new QubitManager(20);

            Qubit q1 = qm.Allocate();

            Assert.True(q1.Id == 0);

            IQArray <Qubit> qa1 = qm.Allocate(4);

            Assert.True(qa1.Length == 4);
            Assert.True(qa1[0].Id == 1);
            Assert.True(qa1[1].Id == 2);
            Assert.True(qa1[2].Id == 3);
            Assert.True(qa1[3].Id == 4);

            Qubit q2 = qm.Allocate();

            Assert.True(q2.Id == 5);

            qm.OnOperationStart(null, qa1);

            long qubitsAvailable;

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb1 = qm.Borrow(3);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 1);
            Assert.True(qb1[0].Id == 0);
            Assert.True(qb1[1].Id == 5);
            Assert.True(qb1[2].Id == 6);
            qm.Return(qb1[0]);
            qm.Return(qb1[2]);

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb2 = qm.Borrow(3);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 2);
            Assert.True(qb2[0].Id == 0);
            Assert.True(qb2[1].Id == 6);
            Assert.True(qb2[2].Id == 7);

            {
                qm.OnOperationStart(null, qb2);

                qubitsAvailable = qm.FreeQubitsCount;
                IQArray <Qubit> qb3 = qm.Borrow(3);
                Assert.True(qubitsAvailable - qm.FreeQubitsCount == 0);
                Assert.True(qb3[0].Id == 1);
                Assert.True(qb3[1].Id == 2);
                Assert.True(qb3[2].Id == 3);

                qm.OnOperationEnd(null, QVoid.Instance);
            }

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb4 = qm.Borrow(1);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 1);
            Assert.True(qb4[0].Id == 8);

            qm.OnOperationEnd(null, QVoid.Instance);
        }
示例#5
0
        public void TestQubitManager()
        {
            QubitManager qm = new QubitManager(30);

            // Test allocation of single qubit
            Qubit q1 = qm.Allocate();

            Assert.True(q1.Id == 0);

            // Test allocation of multiple qubits
            IQArray <Qubit> qa1 = qm.Allocate(4);

            Assert.True(qa1.Length == 4);
            Assert.True(qa1[0].Id == 1);
            Assert.True(qa1[1].Id == 2);
            Assert.True(qa1[2].Id == 3);
            Assert.True(qa1[3].Id == 4);

            // Test reuse of deallocated qubits
            qm.Release(qa1[1]);

            Qubit q2 = qm.Allocate();

            Assert.True(q2.Id == 2);

            IQArray <Qubit> qa2 = qm.Allocate(3);

            Assert.True(qa2.Length == 3);
            Assert.True(qa2[0].Id == 5);
            Assert.True(qa2[1].Id == 6);
            Assert.True(qa2[2].Id == 7);

            qm.Release(qa2);

            Qubit q3 = qm.Allocate();

            Assert.True(q3.Id == 7);

            Qubit q4 = qm.Allocate();

            Assert.True(q4.Id == 6);

            Qubit q5 = qm.Allocate();

            Assert.True(q5.Id == 5);

            // Test borrowing
            HashSet <Qubit> exclusion = new HashSet <Qubit>();

            exclusion.Add(qa1[0]);
            exclusion.Add(qa1[2]);
            exclusion.Add(q4);
            exclusion.Add(q3);

            long qubitsAvailable;

            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qab = qm.Borrow(5, exclusion);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 1);
            Assert.True(qab[0].Id == 0);
            Assert.True(qab[1].Id == 2);
            Assert.True(qab[2].Id == 4);
            Assert.True(qab[3].Id == 5);
            Assert.True(qab[4].Id == 8);

            Qubit q6 = qm.Allocate();

            Assert.True(q6.Id == 9);

            // Test borrowing of the same qubit again
            qubitsAvailable = qm.FreeQubitsCount;
            IQArray <Qubit> qb1 = qm.Borrow(1, exclusion);

            Assert.True(qubitsAvailable - qm.FreeQubitsCount == 0);
            Assert.True(qb1[0].Id == 0);
            qm.Return(qb1[0]);

            qm.Return(qab);

            // Test that qubit allocated for borrowing is freed after being returned
            Qubit q7 = qm.Allocate();

            Assert.True(q7.Id == 8);

            // Test allocation of qubits out of order.
            qm.Release(q4);
            qm.Release(qa1[2]);
            qm.Release(q1);

            IQArray <Qubit> qa3 = qm.Allocate(4);

            Assert.True(qa3.Length == 4);
            Assert.True(qa3[0].Id == 0);
            Assert.True(qa3[1].Id == 3);
            Assert.True(qa3[2].Id == 6);
            Assert.True(qa3[3].Id == 10);

            // Test Disabling qubits
            Qubit q8 = qm.Allocate();

            Assert.True(q8.Id == 11);
            qm.Disable(q8);
            IQArray <Qubit> qab2 = qm.Borrow(12);

            Assert.True(qab2[11].Id == 23);  // make sure 11 is not borrowed.
            qm.Release(q8);
            qm.Return(qab2);

            IQArray <Qubit> qa4 = qm.Allocate(2);

            Assert.True(qa4[0].Id == 23); // make sure 11 is not reused.
            Assert.True(qa4[1].Id == 22); // make sure 11 is not reused.
            qm.Release(qa4);


            { // Test allocating zero qubits
                IQArray <Qubit> n_q;
                n_q = qm.Allocate(0);
                Assert.True(n_q.Length == 0);
                n_q = qm.Borrow(0, exclusion);
                Assert.True(n_q.Length == 0);
            }

            // NOTE: The below tests trigger exceptions, which but the QubitManager into a bad
            // state where it shouldn't be reused. Creating a separate QubitManager in a small
            // scope to test the exceptions avoids having one test case pollute the other.

            // Test for over allocating and over borrowing.
            {
                QubitManager    qm_small = new QubitManager(2);
                IQArray <Qubit> n_q;
                Assert.Throws <NotEnoughQubits>(() => n_q = qm_small.Allocate(5));
            }
            {
                QubitManager    qm_small = new QubitManager(2);
                IQArray <Qubit> n_q;
                Assert.Throws <NotEnoughQubits>(() => n_q = qm_small.Borrow(5));
            }

            // Test for negative input to allocate and borrow.
            {
                QubitManager    qm_small = new QubitManager(20);
                IQArray <Qubit> n_q;
                Assert.Throws <ArgumentException>(() => n_q = qm_small.Allocate(-2));
            }
            {
                QubitManager    qm_small = new QubitManager(20);
                IQArray <Qubit> n_q;
                Assert.Throws <ArgumentException>(() => n_q = qm_small.Borrow(-2));
            }
        }
示例#6
0
        public void TestQubitManagerDiscouragingReuse()
        {
            { // BLOCK testing mayExtendCapacity:false
                QubitManager qm = new QubitManager(10, mayExtendCapacity: false, disableBorrowing: false, encourageReuse: false);

                // Test allocation of single qubit
                Qubit q1 = qm.Allocate();
                Assert.True(q1.Id == 0);

                // Test allocation of multiple qubits
                IQArray <Qubit> qa1 = qm.Allocate(4);
                Assert.True(qa1.Length == 4);
                Assert.True(qa1[0].Id == 1);
                Assert.True(qa1[1].Id == 2);
                Assert.True(qa1[2].Id == 3);
                Assert.True(qa1[3].Id == 4);

                // Test reuse of deallocated qubits
                qm.Release(qa1[1]);

                Qubit q2 = qm.Allocate();
                Assert.True(q2.Id == 5);

                IQArray <Qubit> qa2 = qm.Allocate(3);
                Assert.True(qa2.Length == 3);
                Assert.True(qa2[0].Id == 6);
                Assert.True(qa2[1].Id == 7);
                Assert.True(qa2[2].Id == 8);

                qm.Release(qa2);

                Qubit q3 = qm.Allocate();
                Assert.True(q3.Id == 9);

                Qubit q4 = qm.Allocate();
                Assert.True(q4.Id == 2);

                Qubit q5 = qm.Allocate();
                Assert.True(q5.Id == 6);
            }

            { // BLOCK testing mayExtendCapacity:true
                QubitManager qm = new QubitManager(10, mayExtendCapacity: true, disableBorrowing: false, encourageReuse: false);

                // Test allocation of single qubit
                Qubit q1 = qm.Allocate();
                Assert.True(q1.Id == 0);

                // Test allocation of multiple qubits
                IQArray <Qubit> qa1 = qm.Allocate(4);
                Assert.True(qa1.Length == 4);
                Assert.True(qa1[0].Id == 1);
                Assert.True(qa1[1].Id == 2);
                Assert.True(qa1[2].Id == 3);
                Assert.True(qa1[3].Id == 4);

                // Test reuse of deallocated qubits
                qm.Release(qa1[1]);

                Qubit q2 = qm.Allocate();
                Assert.True(q2.Id == 5);

                IQArray <Qubit> qa2 = qm.Allocate(3);
                Assert.True(qa2.Length == 3);
                Assert.True(qa2[0].Id == 6);
                Assert.True(qa2[1].Id == 7);
                Assert.True(qa2[2].Id == 8);

                qm.Release(qa2);

                Qubit q3 = qm.Allocate();
                Assert.True(q3.Id == 9);

                Qubit q4 = qm.Allocate();
                Assert.True(q4.Id == 10);

                Qubit q5 = qm.Allocate();
                Assert.True(q5.Id == 11);
            }
        }
        public void TestQubitManager()
        {
            QubitManager qm = new QubitManager(20);

            // Test allocation of single qubit
            Qubit q1 = qm.Allocate();

            Assert.True(q1.Id == 0);

            // Test allocation of multiple qubits
            var qa1 = qm.Allocate(4);

            Assert.True(qa1.Length == 4);
            Assert.True(qa1[0].Id == 1);
            Assert.True(qa1[1].Id == 2);
            Assert.True(qa1[2].Id == 3);
            Assert.True(qa1[3].Id == 4);

            // Test reuse of deallocated qubits
            qm.Release(qa1[1]);

            Qubit q2 = qm.Allocate();

            Assert.True(q2.Id == 2);

            var qa2 = qm.Allocate(3);

            Assert.True(qa2.Length == 3);
            Assert.True(qa2[0].Id == 5);
            Assert.True(qa2[1].Id == 6);
            Assert.True(qa2[2].Id == 7);

            qm.Release(qa2);

            Qubit q3 = qm.Allocate();

            Assert.True(q3.Id == 7);

            Qubit q4 = qm.Allocate();

            Assert.True(q4.Id == 6);

            Qubit q5 = qm.Allocate();

            Assert.True(q5.Id == 5);

            // Test borrowing
            Qubit[] exclusion = new Qubit[4];
            exclusion[0] = qa1[0];
            exclusion[1] = qa1[2];
            exclusion[2] = q4;
            exclusion[3] = q3;

            long qubitsAvailable;

            qubitsAvailable = qm.GetFreeQubitsCount();
            var qab = qm.Borrow(5, exclusion);

            Assert.True(qubitsAvailable - qm.GetFreeQubitsCount() == 1);
            Assert.True(qab[0].Id == 0);
            Assert.True(qab[1].Id == 2);
            Assert.True(qab[2].Id == 4);
            Assert.True(qab[3].Id == 5);
            Assert.True(qab[4].Id == 8);

            Qubit q6 = qm.Allocate();

            Assert.True(q6.Id == 9);

            // Test borrowing of the same qubit again
            qubitsAvailable = qm.GetFreeQubitsCount();
            var qb1 = qm.Borrow(1, exclusion);

            Assert.True(qubitsAvailable - qm.GetFreeQubitsCount() == 0);
            Assert.True(qb1[0].Id == 0);
            qm.Return(qb1[0]);

            qm.Return(qab);

            // Test that qubit allocated for borrowing is freed after being returned
            Qubit q7 = qm.Allocate();

            Assert.True(q7.Id == 8);

            // Test allocation of qubits out of order.
            qm.Release(q4);
            qm.Release(qa1[2]);
            qm.Release(q1);

            var qa3 = qm.Allocate(4);

            Assert.True(qa3.Length == 4);
            Assert.True(qa3[0].Id == 0);
            Assert.True(qa3[1].Id == 3);
            Assert.True(qa3[2].Id == 6);
            Assert.True(qa3[3].Id == 10);

            // Test Disabling qubits
            Qubit q8 = qm.Allocate();

            Assert.True(q8.Id == 11);
            qm.Disable(q8);
            var qab2 = qm.Borrow(12, null);

            Assert.True(qab2[11].Id == 12);  // make sure 11 is not borrowed.
            qm.Release(q8);
            qm.Return(qab2);

            var qa4 = qm.Allocate(2);

            Assert.True(qa4[0].Id == 12); // make sure 11 is not reused.
            Assert.True(qa4[1].Id == 13); // make sure 11 is not reused.
            qm.Release(qa4);

            // Test allocating qubits over capacity
            OperationsTestHelper.IgnoreDebugAssert(() =>
            {
                IQArray <Qubit> n_q;

                Assert.Throws <NotEnoughQubits>(() => n_q = qm.Allocate(10));
                Assert.Throws <NotEnoughQubits>(() => n_q = qm.Borrow(25, exclusion));

                Assert.Throws <ArgumentException>(() => n_q = qm.Allocate(0));
                Assert.Throws <ArgumentException>(() => n_q = qm.Allocate(-2));
                Assert.Throws <ArgumentException>(() => n_q = qm.Borrow(0, exclusion));
                Assert.Throws <ArgumentException>(() => n_q = qm.Borrow(-2, exclusion));
            });
        }
示例#8
0
        public override void AssertProb(IQArray <Pauli> bases, IQArray <Qubit> qubits, double probabilityOfZero, string msg, double tol)
        {
            bool   shouldBeDeterministic;
            Result?expectedResult;

            // Is the probability 0?
            if (Math.Abs(probabilityOfZero - 0) < tol)
            {
                shouldBeDeterministic = true;
                expectedResult        = Result.One;
            }
            else if (Math.Abs(probabilityOfZero - 0.5) < tol)
            {
                shouldBeDeterministic = false;
                expectedResult        = null;
            }
            else if (Math.Abs(probabilityOfZero - 1) < tol)
            {
                shouldBeDeterministic = true;
                expectedResult        = Result.Zero;
            }
            else
            {
                throw new ExecutionFailException(msg);
            }

            this.Simulator?.MaybeDisplayDiagnostic(
                new DebugMessage
            {
                Message = $"shouldBeDeterministic = {shouldBeDeterministic}, expectedResult = {expectedResult}",
            });

            if (!bases.TryGetSingleZ(out var idx))
            {
                var aux = this.Simulator !.QubitManager?.Allocate();
                if (aux == null)
                {
                    throw new NullReferenceException("Qubit manager was null.");
                }

                try
                {
                    this.WriteToScratch(bases, qubits, aux);
                    this.AssertProb(
                        new QArray <Pauli>(new[] { Pauli.PauliZ }),
                        new QArray <Qubit>(new[] { aux }),
                        probabilityOfZero,
                        msg,
                        tol);
                    this.WriteToScratch(
                        new QArray <Pauli>(bases.Reverse()),
                        new QArray <Qubit>(qubits.Reverse()),
                        aux);
                }
                finally
                {
                    this.Simulator !.QubitManager?.Release(aux);
                }
            }
            else
            {
                var isDeterministic = this.IsMeasurementDetermined(qubits[idx].Id, out var result);
                if (isDeterministic == shouldBeDeterministic)
                {
                    if (!isDeterministic || expectedResult == result)
                    {
                        return;
                    }

                    throw new ExecutionFailException(msg);
                }
            }
        }