Maestro 0.3.11
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{
23
24class GpuStabilizer
25{
26 public:
27 explicit GpuStabilizer(const std::shared_ptr<GpuLibrary> &lib, int device = -1)
28 : device(device == -1 && lib ? lib->GetCreationDevice() : device), lib(lib), obj(nullptr)
29 {
30 }
31
32 int GetGpuDevice() const
33 {
34 return lib ? lib->GetStabilizerGpuId(obj) : -1;
35 }
36
37 GpuStabilizer() = delete;
38 GpuStabilizer(const GpuStabilizer &) = delete;
39 GpuStabilizer &operator=(const GpuStabilizer &) = delete;
40 GpuStabilizer(GpuStabilizer &&) = default;
41 GpuStabilizer &operator=(GpuStabilizer &&) = default;
42
43 ~GpuStabilizer()
44 {
45 if (lib && obj)
46 lib->DestroyStabilizerSimulator(obj);
47 }
48
49 bool CreateSimulator(long long int numQubits, long long int numShots, long long int numMeasurements, long long int numDetectors)
50 {
51 if (lib)
52 {
53 auto lock = lib->LockInitialization();
54 if (!lib->SetGpuDevice(device))
55 return false;
56 if (obj)
57 lib->DestroyStabilizerSimulator(obj);
58 obj = nullptr;
59 obj = lib->CreateStabilizerSimulator(numQubits, numShots, numMeasurements, numDetectors);
60 return obj != nullptr;
61 }
62
63 return false;
64 }
65
66 bool ExecuteCircuit(const std::string &circuitStr, int randomizeMeasurements, unsigned long long int seed)
67 {
68 if (obj)
69 return lib->ExecuteStabilizerCircuit(obj, circuitStr.c_str(), randomizeMeasurements, seed);
70 return false;
71 }
72
73 bool Clear()
74 {
75 if (obj)
76 {
77 lib->DestroyStabilizerSimulator(obj);
78 obj = nullptr;
79 return true;
80 }
81
82 return false;
83 }
84
85 long long GetNumQubits()
86 {
87 if (obj)
88 return lib->GetStabilizerNumQubits(obj);
89 return 0;
90 }
91
92 long long GetNumShots()
93 {
94 if (obj)
95 return lib->GetStabilizerNumShots(obj);
96 return 0;
97 }
98
99 long long GetNumMeasurements()
100 {
101 if (obj)
102 return lib->GetStabilizerNumMeasurements(obj);
103 return 0;
104 }
105
106 long long GetNumDetectors()
107 {
108 if (obj)
109 return lib->GetStabilizerNumDetectors(obj);
110 return 0;
111 }
112
113 bool IsCreated() const
114 {
115 return obj != nullptr;
116 }
117
118 std::vector<std::vector<bool>> GetXTable()
119 {
120 if (!obj)
121 return std::vector<std::vector<bool>>();
122
123 std::vector<unsigned int> xTableRaw(GetStabilizerXZTableSize());
124 lib->CopyStabilizerXTable(obj, xTableRaw.data());
125
126 return ConvertToBoolVectorVector(xTableRaw, GetNumQubits(), GetNumShots());
127 }
128
129 std::vector<std::vector<bool>> GetZTable()
130 {
131 if (!obj)
132 return std::vector<std::vector<bool>>();
133
134 std::vector<unsigned int> zTableRaw(GetStabilizerXZTableSize());
135 lib->CopyStabilizerZTable(obj, zTableRaw.data());
136
137 return ConvertToBoolVectorVector(zTableRaw, GetNumQubits(), GetNumShots());
138 }
139
140 std::vector<std::vector<bool>> GetMTable()
141 {
142 if (!obj)
143 return std::vector<std::vector<bool>>();
144
145 std::vector<unsigned int> mTableRaw(GetStabilizerMTableSize());
146 lib->CopyStabilizerMTable(obj, mTableRaw.data());
147
148 return ConvertToBoolVectorVector(mTableRaw, GetNumMeasurements(), GetNumShots());
149 }
150
151 bool InitXTable(const std::vector<std::vector<bool>> &xTable)
152 {
153 if (!obj)
154 return false;
155 const long long shots = GetNumShots();
156 const long long words_per_qubitormeas = (shots + 31) / 32;
157 const long long numQubits = GetNumQubits();
158 std::vector<unsigned int> xTableRaw(numQubits * words_per_qubitormeas, 0);
159 for (long long qubit = 0; qubit < numQubits; ++qubit)
160 {
161 for (long long shot = 0; shot < shots; ++shot)
162 {
163 if (xTable[qubit][shot])
164 {
165 xTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |= (1U << (shot % 32));
166 }
167 }
168 }
169 return lib->InitStabilizerXTable(obj, xTableRaw.data()) == 1;
170 }
171
172 bool InitXTableRepeat(const std::vector<bool> &xTable)
173 {
174 // repeat xTable for all shots
175 if (!obj)
176 return false;
177 const long long shots = GetNumShots();
178 const long long words_per_qubitormeas = (shots + 31) / 32;
179 const long long numQubits = GetNumQubits();
180 std::vector<unsigned int> xTableRaw(numQubits * words_per_qubitormeas, 0);
181 for (long long qubit = 0; qubit < numQubits; ++qubit)
182 {
183 for (long long shot = 0; shot < shots; ++shot)
184 {
185 if (xTable[qubit])
186 {
187 xTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |= (1U << (shot % 32));
188 }
189 }
190 }
191
192 return lib->InitStabilizerXTable(obj, xTableRaw.data()) == 1;
193 }
194
195 bool InitZTable(const std::vector<std::vector<bool>> &zTable)
196 {
197 if (!obj)
198 return false;
199 const long long shots = GetNumShots();
200 const long long words_per_qubitormeas = (shots + 31) / 32;
201 const long long numQubits = GetNumQubits();
202 std::vector<unsigned int> zTableRaw(numQubits * words_per_qubitormeas, 0);
203 for (long long qubit = 0; qubit < numQubits; ++qubit)
204 {
205 for (long long shot = 0; shot < shots; ++shot)
206 {
207 if (zTable[qubit][shot])
208 {
209 zTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |= (1U << (shot % 32));
210 }
211 }
212 }
213 return lib->InitStabilizerZTable(obj, zTableRaw.data()) == 1;
214 }
215
216 bool InitZTableRepeat(const std::vector<bool> &zTable)
217 {
218 // repeat zTable for all shots
219 if (!obj)
220 return false;
221 const long long shots = GetNumShots();
222 const long long words_per_qubitormeas = (shots + 31) / 32;
223 const long long numQubits = GetNumQubits();
224 std::vector<unsigned int> zTableRaw(numQubits * words_per_qubitormeas, 0);
225 for (long long qubit = 0; qubit < numQubits; ++qubit)
226 {
227 for (long long shot = 0; shot < shots; ++shot)
228 {
229 if (zTable[qubit])
230 {
231 zTableRaw[qubit * words_per_qubitormeas + (shot / 32)] |= (1U << (shot % 32));
232 }
233 }
234 }
235 return lib->InitStabilizerZTable(obj, zTableRaw.data()) == 1;
236 }
237
238 protected:
239 std::vector<std::vector<bool>> ConvertToBoolVectorVector(const std::vector<unsigned int> &tableRaw, long long int num, long long int shots)
240 {
241 const long long words_per_qubitormeas = (shots + 31) / 32;
242
243 std::vector<std::vector<bool>> result(num);
244
245 for (long long qubitormeas = 0; qubitormeas < num; ++qubitormeas)
246 {
247 for (long long shot = 0; shot < shots; ++shot)
248 {
249 const unsigned int word = tableRaw[qubitormeas * words_per_qubitormeas + (shot / 32)];
250 const bool bit = ((word >> (shot % 32)) & 1) == 1;
251 result[qubitormeas].push_back(bit);
252 }
253 }
254
255 return result;
256 }
257
258 long long GetStabilizerXZTableSize()
259 {
260 if (obj)
261 return lib->GetStabilizerXZTableSize(obj);
262 return 0;
263 }
264
265 long long GetStabilizerMTableSize()
266 {
267 if (obj)
268 return lib->GetStabilizerMTableSize(obj);
269 return 0;
270 }
271
272 long long GetStabilizerTableStrideMajor()
273 {
274 if (obj)
275 return lib->GetStabilizerTableStrideMajor(obj);
276 return 0;
277 }
278
279 private:
280 int device; // Fixed even when native creation is delayed or repeated.
281 GpuDeviceContext lib;
282 void *obj;
283};
284
285} // namespace Simulators
286
287#endif
288#endif
unsigned long int CreateSimulator(int simType, int simExecType)
Bounded online routing based on current physical bond dimensions.