14#ifndef _GPU_STABILIZER_H
15#define _GPU_STABILIZER_H 1
25 explicit GpuStabilizer(
const std::shared_ptr<GpuLibrary> &lib,
int device = -1)
26 : device(device == -1 && lib ? lib->GetCreationDevice() : device), lib(lib), obj(
nullptr) {}
28 int GetGpuDevice()
const {
return lib ? lib->GetStabilizerGpuId(obj) : -1; }
30 GpuStabilizer() =
delete;
31 GpuStabilizer(
const GpuStabilizer &) =
delete;
32 GpuStabilizer &operator=(
const GpuStabilizer &) =
delete;
33 GpuStabilizer(GpuStabilizer &&) =
default;
34 GpuStabilizer &operator=(GpuStabilizer &&) =
default;
37 if (lib && obj) lib->DestroyStabilizerSimulator(obj);
41 long long int numMeasurements,
42 long long int numDetectors) {
44 auto lock = lib->LockInitialization();
45 if (!lib->SetGpuDevice(device))
return false;
46 if (obj) lib->DestroyStabilizerSimulator(obj);
48 obj = lib->CreateStabilizerSimulator(numQubits, numShots, numMeasurements,
50 return obj !=
nullptr;
56 bool ExecuteCircuit(
const std::string &circuitStr,
int randomizeMeasurements,
57 unsigned long long int seed) {
59 return lib->ExecuteStabilizerCircuit(obj, circuitStr.c_str(),
60 randomizeMeasurements, seed);
66 lib->DestroyStabilizerSimulator(obj);
74 long long GetNumQubits() {
75 if (obj)
return lib->GetStabilizerNumQubits(obj);
79 long long GetNumShots() {
80 if (obj)
return lib->GetStabilizerNumShots(obj);
84 long long GetNumMeasurements() {
85 if (obj)
return lib->GetStabilizerNumMeasurements(obj);
89 long long GetNumDetectors() {
90 if (obj)
return lib->GetStabilizerNumDetectors(obj);
94 bool IsCreated()
const {
return obj !=
nullptr; }
96 std::vector<std::vector<bool>> GetXTable() {
97 if (!obj)
return std::vector<std::vector<bool>>();
99 std::vector<unsigned int> xTableRaw(GetStabilizerXZTableSize());
100 lib->CopyStabilizerXTable(obj, xTableRaw.data());
102 return ConvertToBoolVectorVector(xTableRaw, GetNumQubits(), GetNumShots());
105 std::vector<std::vector<bool>> GetZTable() {
106 if (!obj)
return std::vector<std::vector<bool>>();
108 std::vector<unsigned int> zTableRaw(GetStabilizerXZTableSize());
109 lib->CopyStabilizerZTable(obj, zTableRaw.data());
111 return ConvertToBoolVectorVector(zTableRaw, GetNumQubits(), GetNumShots());
114 std::vector<std::vector<bool>> GetMTable() {
115 if (!obj)
return std::vector<std::vector<bool>>();
117 std::vector<unsigned int> mTableRaw(GetStabilizerMTableSize());
118 lib->CopyStabilizerMTable(obj, mTableRaw.data());
120 return ConvertToBoolVectorVector(mTableRaw, GetNumMeasurements(),
124 bool InitXTable(
const std::vector<std::vector<bool>> &xTable) {
125 if (!obj)
return false;
126 const long long shots = GetNumShots();
127 const long long words_per_qubitormeas = (shots + 31) / 32;
128 const long long numQubits = GetNumQubits();
129 std::vector<unsigned int> xTableRaw(numQubits * words_per_qubitormeas, 0);
130 for (
long long qubit = 0; qubit < numQubits; ++qubit) {
131 for (
long long shot = 0; shot < shots; ++shot) {
132 if (xTable[qubit][shot]) {
133 xTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |=
138 return lib->InitStabilizerXTable(obj, xTableRaw.data()) == 1;
141 bool InitXTableRepeat(
const std::vector<bool> &xTable) {
143 if (!obj)
return false;
144 const long long shots = GetNumShots();
145 const long long words_per_qubitormeas = (shots + 31) / 32;
146 const long long numQubits = GetNumQubits();
147 std::vector<unsigned int> xTableRaw(numQubits * words_per_qubitormeas, 0);
148 for (
long long qubit = 0; qubit < numQubits; ++qubit) {
149 for (
long long shot = 0; shot < shots; ++shot) {
151 xTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |=
157 return lib->InitStabilizerXTable(obj, xTableRaw.data()) == 1;
160 bool InitZTable(
const std::vector<std::vector<bool>> &zTable) {
161 if (!obj)
return false;
162 const long long shots = GetNumShots();
163 const long long words_per_qubitormeas = (shots + 31) / 32;
164 const long long numQubits = GetNumQubits();
165 std::vector<unsigned int> zTableRaw(numQubits * words_per_qubitormeas, 0);
166 for (
long long qubit = 0; qubit < numQubits; ++qubit) {
167 for (
long long shot = 0; shot < shots; ++shot) {
168 if (zTable[qubit][shot]) {
169 zTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |=
174 return lib->InitStabilizerZTable(obj, zTableRaw.data()) == 1;
177 bool InitZTableRepeat(
const std::vector<bool> &zTable) {
179 if (!obj)
return false;
180 const long long shots = GetNumShots();
181 const long long words_per_qubitormeas = (shots + 31) / 32;
182 const long long numQubits = GetNumQubits();
183 std::vector<unsigned int> zTableRaw(numQubits * words_per_qubitormeas, 0);
184 for (
long long qubit = 0; qubit < numQubits; ++qubit) {
185 for (
long long shot = 0; shot < shots; ++shot) {
187 zTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |=
192 return lib->InitStabilizerZTable(obj, zTableRaw.data()) == 1;
196 std::vector<std::vector<bool>> ConvertToBoolVectorVector(
197 const std::vector<unsigned int> &tableRaw,
long long int num,
198 long long int shots) {
199 const long long words_per_qubitormeas = (shots + 31) / 32;
201 std::vector<std::vector<bool>> result(num);
203 for (
long long qubitormeas = 0; qubitormeas < num; ++qubitormeas) {
204 for (
long long shot = 0; shot < shots; ++shot) {
205 const unsigned int word =
206 tableRaw[qubitormeas * words_per_qubitormeas + (shot / 32)];
207 const bool bit = ((word >> (shot % 32)) & 1) == 1;
208 result[qubitormeas].push_back(bit);
215 long long GetStabilizerXZTableSize() {
216 if (obj)
return lib->GetStabilizerXZTableSize(obj);
220 long long GetStabilizerMTableSize() {
221 if (obj)
return lib->GetStabilizerMTableSize(obj);
225 long long GetStabilizerTableStrideMajor() {
226 if (obj)
return lib->GetStabilizerTableStrideMajor(obj);
232 GpuDeviceContext lib;
unsigned long int CreateSimulator(int simType, int simExecType)