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 const Eigen::Matrix2cd& gate)
override {
60 throw std::runtime_error(
61 "GpuSimulator::ApplyGenericOneQubitGate: Not supported for GPU "
72 const Eigen::Matrix4cd& gate)
override {
73 throw std::runtime_error(
74 "GpuSimulator::ApplyGenericTwoQubitGate: Not supported for GPU "
87 state->ApplyP(qubit, lambda);
89 mps->ApplyP(qubit, lambda);
91 tn->ApplyP(qubit, lambda);
93 pp->ApplyP(qubit, lambda);
95 NotifyObservers({qubit});
106 state->ApplyX(qubit);
114 NotifyObservers({qubit});
125 state->ApplyY(qubit);
133 NotifyObservers({qubit});
144 state->ApplyZ(qubit);
152 NotifyObservers({qubit});
163 state->ApplyH(qubit);
171 NotifyObservers({qubit});
182 state->ApplyS(qubit);
190 NotifyObservers({qubit});
201 state->ApplySDG(qubit);
203 mps->ApplySDG(qubit);
209 NotifyObservers({qubit});
220 state->ApplyT(qubit);
228 NotifyObservers({qubit});
239 state->ApplyTDG(qubit);
241 mps->ApplyTDG(qubit);
247 NotifyObservers({qubit});
258 state->ApplySX(qubit);
264 pp->ApplySQRTX(qubit);
266 NotifyObservers({qubit});
277 state->ApplySXDG(qubit);
279 mps->ApplySXDG(qubit);
281 tn->ApplySXDG(qubit);
283 pp->ApplySxDAG(qubit);
285 NotifyObservers({qubit});
296 state->ApplyK(qubit);
304 NotifyObservers({qubit});
316 state->ApplyRx(qubit, theta);
318 mps->ApplyRx(qubit, theta);
320 tn->ApplyRx(qubit, theta);
322 pp->ApplyRX(qubit, theta);
324 NotifyObservers({qubit});
336 state->ApplyRy(qubit, theta);
338 mps->ApplyRy(qubit, theta);
340 tn->ApplyRy(qubit, theta);
342 pp->ApplyRY(qubit, theta);
344 NotifyObservers({qubit});
356 state->ApplyRz(qubit, theta);
358 mps->ApplyRz(qubit, theta);
360 tn->ApplyRz(qubit, theta);
362 pp->ApplyRZ(qubit, theta);
364 NotifyObservers({qubit});
375 double gamma)
override {
377 state->ApplyU(qubit, theta, phi, lambda, gamma);
379 mps->ApplyU(qubit, theta, phi, lambda, gamma);
381 tn->ApplyU(qubit, theta, phi, lambda, gamma);
383 pp->ApplyU(qubit, theta, phi, lambda, gamma);
385 NotifyObservers({qubit});
397 state->ApplyCX(ctrl_qubit, tgt_qubit);
399 mps->ApplyCX(ctrl_qubit, tgt_qubit);
401 tn->ApplyCX(ctrl_qubit, tgt_qubit);
403 pp->ApplyCX(ctrl_qubit, tgt_qubit);
405 NotifyObservers({tgt_qubit, ctrl_qubit});
417 state->ApplyCY(ctrl_qubit, tgt_qubit);
419 mps->ApplyCY(ctrl_qubit, tgt_qubit);
421 tn->ApplyCY(ctrl_qubit, tgt_qubit);
423 pp->ApplyCY(ctrl_qubit, tgt_qubit);
425 NotifyObservers({tgt_qubit, ctrl_qubit});
437 state->ApplyCZ(ctrl_qubit, tgt_qubit);
439 mps->ApplyCZ(ctrl_qubit, tgt_qubit);
441 tn->ApplyCZ(ctrl_qubit, tgt_qubit);
443 pp->ApplyCZ(ctrl_qubit, tgt_qubit);
445 NotifyObservers({tgt_qubit, ctrl_qubit});
457 double lambda)
override {
459 state->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
461 mps->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
463 tn->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
465 pp->ApplyCP(ctrl_qubit, tgt_qubit, lambda);
467 NotifyObservers({tgt_qubit, ctrl_qubit});
479 double theta)
override {
481 state->ApplyCRx(ctrl_qubit, tgt_qubit, theta);
483 mps->ApplyCRx(ctrl_qubit, tgt_qubit, theta);
485 tn->ApplyCRx(ctrl_qubit, tgt_qubit, theta);
487 pp->ApplyCRX(ctrl_qubit, tgt_qubit, theta);
489 NotifyObservers({tgt_qubit, ctrl_qubit});
501 double theta)
override {
503 state->ApplyCRy(ctrl_qubit, tgt_qubit, theta);
505 mps->ApplyCRy(ctrl_qubit, tgt_qubit, theta);
507 tn->ApplyCRy(ctrl_qubit, tgt_qubit, theta);
509 pp->ApplyCRY(ctrl_qubit, tgt_qubit, theta);
511 NotifyObservers({tgt_qubit, ctrl_qubit});
523 double theta)
override {
525 state->ApplyCRz(ctrl_qubit, tgt_qubit, theta);
527 mps->ApplyCRz(ctrl_qubit, tgt_qubit, theta);
529 tn->ApplyCRz(ctrl_qubit, tgt_qubit, theta);
531 pp->ApplyCRZ(ctrl_qubit, tgt_qubit, theta);
533 NotifyObservers({tgt_qubit, ctrl_qubit});
545 state->ApplyCH(ctrl_qubit, tgt_qubit);
547 mps->ApplyCH(ctrl_qubit, tgt_qubit);
549 tn->ApplyCH(ctrl_qubit, tgt_qubit);
551 pp->ApplyCH(ctrl_qubit, tgt_qubit);
553 NotifyObservers({tgt_qubit, ctrl_qubit});
565 state->ApplyCSX(ctrl_qubit, tgt_qubit);
567 mps->ApplyCSX(ctrl_qubit, tgt_qubit);
569 tn->ApplyCSX(ctrl_qubit, tgt_qubit);
571 pp->ApplyCSX(ctrl_qubit, tgt_qubit);
573 NotifyObservers({tgt_qubit, ctrl_qubit});
586 state->ApplyCSXDG(ctrl_qubit, tgt_qubit);
588 mps->ApplyCSXDG(ctrl_qubit, tgt_qubit);
590 tn->ApplyCSXDG(ctrl_qubit, tgt_qubit);
592 pp->ApplyCSXDAG(ctrl_qubit, tgt_qubit);
594 NotifyObservers({tgt_qubit, ctrl_qubit});
606 state->ApplySwap(qubit0, qubit1);
608 mps->ApplySwap(qubit0, qubit1);
610 tn->ApplySwap(qubit0, qubit1);
612 pp->ApplySWAP(qubit0, qubit1);
614 NotifyObservers({qubit1, qubit0});
628 state->ApplyCCX(qubit0, qubit1, qubit2);
629 NotifyObservers({qubit0, qubit1, qubit2});
631 const size_t q1 = qubit0;
632 const size_t q2 = qubit1;
633 const size_t q3 = qubit2;
636 mps->ApplyCSX(
static_cast<unsigned int>(q2),
637 static_cast<unsigned int>(q3));
638 NotifyObservers({qubit1, qubit2});
640 mps->ApplyCX(
static_cast<unsigned int>(q1),
641 static_cast<unsigned int>(q2));
642 NotifyObservers({qubit0, qubit1});
644 mps->ApplyCSXDG(
static_cast<unsigned int>(q2),
645 static_cast<unsigned int>(q3));
646 NotifyObservers({qubit1, qubit2});
648 mps->ApplyCX(
static_cast<unsigned int>(q1),
649 static_cast<unsigned int>(q2));
650 NotifyObservers({qubit0, qubit1});
652 mps->ApplyCSX(
static_cast<unsigned int>(q1),
653 static_cast<unsigned int>(q3));
654 NotifyObservers({qubit0, qubit2});
656 tn->ApplyCCX(qubit0, qubit1, qubit2);
657 NotifyObservers({qubit0, qubit1, qubit2});
659 pp->ApplyCCX(qubit0, qubit1, qubit2);
660 NotifyObservers({qubit0, qubit1, qubit2});
675 state->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
676 NotifyObservers({qubit1, qubit0, ctrl_qubit});
678 const size_t q1 = ctrl_qubit;
679 const size_t q2 = qubit0;
680 const size_t q3 = qubit1;
684 mps->ApplyCX(
static_cast<unsigned int>(q3),
685 static_cast<unsigned int>(q2));
686 NotifyObservers({qubit1, qubit0});
688 mps->ApplyCSX(
static_cast<unsigned int>(q2),
689 static_cast<unsigned int>(q3));
690 NotifyObservers({qubit0, qubit1});
692 mps->ApplyCX(
static_cast<unsigned int>(q1),
693 static_cast<unsigned int>(q2));
694 NotifyObservers({ctrl_qubit, qubit0});
696 mps->ApplyP(
static_cast<unsigned int>(q3), M_PI);
697 NotifyObservers({qubit1});
698 mps->ApplyP(
static_cast<unsigned int>(q2), -M_PI_2);
699 NotifyObservers({qubit0});
701 mps->ApplyCSX(
static_cast<unsigned int>(q2),
702 static_cast<unsigned int>(q3));
703 NotifyObservers({qubit0, qubit1});
705 mps->ApplyCX(
static_cast<unsigned int>(q1),
706 static_cast<unsigned int>(q2));
707 NotifyObservers({ctrl_qubit, qubit0});
709 mps->ApplyP(
static_cast<unsigned int>(q3), M_PI);
710 NotifyObservers({qubit1});
712 mps->ApplyCSX(
static_cast<unsigned int>(q1),
713 static_cast<unsigned int>(q3));
714 NotifyObservers({ctrl_qubit, qubit1});
716 mps->ApplyCX(
static_cast<unsigned int>(q3),
717 static_cast<unsigned int>(q2));
718 NotifyObservers({qubit1, qubit0});
720 tn->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
721 NotifyObservers({qubit1, qubit0, ctrl_qubit});
723 pp->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
724 NotifyObservers({qubit1, qubit0, ctrl_qubit});
740 double theta,
double phi,
double lambda,
double gamma)
override {
742 state->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
744 mps->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
746 tn->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
748 pp->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
750 NotifyObservers({tgt_qubit, ctrl_qubit});
760 void ApplyNop()
override {
774 std::unique_ptr<ISimulator> Clone()
override {
777 throw std::runtime_error(
778 "GpuSimulator::Clone: Cloning Tensor Network or Pauli Propagator "
783 auto cloned = std::make_unique<GpuSimulator>();
785 cloned->simulationType = simulationType;
786 cloned->nrQubits = nrQubits;
788 cloned->limitSize = limitSize;
789 cloned->limitEntanglement = limitEntanglement;
791 cloned->singularValueThreshold = singularValueThreshold;
793 cloned->lookaheadDepth = lookaheadDepth;
794 cloned->useOptimalMeetingPosition = useOptimalMeetingPosition;
795 cloned->upcomingGates = upcomingGates;
796 cloned->upcomingGateIndex = upcomingGateIndex;
797 cloned->growthFactorGate = growthFactorGate;
798 cloned->growthFactorSwap = growthFactorSwap;
801 cloned->state = state->Clone();
803 cloned->mps = mps->Clone();
805 cloned->gateCounterObserver =
806 std::make_shared<GateCounterObserver>(upcomingGateIndex);
807 cloned->RegisterObserver(cloned->gateCounterObserver);
809 cloned->dummySim = dummySim ? dummySim->Clone() :
nullptr;
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)
uint_fast64_t qubit_t
The type of a qubit.