diff --git a/src/QirRuntime/lib/Simulators/ToffoliSimulator.cpp b/src/QirRuntime/lib/Simulators/ToffoliSimulator.cpp index db992d24ba3..bc3c94c3de4 100644 --- a/src/QirRuntime/lib/Simulators/ToffoliSimulator.cpp +++ b/src/QirRuntime/lib/Simulators/ToffoliSimulator.cpp @@ -8,8 +8,6 @@ #include "QSharpSimApi_I.hpp" #include "SimFactory.hpp" -#include "BitStates.hpp" - namespace Microsoft { namespace Quantum @@ -24,7 +22,7 @@ namespace Quantum // State of a qubit is represented by a bit in states indexed by qubit's id, // bits 0 and 1 correspond to |0> and |1> states respectively. - BitStates states; + std::vector states; // The clients should never attempt to derefenece the Result, so we'll use fake // pointers to avoid allocation and deallocation. @@ -67,7 +65,7 @@ namespace Quantum Qubit AllocateQubit() override { this->lastUsedId++; - this->states.ExtendToInclude(this->lastUsedId); + this->states.emplace_back(false); return reinterpret_cast(this->lastUsedId); } @@ -75,13 +73,15 @@ namespace Quantum { const long id = GetQubitId(qubit); assert(id <= this->lastUsedId); - assert(!this->states.IsBitSetAt(id)); + assert(!this->states.at(id)); + this->lastUsedId--; + this->states.pop_back(); } std::string QubitToString(Qubit qubit) override { const long id = GetQubitId(qubit); - return std::to_string(id) + ":" + (this->states.IsBitSetAt(id) ? "1" : "0"); + return std::to_string(id) + ":" + (this->states.at(id) ? "1" : "0"); } /// @@ -120,7 +120,7 @@ namespace Quantum /// void X(Qubit qubit) override { - this->states.FlipBitAt(GetQubitId(qubit)); + this->states.at(GetQubitId(qubit)).flip(); } void ControlledX(long numControls, Qubit* const controls, Qubit qubit) override @@ -128,7 +128,7 @@ namespace Quantum bool allControlsSet = true; for (long i = 0; i < numControls; i++) { - if (!this->states.IsBitSetAt(GetQubitId(controls[i]))) + if (!this->states.at(GetQubitId(controls[i]))) { allControlsSet = false; break; @@ -137,7 +137,7 @@ namespace Quantum if (allControlsSet) { - this->states.FlipBitAt(GetQubitId(qubit)); + this->states.at(GetQubitId(qubit)).flip(); } } @@ -153,7 +153,7 @@ namespace Quantum } if (bases[i] == PauliId_Z) { - odd ^= (this->states.IsBitSetAt(GetQubitId(targets[i]))); + odd ^= (this->states.at(GetQubitId(targets[i]))); } } return odd ? one : zero; diff --git a/src/QirRuntime/public/BitStates.hpp b/src/QirRuntime/public/BitStates.hpp deleted file mode 100644 index 671a5742e36..00000000000 --- a/src/QirRuntime/public/BitStates.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -#include -#include - -#include "CoreTypes.hpp" - -namespace Microsoft -{ -namespace Quantum -{ - /*============================================================================== - Provides dynamically extendable storage for packed bits - ==============================================================================*/ - struct QIR_SHARED_API BitStates - { - typedef uint64_t TSLOT; - static constexpr int slotSizeBits = sizeof(TSLOT) * 8; - - std::vector slots; - - static long GetSlotIndex(long bitIndex) - { - return (bitIndex / (slotSizeBits)); - } - static long GetIndexInSlot(long bitIndex) - { - return (bitIndex & (slotSizeBits - 1)); - } - - void ExtendToInclude(long index) - { - long slotIndex = GetSlotIndex(index); - for (long i = this->slots.size(); i < slotIndex + 1; i++) - { - this->slots.push_back(0); - } - } - - void Clear() - { - this->slots.clear(); - } - - void SetBitAt(long index) - { - const long slotIndex = GetSlotIndex(index); - const long bitIndex = GetIndexInSlot(index); - this->slots[slotIndex] |= (static_cast(1) << bitIndex); - } - - void FlipBitAt(long index) - { - const long slotIndex = GetSlotIndex(index); - const long bitIndex = GetIndexInSlot(index); - this->slots[slotIndex] ^= (static_cast(1) << bitIndex); - } - - bool IsBitSetAt(long index) const - { - const long slotIndex = GetSlotIndex(index); - const long bitIndex = GetIndexInSlot(index); - return this->slots[slotIndex] & (static_cast(1) << bitIndex); - } - - bool IsAny() const - { - for (long i = 0; i < this->slots.size(); i++) - { - if (this->slots[i] != 0) - { - return true; - } - } - return false; - } - }; - -} // namespace Quantum -} // namespace Microsoft \ No newline at end of file diff --git a/src/QirRuntime/test/unittests/QirRuntimeTests.cpp b/src/QirRuntime/test/unittests/QirRuntimeTests.cpp index d47c26fafcb..f149f388e8d 100644 --- a/src/QirRuntime/test/unittests/QirRuntimeTests.cpp +++ b/src/QirRuntime/test/unittests/QirRuntimeTests.cpp @@ -14,7 +14,6 @@ #include "qsharp__core__qis.hpp" #include "QirRuntime.hpp" -#include "BitStates.hpp" #include "QirContext.hpp" #include "SimulatorStub.hpp" @@ -22,9 +21,9 @@ using namespace Microsoft::Quantum; struct ResultsReferenceCountingTestQAPI : public SimulatorStub { - int lastId = 1; + int lastId = -1; const int maxResults; - BitStates allocated; + std::vector allocated; static int GetResultId(Result r) { @@ -32,16 +31,16 @@ struct ResultsReferenceCountingTestQAPI : public SimulatorStub } ResultsReferenceCountingTestQAPI(int maxResults) - : maxResults(maxResults + 2) + : maxResults(maxResults), + allocated(maxResults, false) { - allocated.ExtendToInclude(maxResults); } Result Measure(long, PauliId[], long, Qubit[]) override { assert(this->lastId < this->maxResults); this->lastId++; - this->allocated.SetBitAt(this->lastId); + this->allocated.at(this->lastId) = true;; return reinterpret_cast(this->lastId); } Result UseZero() override @@ -56,8 +55,8 @@ struct ResultsReferenceCountingTestQAPI : public SimulatorStub { const int id = GetResultId(result); INFO(id); - REQUIRE(this->allocated.IsBitSetAt(id)); - this->allocated.FlipBitAt(id); + REQUIRE(this->allocated.at(id)); + this->allocated.at(id).flip(); } bool AreEqualResults(Result r1, Result r2) override { @@ -66,7 +65,14 @@ struct ResultsReferenceCountingTestQAPI : public SimulatorStub bool HaveResultsInFlight() const { - return this->allocated.IsAny(); + for (const auto& b : this->allocated) + { + if (b) + { + return true; + } + } + return false; } }; TEST_CASE("Results: comparison and reference counting", "[qir_support]") @@ -693,7 +699,7 @@ struct QubitTestQAPI : public SimulatorStub { int lastId = -1; const int maxQubits; - BitStates allocated; + std::vector allocated; static int GetQubitId(Qubit q) { @@ -701,23 +707,24 @@ struct QubitTestQAPI : public SimulatorStub } QubitTestQAPI(int maxQubits) - : maxQubits(maxQubits) + : maxQubits(maxQubits), + allocated(maxQubits, false) { - allocated.ExtendToInclude(maxQubits); } + Qubit AllocateQubit() override { assert(this->lastId < this->maxQubits); this->lastId++; - this->allocated.SetBitAt(this->lastId); + this->allocated.at(this->lastId) = true; return reinterpret_cast(this->lastId); } void ReleaseQubit(Qubit qubit) override { const int id = GetQubitId(qubit); INFO(id); - REQUIRE(this->allocated.IsBitSetAt(id)); - this->allocated.FlipBitAt(id); + REQUIRE(this->allocated.at(id)); + this->allocated.at(id).flip(); } std::string QubitToString(Qubit qubit) override { @@ -735,12 +742,19 @@ struct QubitTestQAPI : public SimulatorStub bool HaveQubitsInFlight() const { - return this->allocated.IsAny(); + for (const auto& b : this->allocated) + { + if (b) + { + return true; + } + } + return false; } }; TEST_CASE("Qubits: allocate, release, dump", "[qir_support]") { - std::unique_ptr qapi = std::make_unique(3); + std::unique_ptr qapi = std::make_unique(4); QirContextScope qirctx(qapi.get()); QirString* qstr = nullptr;