Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
GpuStabilizer.h
Go to the documentation of this file.
1
11
12#pragma once
13
14#ifndef _GPU_STABILIZER_H
15#define _GPU_STABILIZER_H 1
16
17#ifdef __linux__
18
19#include "GpuDeviceContext.h"
20
21namespace Simulators {
22
23class GpuStabilizer {
24 public:
25 explicit GpuStabilizer(const std::shared_ptr<GpuLibrary> &lib, int device = -1)
26 : device(device == -1 && lib ? lib->GetCreationDevice() : device), lib(lib), obj(nullptr) {}
27
28 int GetGpuDevice() const { return lib ? lib->GetStabilizerGpuId(obj) : -1; }
29
30 GpuStabilizer() = delete;
31 GpuStabilizer(const GpuStabilizer &) = delete;
32 GpuStabilizer &operator=(const GpuStabilizer &) = delete;
33 GpuStabilizer(GpuStabilizer &&) = default;
34 GpuStabilizer &operator=(GpuStabilizer &&) = default;
35
36 ~GpuStabilizer() {
37 if (lib && obj) lib->DestroyStabilizerSimulator(obj);
38 }
39
40 bool CreateSimulator(long long int numQubits, long long int numShots,
41 long long int numMeasurements,
42 long long int numDetectors) {
43 if (lib) {
44 auto lock = lib->LockInitialization();
45 if (!lib->SetGpuDevice(device)) return false;
46 if (obj) lib->DestroyStabilizerSimulator(obj);
47 obj = nullptr;
48 obj = lib->CreateStabilizerSimulator(numQubits, numShots, numMeasurements,
49 numDetectors);
50 return obj != nullptr;
51 }
52
53 return false;
54 }
55
56 bool ExecuteCircuit(const std::string &circuitStr, int randomizeMeasurements,
57 unsigned long long int seed) {
58 if (obj)
59 return lib->ExecuteStabilizerCircuit(obj, circuitStr.c_str(),
60 randomizeMeasurements, seed);
61 return false;
62 }
63
64 bool Clear() {
65 if (obj) {
66 lib->DestroyStabilizerSimulator(obj);
67 obj = nullptr;
68 return true;
69 }
70
71 return false;
72 }
73
74 long long GetNumQubits() {
75 if (obj) return lib->GetStabilizerNumQubits(obj);
76 return 0;
77 }
78
79 long long GetNumShots() {
80 if (obj) return lib->GetStabilizerNumShots(obj);
81 return 0;
82 }
83
84 long long GetNumMeasurements() {
85 if (obj) return lib->GetStabilizerNumMeasurements(obj);
86 return 0;
87 }
88
89 long long GetNumDetectors() {
90 if (obj) return lib->GetStabilizerNumDetectors(obj);
91 return 0;
92 }
93
94 bool IsCreated() const { return obj != nullptr; }
95
96 std::vector<std::vector<bool>> GetXTable() {
97 if (!obj) return std::vector<std::vector<bool>>();
98
99 std::vector<unsigned int> xTableRaw(GetStabilizerXZTableSize());
100 lib->CopyStabilizerXTable(obj, xTableRaw.data());
101
102 return ConvertToBoolVectorVector(xTableRaw, GetNumQubits(), GetNumShots());
103 }
104
105 std::vector<std::vector<bool>> GetZTable() {
106 if (!obj) return std::vector<std::vector<bool>>();
107
108 std::vector<unsigned int> zTableRaw(GetStabilizerXZTableSize());
109 lib->CopyStabilizerZTable(obj, zTableRaw.data());
110
111 return ConvertToBoolVectorVector(zTableRaw, GetNumQubits(), GetNumShots());
112 }
113
114 std::vector<std::vector<bool>> GetMTable() {
115 if (!obj) return std::vector<std::vector<bool>>();
116
117 std::vector<unsigned int> mTableRaw(GetStabilizerMTableSize());
118 lib->CopyStabilizerMTable(obj, mTableRaw.data());
119
120 return ConvertToBoolVectorVector(mTableRaw, GetNumMeasurements(),
121 GetNumShots());
122 }
123
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)] |=
134 (1U << (shot % 32));
135 }
136 }
137 }
138 return lib->InitStabilizerXTable(obj, xTableRaw.data()) == 1;
139 }
140
141 bool InitXTableRepeat(const std::vector<bool> &xTable) {
142 // repeat xTable for all shots
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) {
150 if (xTable[qubit]) {
151 xTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |=
152 (1U << (shot % 32));
153 }
154 }
155 }
156
157 return lib->InitStabilizerXTable(obj, xTableRaw.data()) == 1;
158 }
159
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)] |=
170 (1U << (shot % 32));
171 }
172 }
173 }
174 return lib->InitStabilizerZTable(obj, zTableRaw.data()) == 1;
175 }
176
177 bool InitZTableRepeat(const std::vector<bool> &zTable) {
178 // repeat zTable for all shots
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) {
186 if (zTable[qubit]) {
187 zTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |=
188 (1U << (shot % 32));
189 }
190 }
191 }
192 return lib->InitStabilizerZTable(obj, zTableRaw.data()) == 1;
193 }
194
195 protected:
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;
200
201 std::vector<std::vector<bool>> result(num);
202
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);
209 }
210 }
211
212 return result;
213 }
214
215 long long GetStabilizerXZTableSize() {
216 if (obj) return lib->GetStabilizerXZTableSize(obj);
217 return 0;
218 }
219
220 long long GetStabilizerMTableSize() {
221 if (obj) return lib->GetStabilizerMTableSize(obj);
222 return 0;
223 }
224
225 long long GetStabilizerTableStrideMajor() {
226 if (obj) return lib->GetStabilizerTableStrideMajor(obj);
227 return 0;
228 }
229
230 private:
231 int device; // Fixed even when native creation is delayed or repeated.
232 GpuDeviceContext lib;
233 void *obj;
234};
235
236} // namespace Simulators
237
238#endif
239#endif
unsigned long int CreateSimulator(int simType, int simExecType)