15#ifndef _GPUSIMULATOR_H
16#define _GPUSIMULATOR_H
18#ifdef INCLUDED_BY_FACTORY
41class GpuSimulator :
public GpuState {
43 GpuSimulator() =
default;
45 GpuSimulator(
const GpuSimulator &) =
delete;
46 GpuSimulator &operator=(
const GpuSimulator &) =
delete;
49 GpuSimulator(GpuSimulator &&other) =
default;
50 GpuSimulator &operator=(GpuSimulator &&other) =
default;
59 void ApplyP(Types::qubit_t qubit,
double lambda)
override {
61 state->ApplyP(qubit, lambda);
63 mps->ApplyP(qubit, lambda);
65 tn->ApplyP(qubit, lambda);
67 pp->ApplyP(qubit, lambda);
69 NotifyObservers({qubit});
78 void ApplyX(Types::qubit_t qubit)
override {
88 NotifyObservers({qubit});
97 void ApplyY(Types::qubit_t qubit)
override {
107 NotifyObservers({qubit});
116 void ApplyZ(Types::qubit_t qubit)
override {
118 state->ApplyZ(qubit);
126 NotifyObservers({qubit});
135 void ApplyH(Types::qubit_t qubit)
override {
137 state->ApplyH(qubit);
145 NotifyObservers({qubit});
154 void ApplyS(Types::qubit_t qubit)
override {
156 state->ApplyS(qubit);
164 NotifyObservers({qubit});
173 void ApplySDG(Types::qubit_t qubit)
override {
175 state->ApplySDG(qubit);
177 mps->ApplySDG(qubit);
183 NotifyObservers({qubit});
192 void ApplyT(Types::qubit_t qubit)
override {
194 state->ApplyT(qubit);
202 NotifyObservers({qubit});
211 void ApplyTDG(Types::qubit_t qubit)
override {
213 state->ApplyTDG(qubit);
215 mps->ApplyTDG(qubit);
221 NotifyObservers({qubit});
230 void ApplySx(Types::qubit_t qubit)
override {
232 state->ApplySX(qubit);
238 pp->ApplySQRTX(qubit);
240 NotifyObservers({qubit});
249 void ApplySxDAG(Types::qubit_t qubit)
override {
251 state->ApplySXDG(qubit);
253 mps->ApplySXDG(qubit);
255 tn->ApplySXDG(qubit);
257 pp->ApplySxDAG(qubit);
259 NotifyObservers({qubit});
268 void ApplyK(Types::qubit_t qubit)
override {
270 state->ApplyK(qubit);
278 NotifyObservers({qubit});
288 void ApplyRx(Types::qubit_t qubit,
double theta)
override {
290 state->ApplyRx(qubit, theta);
292 mps->ApplyRx(qubit, theta);
294 tn->ApplyRx(qubit, theta);
296 pp->ApplyRX(qubit, theta);
298 NotifyObservers({qubit});
308 void ApplyRy(Types::qubit_t qubit,
double theta)
override {
310 state->ApplyRy(qubit, theta);
312 mps->ApplyRy(qubit, theta);
314 tn->ApplyRy(qubit, theta);
316 pp->ApplyRY(qubit, theta);
318 NotifyObservers({qubit});
328 void ApplyRz(Types::qubit_t qubit,
double theta)
override {
330 state->ApplyRz(qubit, theta);
332 mps->ApplyRz(qubit, theta);
334 tn->ApplyRz(qubit, theta);
336 pp->ApplyRZ(qubit, theta);
338 NotifyObservers({qubit});
348 void ApplyU(Types::qubit_t qubit,
double theta,
double phi,
double lambda,
349 double gamma)
override {
351 state->ApplyU(qubit, theta, phi, lambda, gamma);
353 mps->ApplyU(qubit, theta, phi, lambda, gamma);
355 tn->ApplyU(qubit, theta, phi, lambda, gamma);
357 pp->ApplyU(qubit, theta, phi, lambda, gamma);
359 NotifyObservers({qubit});
369 void ApplyCX(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
371 state->ApplyCX(ctrl_qubit, tgt_qubit);
373 mps->ApplyCX(ctrl_qubit, tgt_qubit);
375 tn->ApplyCX(ctrl_qubit, tgt_qubit);
377 pp->ApplyCX(ctrl_qubit, tgt_qubit);
379 NotifyObservers({tgt_qubit, ctrl_qubit});
389 void ApplyCY(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
391 state->ApplyCY(ctrl_qubit, tgt_qubit);
393 mps->ApplyCY(ctrl_qubit, tgt_qubit);
395 tn->ApplyCY(ctrl_qubit, tgt_qubit);
397 pp->ApplyCY(ctrl_qubit, tgt_qubit);
399 NotifyObservers({tgt_qubit, ctrl_qubit});
409 void ApplyCZ(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
411 state->ApplyCZ(ctrl_qubit, tgt_qubit);
413 mps->ApplyCZ(ctrl_qubit, tgt_qubit);
415 tn->ApplyCZ(ctrl_qubit, tgt_qubit);
417 pp->ApplyCZ(ctrl_qubit, tgt_qubit);
419 NotifyObservers({tgt_qubit, ctrl_qubit});
430 void ApplyCP(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
431 double lambda)
override {
433 state->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
435 mps->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
437 tn->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
439 pp->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
441 NotifyObservers({tgt_qubit, ctrl_qubit});
452 void ApplyCRx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
453 double theta)
override {
455 state->ApplyCRx(ctrl_qubit, tgt_qubit, theta);
457 mps->ApplyCRx(ctrl_qubit, tgt_qubit, theta);
459 tn->ApplyCRx(ctrl_qubit, tgt_qubit, theta);
461 pp->ApplyCRX(ctrl_qubit, tgt_qubit, theta);
463 NotifyObservers({tgt_qubit, ctrl_qubit});
474 void ApplyCRy(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
475 double theta)
override {
477 state->ApplyCRy(ctrl_qubit, tgt_qubit, theta);
479 mps->ApplyCRy(ctrl_qubit, tgt_qubit, theta);
481 tn->ApplyCRy(ctrl_qubit, tgt_qubit, theta);
483 pp->ApplyCRY(ctrl_qubit, tgt_qubit, theta);
485 NotifyObservers({tgt_qubit, ctrl_qubit});
496 void ApplyCRz(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
497 double theta)
override {
499 state->ApplyCRz(ctrl_qubit, tgt_qubit, theta);
501 mps->ApplyCRz(ctrl_qubit, tgt_qubit, theta);
503 tn->ApplyCRz(ctrl_qubit, tgt_qubit, theta);
505 pp->ApplyCRZ(ctrl_qubit, tgt_qubit, theta);
507 NotifyObservers({tgt_qubit, ctrl_qubit});
517 void ApplyCH(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
519 state->ApplyCH(ctrl_qubit, tgt_qubit);
521 mps->ApplyCH(ctrl_qubit, tgt_qubit);
523 tn->ApplyCH(ctrl_qubit, tgt_qubit);
525 pp->ApplyCH(ctrl_qubit, tgt_qubit);
527 NotifyObservers({tgt_qubit, ctrl_qubit});
537 void ApplyCSx(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit)
override {
539 state->ApplyCSX(ctrl_qubit, tgt_qubit);
541 mps->ApplyCSX(ctrl_qubit, tgt_qubit);
543 tn->ApplyCSX(ctrl_qubit, tgt_qubit);
545 pp->ApplyCSX(ctrl_qubit, tgt_qubit);
547 NotifyObservers({tgt_qubit, ctrl_qubit});
557 void ApplyCSxDAG(Types::qubit_t ctrl_qubit,
558 Types::qubit_t tgt_qubit)
override {
560 state->ApplyCSXDG(ctrl_qubit, tgt_qubit);
562 mps->ApplyCSXDG(ctrl_qubit, tgt_qubit);
564 tn->ApplyCSXDG(ctrl_qubit, tgt_qubit);
566 pp->ApplyCSXDAG(ctrl_qubit, tgt_qubit);
568 NotifyObservers({tgt_qubit, ctrl_qubit});
578 void ApplySwap(Types::qubit_t qubit0, Types::qubit_t qubit1)
override {
580 state->ApplySwap(qubit0, qubit1);
582 mps->ApplySwap(qubit0, qubit1);
584 tn->ApplySwap(qubit0, qubit1);
586 pp->ApplySWAP(qubit0, qubit1);
588 NotifyObservers({qubit1, qubit0});
599 void ApplyCCX(Types::qubit_t qubit0, Types::qubit_t qubit1,
600 Types::qubit_t qubit2)
override {
602 state->ApplyCCX(qubit0, qubit1, qubit2);
604 const size_t q1 = qubit0;
605 const size_t q2 = qubit1;
606 const size_t q3 = qubit2;
609 mps->ApplyCSX(
static_cast<unsigned int>(q2),
610 static_cast<unsigned int>(q3));
611 mps->ApplyCX(
static_cast<unsigned int>(q1),
612 static_cast<unsigned int>(q2));
613 mps->ApplyCSXDG(
static_cast<unsigned int>(q2),
614 static_cast<unsigned int>(q3));
615 mps->ApplyCX(
static_cast<unsigned int>(q1),
616 static_cast<unsigned int>(q2));
617 mps->ApplyCSX(
static_cast<unsigned int>(q1),
618 static_cast<unsigned int>(q3));
620 tn->ApplyCCX(qubit0, qubit1, qubit2);
622 pp->ApplyCCX(qubit0, qubit1, qubit2);
624 NotifyObservers({qubit0, qubit1, qubit2});
635 void ApplyCSwap(Types::qubit_t ctrl_qubit, Types::qubit_t qubit0,
636 Types::qubit_t qubit1)
override {
638 state->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
640 const size_t q1 = ctrl_qubit;
641 const size_t q2 = qubit0;
642 const size_t q3 = qubit1;
646 mps->ApplyCX(
static_cast<unsigned int>(q3),
647 static_cast<unsigned int>(q2));
648 mps->ApplyCSX(
static_cast<unsigned int>(q2),
649 static_cast<unsigned int>(q3));
650 mps->ApplyCX(
static_cast<unsigned int>(q1),
651 static_cast<unsigned int>(q2));
653 mps->ApplyP(
static_cast<unsigned int>(q3), M_PI);
654 mps->ApplyP(
static_cast<unsigned int>(q2), -M_PI_2);
656 mps->ApplyCSX(
static_cast<unsigned int>(q2),
657 static_cast<unsigned int>(q3));
658 mps->ApplyCX(
static_cast<unsigned int>(q1),
659 static_cast<unsigned int>(q2));
661 mps->ApplyP(
static_cast<unsigned int>(q3), M_PI);
663 mps->ApplyCSX(
static_cast<unsigned int>(q1),
664 static_cast<unsigned int>(q3));
665 mps->ApplyCX(
static_cast<unsigned int>(q3),
666 static_cast<unsigned int>(q2));
668 tn->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
670 pp->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
672 NotifyObservers({qubit1, qubit0, ctrl_qubit});
686 void ApplyCU(Types::qubit_t ctrl_qubit, Types::qubit_t tgt_qubit,
687 double theta,
double phi,
double lambda,
double gamma)
override {
689 state->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
691 mps->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
693 tn->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
695 pp->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
697 NotifyObservers({tgt_qubit, ctrl_qubit});
707 void ApplyNop()
override {
721 std::unique_ptr<ISimulator> Clone()
override {
723 throw std::runtime_error(
724 "GpuSimulator::Clone: Cloning Tensor Network or Pauli Propagator simulation is not "
728 auto cloned = std::make_unique<GpuSimulator>();
730 cloned->simulationType = simulationType;
731 cloned->nrQubits = nrQubits;
733 cloned->limitSize = limitSize;
734 cloned->limitEntanglement = limitEntanglement;
736 cloned->singularValueThreshold = singularValueThreshold;
739 cloned->state = state->Clone();
741 cloned->mps = mps->Clone();
int ApplyK(void *sim, int qubit)
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 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 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)
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 GetSimulationType(void *sim)
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)