Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
GpuLibMPSSim.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#ifndef _GPU_LIB_MPS_SIM_H_
16#define _GPU_LIB_MPS_SIM_H_
17
18#ifdef __linux__
19
20#include <memory>
21#include <vector>
22
23#include "GpuDeviceContext.h"
24
25namespace Simulators {
26
27class GpuLibMPSSim {
28 public:
29 explicit GpuLibMPSSim(const std::shared_ptr<GpuLibrary>& lib, int device = -1)
30 : lib(lib), obj(nullptr) {
31 if (lib) {
32 auto lock = lib->LockInitialization();
33 if (lib->SetGpuDevice(device == -1 ? lib->GetCreationDevice() : device))
34 obj = lib->CreateMPS();
35 }
36 }
37
38 int GetGpuDevice() const { return lib ? lib->MPSGetGpuId(obj) : -1; }
39
40 GpuLibMPSSim(const std::shared_ptr<GpuLibrary> &lib, void *obj)
41 : lib(lib), obj(obj) {}
42
43 GpuLibMPSSim() = delete;
44 GpuLibMPSSim(const GpuLibMPSSim &) = delete;
45 GpuLibMPSSim &operator=(const GpuLibMPSSim &) = delete;
46 GpuLibMPSSim(GpuLibMPSSim &&) = default;
47 GpuLibMPSSim &operator=(GpuLibMPSSim &&) = default;
48
49 ~GpuLibMPSSim() {
50 if (lib && obj) lib->DestroyMPS(obj);
51 }
52
53 bool Create(unsigned int nrQubits) {
54 if (obj) return lib->MPSCreate(obj, nrQubits);
55
56 return false;
57 }
58
59 bool CreateWithBasisState(unsigned int nrQubits, unsigned long long state) {
60 if (obj) return lib->MPSCreateWithBasisState(obj, nrQubits, state);
61
62 return false;
63 }
64
65 bool CreateWithBasisStateBits(unsigned int nrQubits,
66 const std::vector<unsigned char> &stateBits) {
67 if (obj)
68 return lib->MPSCreateWithBasisStateBits(obj, nrQubits,
69 stateBits.data());
70
71 return false;
72 }
73
74 bool Reset() {
75 if (obj) return lib->MPSReset(obj);
76
77 return false;
78 }
79
80 bool SetSeed(uint64_t seed) { return obj && lib->MPSSetSeed(obj, seed); }
81
82 bool SetInitialQubitsMap(const std::vector<long long int> &initialMap) {
83 if (obj) return lib->MPSSetInitialQubitsMap(obj, initialMap);
84
85 return false;
86 }
87
88 bool SetUseOptimalMeetingPosition(bool useOptimalMeetingPosition) {
89 if (obj) return lib->MPSSetUseOptimalMeetingPosition(obj, useOptimalMeetingPosition);
90 return false;
91 }
92
93 bool GetUseOptimalMeetingPosition() const {
94 if (obj) return lib->MPSGetUseOptimalMeetingPosition(obj);
95 return false;
96 }
97
98 bool IsValid() const {
99 if (obj) return lib->MPSIsValid(obj);
100
101 return false;
102 }
103
104 bool IsCreated() const {
105 if (obj) return lib->MPSIsCreated(obj);
106
107 return false;
108 }
109
110 bool SetDataType(int useDoublePrecision) {
111 if (obj) return lib->MPSSetDataType(obj, useDoublePrecision);
112
113 return false;
114 }
115
116 bool IsDoublePrecision() const {
117 if (obj) return lib->MPSIsDoublePrecision(obj);
118
119 return false;
120 }
121
122 bool SetCutoff(double val) {
123 if (obj) return lib->MPSSetCutoff(obj, val);
124
125 return false;
126 }
127
128 double GetCutoff() const {
129 if (obj) return lib->MPSGetCutoff(obj);
130
131 return 0.;
132 }
133
134 // mode: 0 = RelativeToMax, 1 = DiscardedWeight (default). See
135 // TruncationMode in the GPU library's lib/truncationmode.hpp.
136 bool SetTruncationMode(int mode) {
137 if (obj) return lib->MPSSetTruncationMode(obj, mode);
138
139 return false;
140 }
141
142 int GetTruncationMode() const {
143 if (obj) return lib->MPSGetTruncationMode(obj);
144
145 return 0;
146 }
147
148 bool SetGesvdJ(int val) {
149 if (obj) return lib->MPSSetGesvdJ(obj, val);
150
151 return false;
152 }
153
154 bool GetGesvdJ() const {
155 if (obj) return lib->MPSGetGesvdJ(obj);
156
157 return false;
158 }
159
160 // Enabling any of J/P/R clears the other two selectors in the plugin.
161 bool SetGesvdP(bool enable) {
162 return obj && lib->MPSSetGesvdP(obj, enable);
163 }
164 bool GetGesvdP() const { return lib->MPSGetGesvdP(obj); }
165 bool SetGesvdR(bool enable) {
166 return obj && lib->MPSSetGesvdR(obj, enable);
167 }
168 bool GetGesvdR() const { return lib->MPSGetGesvdR(obj); }
169 int GetLastSvdAlgo() const { return lib->MPSGetLastSvdAlgo(obj); }
170
171 bool SetMaxExtent(long int val) {
172 if (obj) return lib->MPSSetMaxExtent(obj, val);
173
174 return false;
175 }
176
177 long int GetMaxExtent() const {
178 if (obj) return lib->MPSGetMaxExtent(obj);
179
180 return 0;
181 }
182
183 int GetNrQubits() const {
184 if (obj) return lib->MPSGetNrQubits(obj);
185
186 return 0;
187 }
188
189 std::vector<long long int> GetBondDimensions(size_t nrQubits) const {
190 if (!obj || nrQubits < 2) return {};
191 std::vector<long long int> bondDims(nrQubits - 1);
192 if (!lib->MPSGetBondDimensions(obj, bondDims.data())) return {};
193 return bondDims;
194 }
195
196 bool SetCallbackContext(void *context) {
197 if (obj) return lib->MPSSetCallbackContext(obj, context);
198 return false;
199 }
200
201 bool SetMeetingPositionCallback(int64_t (*callback)(void *, const int64_t *)) {
202 if (obj) return lib->MPSSetMeetingPositionCallback(obj, callback);
203 return false;
204 }
205
206 bool SetBondDimensionsCallback(void (*callback)(void*, const int64_t*)) {
207 if (obj) return lib->MPSSetBondDimensionsCallback(obj, callback);
208 return false;
209 }
210
211 bool Amplitude(long int numFixedValues, long int *fixedValues, double *real,
212 double *imaginary) const {
213 if (obj)
214 return lib->MPSAmplitude(obj, numFixedValues, fixedValues, real,
215 imaginary);
216
217 return false;
218 }
219
220 double Probability0(unsigned int qubit) const {
221 if (obj) return lib->MPSProbability0(obj, qubit);
222
223 return 0.;
224 }
225
226 bool Measure(unsigned int qubit) {
227 if (obj) return lib->MPSMeasure(obj, qubit);
228
229 return 0;
230 }
231
232 bool MeasureQubits(long int numQubits, unsigned int *qubits, int *result) {
233 if (obj) return lib->MPSMeasureQubits(obj, numQubits, qubits, result);
234
235 return false;
236 }
237
238 std::unordered_map<std::vector<bool>, int64_t> *GetMapForSample() const {
239 if (lib) return lib->MPSGetMapForSample();
240
241 return nullptr;
242 }
243
244 bool FreeMapForSample(
245 std::unordered_map<std::vector<bool>, int64_t> *map) const {
246 if (lib) return lib->MPSFreeMapForSample(map);
247
248 return false;
249 }
250
251 bool Sample(long int numShots, long int numQubits, unsigned int *qubits,
252 void *resultMap) {
253 if (obj) return lib->MPSSample(obj, numShots, numQubits, qubits, resultMap);
254
255 return false;
256 }
257
258 bool SampleRaw(unsigned int nSamples, long int *samples, unsigned int nBits,
259 const unsigned int *bitOrdering) {
260 if (obj)
261 return lib->MPSSampleRaw(obj, nSamples, samples, nBits, bitOrdering);
262
263 return false;
264 }
265
266 bool SampleAll(unsigned int nSamples, long int *samples) {
267 if (obj) return lib->MPSSampleAll(obj, nSamples, samples);
268
269 return false;
270 }
271
272 bool SaveState() {
273 if (obj) return lib->MPSSaveState(obj);
274
275 return false;
276 }
277
278 bool RestoreState() {
279 if (obj) return lib->MPSRestoreState(obj);
280
281 return false;
282 }
283
284 bool CleanSavedState() {
285 if (obj) return lib->MPSCleanSavedState(obj);
286
287 return false;
288 }
289
290 std::unique_ptr<GpuLibMPSSim> Clone() const {
291 if (obj) return std::make_unique<GpuLibMPSSim>(lib, lib->MPSClone(obj));
292
293 return nullptr;
294 }
295
296 double ExpectationValue(const std::string &pauliString) {
297 if (obj)
298 return lib->MPSExpectationValue(obj, pauliString.c_str(),
299 pauliString.length());
300
301 return 0.0;
302 }
303
304 std::complex<double> ProjectOnZero() {
305 if (obj) return lib->MPSProjectOnZero(obj);
306
307 return std::complex<double>(0., 0.);
308 }
309
310 bool ApplyX(unsigned int siteA) {
311 if (obj) return lib->MPSApplyX(obj, siteA);
312
313 return false;
314 }
315
316 bool ApplyY(unsigned int siteA) {
317 if (obj) return lib->MPSApplyY(obj, siteA);
318
319 return false;
320 }
321
322 bool ApplyZ(unsigned int siteA) {
323 if (obj) return lib->MPSApplyZ(obj, siteA);
324
325 return false;
326 }
327
328 bool ApplyH(unsigned int siteA) {
329 if (obj) return lib->MPSApplyH(obj, siteA);
330
331 return false;
332 }
333
334 bool ApplyS(unsigned int siteA) {
335 if (obj) return lib->MPSApplyS(obj, siteA);
336
337 return false;
338 }
339
340 bool ApplySDG(unsigned int siteA) {
341 if (obj) return lib->MPSApplySDG(obj, siteA);
342
343 return false;
344 }
345
346 bool ApplyT(unsigned int siteA) {
347 if (obj) return lib->MPSApplyT(obj, siteA);
348
349 return false;
350 }
351
352 bool ApplyTDG(unsigned int siteA) {
353 if (obj) return lib->MPSApplyTDG(obj, siteA);
354
355 return false;
356 }
357
358 bool ApplySX(unsigned int siteA) {
359 if (obj) return lib->MPSApplySX(obj, siteA);
360
361 return false;
362 }
363
364 bool ApplySXDG(unsigned int siteA) {
365 if (obj) return lib->MPSApplySXDG(obj, siteA);
366
367 return false;
368 }
369
370 bool ApplyK(unsigned int siteA) {
371 if (obj) return lib->MPSApplyK(obj, siteA);
372
373 return false;
374 }
375
376 bool ApplyP(unsigned int siteA, double theta) {
377 if (obj) return lib->MPSApplyP(obj, siteA, theta);
378
379 return false;
380 }
381
382 bool ApplyRx(unsigned int siteA, double theta) {
383 if (obj) return lib->MPSApplyRx(obj, siteA, theta);
384
385 return false;
386 }
387
388 bool ApplyRy(unsigned int siteA, double theta) {
389 if (obj) return lib->MPSApplyRy(obj, siteA, theta);
390
391 return false;
392 }
393
394 bool ApplyRz(unsigned int siteA, double theta) {
395 if (obj) return lib->MPSApplyRz(obj, siteA, theta);
396
397 return false;
398 }
399
400 bool ApplyU(unsigned int siteA, double theta, double phi, double lambda,
401 double gamma) {
402 if (obj) return lib->MPSApplyU(obj, siteA, theta, phi, lambda, gamma);
403
404 return false;
405 }
406
407 bool ApplyOneQubitMatrix(unsigned int qubit,
408 const double *matrixInterleaved) {
409 if (obj) return lib->MPSApplyOneQubitMatrix(obj, qubit, matrixInterleaved);
410
411 return false;
412 }
413
414 bool ApplyTwoQubitMatrix(unsigned int qubit1, unsigned int qubit2,
415 const double *matrixInterleaved) {
416 if (obj)
417 return lib->MPSApplyTwoQubitMatrix(obj, qubit1, qubit2,
418 matrixInterleaved);
419
420 return false;
421 }
422
423 bool ApplySwap(unsigned int controlQubit, unsigned int targetQubit) {
424 if (obj) return lib->MPSApplySwap(obj, controlQubit, targetQubit);
425
426 return false;
427 }
428
429 bool ApplyCX(unsigned int controlQubit, unsigned int targetQubit) {
430 if (obj) return lib->MPSApplyCX(obj, controlQubit, targetQubit);
431
432 return false;
433 }
434
435 bool ApplyCY(unsigned int controlQubit, unsigned int targetQubit) {
436 if (obj) return lib->MPSApplyCY(obj, controlQubit, targetQubit);
437
438 return false;
439 }
440
441 bool ApplyCZ(unsigned int controlQubit, unsigned int targetQubit) {
442 if (obj) return lib->MPSApplyCZ(obj, controlQubit, targetQubit);
443
444 return false;
445 }
446
447 bool ApplyCH(unsigned int controlQubit, unsigned int targetQubit) {
448 if (obj) return lib->MPSApplyCH(obj, controlQubit, targetQubit);
449
450 return false;
451 }
452
453 bool ApplyCSX(unsigned int controlQubit, unsigned int targetQubit) {
454 if (obj) return lib->MPSApplyCSX(obj, controlQubit, targetQubit);
455
456 return false;
457 }
458
459 bool ApplyCSXDG(unsigned int controlQubit, unsigned int targetQubit) {
460 if (obj) return lib->MPSApplyCSXDG(obj, controlQubit, targetQubit);
461
462 return false;
463 }
464
465 bool ApplyCP(unsigned int controlQubit, unsigned int targetQubit,
466 double theta) {
467 if (obj) return lib->MPSApplyCP(obj, controlQubit, targetQubit, theta);
468
469 return false;
470 }
471
472 bool ApplyCRx(unsigned int controlQubit, unsigned int targetQubit,
473 double theta) {
474 if (obj) return lib->MPSApplyCRx(obj, controlQubit, targetQubit, theta);
475
476 return false;
477 }
478
479 bool ApplyCRy(unsigned int controlQubit, unsigned int targetQubit,
480 double theta) {
481 if (obj) return lib->MPSApplyCRy(obj, controlQubit, targetQubit, theta);
482
483 return false;
484 }
485
486 bool ApplyCRz(unsigned int controlQubit, unsigned int targetQubit,
487 double theta) {
488 if (obj) return lib->MPSApplyCRz(obj, controlQubit, targetQubit, theta);
489
490 return false;
491 }
492
493 bool ApplyCU(unsigned int controlQubit, unsigned int targetQubit,
494 double theta, double phi, double lambda, double gamma) {
495 if (obj)
496 return lib->MPSApplyCU(obj, controlQubit, targetQubit, theta, phi, lambda,
497 gamma);
498
499 return false;
500 }
501
502 private:
503 GpuDeviceContext lib;
504 void *obj;
505};
506
507} // namespace Simulators
508
509#endif // __linux__
510
511#endif // _GPU_LIB_MPS_SIM_H_
int ApplyK(void *sim, int qubit)
int RestoreState(void *sim)
int ApplyRx(void *sim, int qubit, double theta)
int ApplyX(void *sim, int qubit)
int ApplyU(void *sim, int qubit, double theta, double phi, double lambda, double gamma)
int ApplyCRy(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyTDG(void *sim, int qubit)
int ApplyCSXDG(void *sim, int controlQubit, int targetQubit)
int ApplyS(void *sim, int qubit)
int ApplyCX(void *sim, int controlQubit, int targetQubit)
int ApplyCRz(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int ApplySXDG(void *sim, int qubit)
int ApplySDG(void *sim, int qubit)
unsigned long long int Measure(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
int ApplyY(void *sim, int qubit)
double * Amplitude(void *sim, unsigned long long int outcome)
int ApplyZ(void *sim, int qubit)
int ApplyH(void *sim, int qubit)
int ApplyCY(void *sim, int controlQubit, int targetQubit)
int ApplyCU(void *sim, int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma)
int ApplySwap(void *sim, int qubit1, int qubit2)
int ApplyRy(void *sim, int qubit, double theta)
int ApplyP(void *sim, int qubit, double theta)
int ApplyCH(void *sim, int controlQubit, int targetQubit)
int ApplySX(void *sim, int qubit)
int ApplyCZ(void *sim, int controlQubit, int targetQubit)
int ApplyRz(void *sim, int qubit, double theta)
int ApplyT(void *sim, int qubit)
int ApplyCRx(void *sim, int controlQubit, int targetQubit, double theta)
int ApplyCSX(void *sim, int controlQubit, int targetQubit)
int SaveState(void *sim)