Maestro 0.3.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
DistributedGpuLibStateVectorSim.h
Go to the documentation of this file.
1// Owns one distributed state and keeps its originating plugin alive.
2#pragma once
3#ifdef __linux__
5#include <cmath>
6#include <utility>
7
8namespace Simulators
9{
10class DistributedGpuLibStateVectorSim
11{
12 public:
13 DistributedGpuLibStateVectorSim(std::shared_ptr<DistributedGpuLibrary> lib, void *obj) : lib(std::move(lib)), obj(obj)
14 {
15 if (!obj)
16 throw std::runtime_error("Null distributed GPU state");
17 }
18
19 virtual ~DistributedGpuLibStateVectorSim()
20 {
21 lib->DestroyNative(obj);
22 }
23
24 DistributedGpuLibStateVectorSim(const DistributedGpuLibStateVectorSim &) = delete;
25 DistributedGpuLibStateVectorSim &operator=(const DistributedGpuLibStateVectorSim &) = delete;
26
27 DistributedGpuLibStateVectorSim(DistributedGpuLibStateVectorSim &&other) noexcept : lib(other.lib), obj(std::exchange(other.obj, nullptr))
28 {
29 }
30
31 DistributedGpuLibStateVectorSim &operator=(DistributedGpuLibStateVectorSim &&) = delete;
32
33 std::unique_ptr<DistributedGpuLibStateVectorSim> Clone() const
34 {
35 return std::make_unique<DistributedGpuLibStateVectorSim>(lib, lib->CloneNative(obj));
36 }
37
38 int GetBackend() const
39 {
40 auto result = lib->GetBackend(obj);
41 if (result < 0)
42 lib->Fail("GetBackend");
43 const char *error = lib->GetLastError();
44 if (error && *error)
45 throw std::runtime_error(error);
46 return result;
47 }
48
49 int SetExExecutionConfig(const DistributedGpuApi::MgdExExecutionConfig *config) const
50 {
51 auto result = lib->SetExExecutionConfig(obj, config);
52 lib->Check(result, "SetExExecutionConfig");
53 return result;
54 }
55
56 int SetDataType(int useDoublePrecision) const
57 {
58 auto result = lib->SetDataType(obj, useDoublePrecision);
59 lib->Check(result, "SetDataType");
60 return result;
61 }
62
63 int SetSeed(unsigned long long seed) const
64 {
65 auto result = lib->SetSeed(obj, seed);
66 lib->Check(result, "SetSeed");
67 return result;
68 }
69
70 int IsDoublePrecision() const
71 {
72 auto result = lib->IsDoublePrecision(obj);
73 const char *error = lib->GetLastError();
74 if (error && *error)
75 throw std::runtime_error(error);
76 return result;
77 }
78
79 int GetNrQubits() const
80 {
81 auto result = lib->GetNrQubits(obj);
82 if (result < 0)
83 lib->Fail("GetNrQubits");
84 const char *error = lib->GetLastError();
85 if (error && *error)
86 throw std::runtime_error(error);
87 return result;
88 }
89
90 int GetStateVectorGpuId() const
91 {
92 auto result = lib->GetStateVectorGpuId(obj);
93 const char *error = lib->GetLastError();
94 if (error && *error)
95 throw std::runtime_error(error);
96 return result;
97 }
98
99 int Create(unsigned int nrQubits) const
100 {
101 auto result = lib->Create(obj, nrQubits);
102 lib->Check(result, "Create");
103 return result;
104 }
105
106 int CreateWithState(unsigned int nrQubits, const double *state) const
107 {
108 auto result = lib->CreateWithState(obj, nrQubits, state);
109 lib->Check(result, "CreateWithState");
110 return result;
111 }
112
113 int Reset() const
114 {
115 auto result = lib->Reset(obj);
116 lib->Check(result, "Reset");
117 return result;
118 }
119
120 int MeasureQubitCollapse(int qubitIndex) const
121 {
122 auto result = lib->MeasureQubitCollapse(obj, qubitIndex);
123 if (result != 0 && result != 1)
124 lib->Fail("MeasureQubitCollapse");
125 return result;
126 }
127
128 int MeasureQubitNoCollapse(int qubitIndex) const
129 {
130 auto result = lib->MeasureQubitNoCollapse(obj, qubitIndex);
131 if (result != 0 && result != 1)
132 lib->Fail("MeasureQubitNoCollapse");
133 return result;
134 }
135
136 int MeasureQubitsCollapse(int *qubits, int *bitstring, int bitstringLen) const
137 {
138 auto result = lib->MeasureQubitsCollapse(obj, qubits, bitstring, bitstringLen);
139 lib->Check(result, "MeasureQubitsCollapse");
140 return result;
141 }
142
143 int MeasureQubitsNoCollapse(int *qubits, int *bitstring, int bitstringLen) const
144 {
145 auto result = lib->MeasureQubitsNoCollapse(obj, qubits, bitstring, bitstringLen);
146 lib->Check(result, "MeasureQubitsNoCollapse");
147 return result;
148 }
149
150 unsigned long long MeasureAllQubitsCollapse() const
151 {
152 auto result = lib->MeasureAllQubitsCollapse(obj);
153 if (result == UINT64_MAX)
154 lib->Fail("MeasureAllQubitsCollapse");
155 return result;
156 }
157
158 unsigned long long MeasureAllQubitsNoCollapse() const
159 {
160 auto result = lib->MeasureAllQubitsNoCollapse(obj);
161 if (result == UINT64_MAX)
162 lib->Fail("MeasureAllQubitsNoCollapse");
163 return result;
164 }
165
166 int SaveState() const
167 {
168 auto result = lib->SaveState(obj);
169 lib->Check(result, "SaveState");
170 return result;
171 }
172
173 int SaveStateToHost() const
174 {
175 auto result = lib->SaveStateToHost(obj);
176 lib->Check(result, "SaveStateToHost");
177 return result;
178 }
179
180 int SaveStateDestructive() const
181 {
182 auto result = lib->SaveStateDestructive(obj);
183 lib->Check(result, "SaveStateDestructive");
184 return result;
185 }
186
187 int RestoreStateFreeSaved() const
188 {
189 auto result = lib->RestoreStateFreeSaved(obj);
190 lib->Check(result, "RestoreStateFreeSaved");
191 return result;
192 }
193
194 int RestoreStateNoFreeSaved() const
195 {
196 auto result = lib->RestoreStateNoFreeSaved(obj);
197 lib->Check(result, "RestoreStateNoFreeSaved");
198 return result;
199 }
200
201 void FreeSavedState() const
202 {
203 lib->FreeSavedState(obj);
204 const char *error = lib->GetLastError();
205 if (error && *error)
206 throw std::runtime_error(error);
207 }
208
209 int Sample(unsigned int nSamples, long int *samples, unsigned int nBits, int *bitOrdering) const
210 {
211 auto result = lib->Sample(obj, nSamples, samples, nBits, bitOrdering);
212 lib->Check(result, "Sample");
213 return result;
214 }
215
216 int SampleAll(unsigned int nSamples, long int *samples) const
217 {
218 auto result = lib->SampleAll(obj, nSamples, samples);
219 lib->Check(result, "SampleAll");
220 return result;
221 }
222
223 int Amplitude(long long int state, double *real, double *imaginary) const
224 {
225 auto result = lib->Amplitude(obj, state, real, imaginary);
226 lib->Check(result, "Amplitude");
227 return result;
228 }
229
230 double Probability(int *qubits, int *mask, int len) const
231 {
232 auto result = lib->Probability(obj, qubits, mask, len);
233 if (!std::isfinite(result))
234 lib->Fail("Probability");
235 return result;
236 }
237
238 double BasisStateProbability(long long int state) const
239 {
240 auto result = lib->BasisStateProbability(obj, state);
241 if (!std::isfinite(result))
242 lib->Fail("BasisStateProbability");
243 return result;
244 }
245
246 int AllProbabilities(double *probabilities) const
247 {
248 auto result = lib->AllProbabilities(obj, probabilities);
249 lib->Check(result, "AllProbabilities");
250 return result;
251 }
252
253 double ExpectationValue(const char *pauliString, int len) const
254 {
255 auto result = lib->ExpectationValue(obj, pauliString, len);
256 if (!std::isfinite(result))
257 lib->Fail("ExpectationValue");
258 return result;
259 }
260
261 int ApplyX(int qubit) const
262 {
263 auto result = lib->ApplyX(obj, qubit);
264 lib->Check(result, "ApplyX");
265 return result;
266 }
267
268 int ApplyY(int qubit) const
269 {
270 auto result = lib->ApplyY(obj, qubit);
271 lib->Check(result, "ApplyY");
272 return result;
273 }
274
275 int ApplyZ(int qubit) const
276 {
277 auto result = lib->ApplyZ(obj, qubit);
278 lib->Check(result, "ApplyZ");
279 return result;
280 }
281
282 int ApplyH(int qubit) const
283 {
284 auto result = lib->ApplyH(obj, qubit);
285 lib->Check(result, "ApplyH");
286 return result;
287 }
288
289 int ApplyS(int qubit) const
290 {
291 auto result = lib->ApplyS(obj, qubit);
292 lib->Check(result, "ApplyS");
293 return result;
294 }
295
296 int ApplySDG(int qubit) const
297 {
298 auto result = lib->ApplySDG(obj, qubit);
299 lib->Check(result, "ApplySDG");
300 return result;
301 }
302
303 int ApplyT(int qubit) const
304 {
305 auto result = lib->ApplyT(obj, qubit);
306 lib->Check(result, "ApplyT");
307 return result;
308 }
309
310 int ApplyTDG(int qubit) const
311 {
312 auto result = lib->ApplyTDG(obj, qubit);
313 lib->Check(result, "ApplyTDG");
314 return result;
315 }
316
317 int ApplySX(int qubit) const
318 {
319 auto result = lib->ApplySX(obj, qubit);
320 lib->Check(result, "ApplySX");
321 return result;
322 }
323
324 int ApplySXDG(int qubit) const
325 {
326 auto result = lib->ApplySXDG(obj, qubit);
327 lib->Check(result, "ApplySXDG");
328 return result;
329 }
330
331 int ApplyK(int qubit) const
332 {
333 auto result = lib->ApplyK(obj, qubit);
334 lib->Check(result, "ApplyK");
335 return result;
336 }
337
338 int ApplyP(int qubit, double theta) const
339 {
340 auto result = lib->ApplyP(obj, qubit, theta);
341 lib->Check(result, "ApplyP");
342 return result;
343 }
344
345 int ApplyRx(int qubit, double theta) const
346 {
347 auto result = lib->ApplyRx(obj, qubit, theta);
348 lib->Check(result, "ApplyRx");
349 return result;
350 }
351
352 int ApplyRy(int qubit, double theta) const
353 {
354 auto result = lib->ApplyRy(obj, qubit, theta);
355 lib->Check(result, "ApplyRy");
356 return result;
357 }
358
359 int ApplyRz(int qubit, double theta) const
360 {
361 auto result = lib->ApplyRz(obj, qubit, theta);
362 lib->Check(result, "ApplyRz");
363 return result;
364 }
365
366 int ApplyU(int qubit, double theta, double phi, double lambda, double gamma) const
367 {
368 auto result = lib->ApplyU(obj, qubit, theta, phi, lambda, gamma);
369 lib->Check(result, "ApplyU");
370 return result;
371 }
372
373 int ApplyCX(int controlQubit, int targetQubit) const
374 {
375 auto result = lib->ApplyCX(obj, controlQubit, targetQubit);
376 lib->Check(result, "ApplyCX");
377 return result;
378 }
379
380 int ApplyCY(int controlQubit, int targetQubit) const
381 {
382 auto result = lib->ApplyCY(obj, controlQubit, targetQubit);
383 lib->Check(result, "ApplyCY");
384 return result;
385 }
386
387 int ApplyCZ(int controlQubit, int targetQubit) const
388 {
389 auto result = lib->ApplyCZ(obj, controlQubit, targetQubit);
390 lib->Check(result, "ApplyCZ");
391 return result;
392 }
393
394 int ApplyCH(int controlQubit, int targetQubit) const
395 {
396 auto result = lib->ApplyCH(obj, controlQubit, targetQubit);
397 lib->Check(result, "ApplyCH");
398 return result;
399 }
400
401 int ApplyCSX(int controlQubit, int targetQubit) const
402 {
403 auto result = lib->ApplyCSX(obj, controlQubit, targetQubit);
404 lib->Check(result, "ApplyCSX");
405 return result;
406 }
407
408 int ApplyCSXDG(int controlQubit, int targetQubit) const
409 {
410 auto result = lib->ApplyCSXDG(obj, controlQubit, targetQubit);
411 lib->Check(result, "ApplyCSXDG");
412 return result;
413 }
414
415 int ApplyCP(int controlQubit, int targetQubit, double theta) const
416 {
417 auto result = lib->ApplyCP(obj, controlQubit, targetQubit, theta);
418 lib->Check(result, "ApplyCP");
419 return result;
420 }
421
422 int ApplyCRx(int controlQubit, int targetQubit, double theta) const
423 {
424 auto result = lib->ApplyCRx(obj, controlQubit, targetQubit, theta);
425 lib->Check(result, "ApplyCRx");
426 return result;
427 }
428
429 int ApplyCRy(int controlQubit, int targetQubit, double theta) const
430 {
431 auto result = lib->ApplyCRy(obj, controlQubit, targetQubit, theta);
432 lib->Check(result, "ApplyCRy");
433 return result;
434 }
435
436 int ApplyCRz(int controlQubit, int targetQubit, double theta) const
437 {
438 auto result = lib->ApplyCRz(obj, controlQubit, targetQubit, theta);
439 lib->Check(result, "ApplyCRz");
440 return result;
441 }
442
443 int ApplyCCX(int controlQubit1, int controlQubit2, int targetQubit) const
444 {
445 auto result = lib->ApplyCCX(obj, controlQubit1, controlQubit2, targetQubit);
446 lib->Check(result, "ApplyCCX");
447 return result;
448 }
449
450 int ApplySwap(int qubit1, int qubit2) const
451 {
452 auto result = lib->ApplySwap(obj, qubit1, qubit2);
453 lib->Check(result, "ApplySwap");
454 return result;
455 }
456
457 int ApplyCSwap(int controlQubit, int qubit1, int qubit2) const
458 {
459 auto result = lib->ApplyCSwap(obj, controlQubit, qubit1, qubit2);
460 lib->Check(result, "ApplyCSwap");
461 return result;
462 }
463
464 int ApplyCU(int controlQubit, int targetQubit, double theta, double phi, double lambda, double gamma) const
465 {
466 auto result = lib->ApplyCU(obj, controlQubit, targetQubit, theta, phi, lambda, gamma);
467 lib->Check(result, "ApplyCU");
468 return result;
469 }
470
471 int ConfigureDistribution(const DistributedGpuApi::MgdDistributionConfig *config) const
472 {
473 auto result = lib->ConfigureDistribution(obj, config);
474 lib->Check(result, "ConfigureDistribution");
475 return result;
476 }
477
478 int GetShardDevices(int32_t *devices, uint32_t capacity) const
479 {
480 auto result = lib->GetShardDevices(obj, devices, capacity);
481 if (result < 0)
482 lib->Fail("GetShardDevices");
483 const char *error = lib->GetLastError();
484 if (error && *error)
485 throw std::runtime_error(error);
486 return result;
487 }
488
489 int GetGlobalQubits(int32_t *qubits, uint32_t capacity) const
490 {
491 auto result = lib->GetGlobalQubits(obj, qubits, capacity);
492 if (result < 0)
493 lib->Fail("GetGlobalQubits");
494 const char *error = lib->GetLastError();
495 if (error && *error)
496 throw std::runtime_error(error);
497 return result;
498 }
499
500 int GetQubitLayout(int32_t *wires, uint32_t capacity) const
501 {
502 auto result = lib->GetQubitLayout(obj, wires, capacity);
503 if (result < 0)
504 lib->Fail("GetQubitLayout");
505 const char *error = lib->GetLastError();
506 if (error && *error)
507 throw std::runtime_error(error);
508 return result;
509 }
510
511 int Redistribute(const int32_t *global_qubits, uint32_t count) const
512 {
513 auto result = lib->Redistribute(obj, global_qubits, count);
514 lib->Check(result, "Redistribute");
515 return result;
516 }
517
518 int SwapGlobalLocalQubits(const int32_t *global_qubits, const int32_t *local_qubits, uint32_t count) const
519 {
520 auto result = lib->SwapGlobalLocalQubits(obj, global_qubits, local_qubits, count);
521 lib->Check(result, "SwapGlobalLocalQubits");
522 return result;
523 }
524
525 int Synchronize() const
526 {
527 auto result = lib->Synchronize(obj);
528 lib->Check(result, "Synchronize");
529 return result;
530 }
531
532 int GetStateRange(uint64_t begin, uint64_t end, double *output) const
533 {
534 auto result = lib->GetStateRange(obj, begin, end, output);
535 lib->Check(result, "GetStateRange");
536 return result;
537 }
538
539 int SetStateRange(uint64_t begin, uint64_t end, const double *input) const
540 {
541 auto result = lib->SetStateRange(obj, begin, end, input);
542 lib->Check(result, "SetStateRange");
543 return result;
544 }
545
546 int GetLocalStateBounds(uint64_t *begin, uint64_t *end) const
547 {
548 auto result = lib->GetLocalStateBounds(obj, begin, end);
549 lib->Check(result, "GetLocalStateBounds");
550 return result;
551 }
552
553 int GetLocalStateRange(uint64_t begin, uint64_t end, double *output) const
554 {
555 auto result = lib->GetLocalStateRange(obj, begin, end, output);
556 lib->Check(result, "GetLocalStateRange");
557 return result;
558 }
559
560 int SetLocalStateRange(uint64_t begin, uint64_t end, const double *input) const
561 {
562 auto result = lib->SetLocalStateRange(obj, begin, end, input);
563 lib->Check(result, "SetLocalStateRange");
564 return result;
565 }
566
567 int CreateWithBasisState(uint32_t nrQubits, uint64_t basis) const
568 {
569 auto result = lib->CreateWithBasisState(obj, nrQubits, basis);
570 lib->Check(result, "CreateWithBasisState");
571 return result;
572 }
573
574 int ApplyOneQubitMatrix(int qubit, const double *matrix) const
575 {
576 auto result = lib->ApplyOneQubitMatrix(obj, qubit, matrix);
577 lib->Check(result, "ApplyOneQubitMatrix");
578 return result;
579 }
580
581 int ApplyOneQubitMatrixWithLayout(int qubit, const double *matrix, int layout) const
582 {
583 auto result = lib->ApplyOneQubitMatrixWithLayout(obj, qubit, matrix, layout);
584 lib->Check(result, "ApplyOneQubitMatrixWithLayout");
585 return result;
586 }
587
588 int ApplyTwoQubitMatrix(int qubit0, int qubit1, const double *matrix) const
589 {
590 auto result = lib->ApplyTwoQubitMatrix(obj, qubit0, qubit1, matrix);
591 lib->Check(result, "ApplyTwoQubitMatrix");
592 return result;
593 }
594
595 int ApplyTwoQubitMatrixWithLayout(int qubit0, int qubit1, const double *matrix, int layout) const
596 {
597 auto result = lib->ApplyTwoQubitMatrixWithLayout(obj, qubit0, qubit1, matrix, layout);
598 lib->Check(result, "ApplyTwoQubitMatrixWithLayout");
599 return result;
600 }
601
602 int ApplyThreeQubitMatrix(int qubit0, int qubit1, int qubit2, const double *matrix) const
603 {
604 if (!lib->ApplyThreeQubitMatrix)
605 throw std::runtime_error("Update the distributed GPU plugin to apply three-qubit matrices");
606 auto result = lib->ApplyThreeQubitMatrix(obj, qubit0, qubit1, qubit2, matrix);
607 lib->Check(result, "ApplyThreeQubitMatrix");
608 return result;
609 }
610
611 int ApplyThreeQubitMatrixWithLayout(int qubit0, int qubit1, int qubit2, const double *matrix, int layout) const
612 {
613 if (!lib->ApplyThreeQubitMatrixWithLayout)
614 throw std::runtime_error("Update the distributed GPU plugin to apply three-qubit matrices");
615 auto result = lib->ApplyThreeQubitMatrixWithLayout(obj, qubit0, qubit1, qubit2, matrix, layout);
616 lib->Check(result, "ApplyThreeQubitMatrixWithLayout");
617 return result;
618 }
619
620 protected:
621 std::shared_ptr<DistributedGpuLibrary> lib;
622 void *obj;
623};
624} // namespace Simulators
625#endif
int ApplyK(void *sim, int qubit)
double Probability(void *sim, unsigned long long int outcome)
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)
double * AllProbabilities(void *sim)
int ApplyCP(void *sim, int controlQubit, int targetQubit, double theta)
int ApplySXDG(void *sim, int qubit)
int ApplySDG(void *sim, int qubit)
int ApplyCSwap(void *sim, int controlQubit, int qubit1, int qubit2)
int ApplyCCX(void *sim, int controlQubit1, int controlQubit2, int targetQubit)
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)
Bounded online routing based on current physical bond dimensions.