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;
61 state->ApplyP(qubit, lambda);
63 mps->ApplyP(qubit, lambda);
65 tn->ApplyP(qubit, lambda);
67 pp->ApplyP(qubit, lambda);
69 NotifyObservers({qubit});
88 NotifyObservers({qubit});
107 NotifyObservers({qubit});
118 state->ApplyZ(qubit);
126 NotifyObservers({qubit});
137 state->ApplyH(qubit);
145 NotifyObservers({qubit});
156 state->ApplyS(qubit);
164 NotifyObservers({qubit});
175 state->ApplySDG(qubit);
177 mps->ApplySDG(qubit);
183 NotifyObservers({qubit});
194 state->ApplyT(qubit);
202 NotifyObservers({qubit});
213 state->ApplyTDG(qubit);
215 mps->ApplyTDG(qubit);
221 NotifyObservers({qubit});
232 state->ApplySX(qubit);
238 pp->ApplySQRTX(qubit);
240 NotifyObservers({qubit});
251 state->ApplySXDG(qubit);
253 mps->ApplySXDG(qubit);
255 tn->ApplySXDG(qubit);
257 pp->ApplySxDAG(qubit);
259 NotifyObservers({qubit});
270 state->ApplyK(qubit);
278 NotifyObservers({qubit});
290 state->ApplyRx(qubit, theta);
292 mps->ApplyRx(qubit, theta);
294 tn->ApplyRx(qubit, theta);
296 pp->ApplyRX(qubit, theta);
298 NotifyObservers({qubit});
310 state->ApplyRy(qubit, theta);
312 mps->ApplyRy(qubit, theta);
314 tn->ApplyRy(qubit, theta);
316 pp->ApplyRY(qubit, theta);
318 NotifyObservers({qubit});
330 state->ApplyRz(qubit, theta);
332 mps->ApplyRz(qubit, theta);
334 tn->ApplyRz(qubit, theta);
336 pp->ApplyRZ(qubit, theta);
338 NotifyObservers({qubit});
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});
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});
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});
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});
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});
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});
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});
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});
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});
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});
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});
580 state->ApplySwap(qubit0, qubit1);
582 mps->ApplySwap(qubit0, qubit1);
584 tn->ApplySwap(qubit0, qubit1);
586 pp->ApplySWAP(qubit0, qubit1);
588 NotifyObservers({qubit1, qubit0});
602 state->ApplyCCX(qubit0, qubit1, qubit2);
603 NotifyObservers({qubit0, qubit1, qubit2});
605 const size_t q1 = qubit0;
606 const size_t q2 = qubit1;
607 const size_t q3 = qubit2;
610 mps->ApplyCSX(
static_cast<unsigned int>(q2),
611 static_cast<unsigned int>(q3));
612 NotifyObservers({qubit1, qubit2});
614 mps->ApplyCX(
static_cast<unsigned int>(q1),
615 static_cast<unsigned int>(q2));
616 NotifyObservers({qubit0, qubit1});
618 mps->ApplyCSXDG(
static_cast<unsigned int>(q2),
619 static_cast<unsigned int>(q3));
620 NotifyObservers({qubit1, qubit2});
622 mps->ApplyCX(
static_cast<unsigned int>(q1),
623 static_cast<unsigned int>(q2));
624 NotifyObservers({qubit0, qubit1});
626 mps->ApplyCSX(
static_cast<unsigned int>(q1),
627 static_cast<unsigned int>(q3));
628 NotifyObservers({qubit0, qubit2});
630 tn->ApplyCCX(qubit0, qubit1, qubit2);
631 NotifyObservers({qubit0, qubit1, qubit2});
633 pp->ApplyCCX(qubit0, qubit1, qubit2);
634 NotifyObservers({qubit0, qubit1, qubit2});
649 state->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
650 NotifyObservers({qubit1, qubit0, ctrl_qubit});
652 const size_t q1 = ctrl_qubit;
653 const size_t q2 = qubit0;
654 const size_t q3 = qubit1;
658 mps->ApplyCX(
static_cast<unsigned int>(q3),
659 static_cast<unsigned int>(q2));
660 NotifyObservers({qubit1, qubit0});
662 mps->ApplyCSX(
static_cast<unsigned int>(q2),
663 static_cast<unsigned int>(q3));
664 NotifyObservers({qubit0, qubit1});
666 mps->ApplyCX(
static_cast<unsigned int>(q1),
667 static_cast<unsigned int>(q2));
668 NotifyObservers({ctrl_qubit, qubit0});
670 mps->ApplyP(
static_cast<unsigned int>(q3), M_PI);
671 NotifyObservers({qubit1});
672 mps->ApplyP(
static_cast<unsigned int>(q2), -M_PI_2);
673 NotifyObservers({qubit0});
675 mps->ApplyCSX(
static_cast<unsigned int>(q2),
676 static_cast<unsigned int>(q3));
677 NotifyObservers({qubit0, qubit1});
679 mps->ApplyCX(
static_cast<unsigned int>(q1),
680 static_cast<unsigned int>(q2));
681 NotifyObservers({ctrl_qubit, qubit0});
683 mps->ApplyP(
static_cast<unsigned int>(q3), M_PI);
684 NotifyObservers({qubit1});
686 mps->ApplyCSX(
static_cast<unsigned int>(q1),
687 static_cast<unsigned int>(q3));
688 NotifyObservers({ctrl_qubit, qubit1});
690 mps->ApplyCX(
static_cast<unsigned int>(q3),
691 static_cast<unsigned int>(q2));
692 NotifyObservers({qubit1, qubit0});
694 tn->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
695 NotifyObservers({qubit1, qubit0, ctrl_qubit});
697 pp->ApplyCSwap(ctrl_qubit, qubit0, qubit1);
698 NotifyObservers({qubit1, qubit0, ctrl_qubit});
714 double theta,
double phi,
double lambda,
double gamma)
override {
716 state->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
718 mps->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
720 tn->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
722 pp->ApplyCU(ctrl_qubit, tgt_qubit, theta, phi, lambda, gamma);
724 NotifyObservers({tgt_qubit, ctrl_qubit});
734 void ApplyNop()
override {
748 std::unique_ptr<ISimulator> Clone()
override {
751 throw std::runtime_error(
752 "GpuSimulator::Clone: Cloning Tensor Network or Pauli Propagator "
757 auto cloned = std::make_unique<GpuSimulator>();
759 cloned->simulationType = simulationType;
760 cloned->nrQubits = nrQubits;
762 cloned->limitSize = limitSize;
763 cloned->limitEntanglement = limitEntanglement;
765 cloned->singularValueThreshold = singularValueThreshold;
767 cloned->lookaheadDepth = lookaheadDepth;
768 cloned->useOptimalMeetingPosition = useOptimalMeetingPosition;
769 cloned->upcomingGates = upcomingGates;
770 cloned->upcomingGateIndex = upcomingGateIndex;
771 cloned->growthFactorGate = growthFactorGate;
772 cloned->growthFactorSwap = growthFactorSwap;
775 cloned->state = state->Clone();
777 cloned->mps = mps->Clone();
779 cloned->gateCounterObserver =
780 std::make_shared<GateCounterObserver>(upcomingGateIndex);
781 cloned->RegisterObserver(cloned->gateCounterObserver);
783 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.