20#ifdef INCLUDED_BY_FACTORY
38class GpuState :
public ISimulator {
47 void Initialize()
override {
49 if (simulationType == SimulationType::kStatevector) {
50 state = SimulatorsFactory::CreateGpuLibStateVectorSim();
52 const bool res = state->Create(nrQubits);
54 throw std::runtime_error(
"GpuState::Initialize: Failed to create "
55 "and initialize the statevector state.");
57 throw std::runtime_error(
58 "GpuState::Initialize: Failed to create the statevector state.");
59 }
else if (simulationType == SimulationType::kMatrixProductState) {
60 mps = SimulatorsFactory::CreateGpuLibMPSSim();
62 if (limitEntanglement && singularValueThreshold > 0.)
63 mps->SetCutoff(singularValueThreshold);
64 if (limitSize && chi > 0)
65 mps->SetMaxExtent(chi);
66 const bool res = mps->Create(nrQubits);
68 throw std::runtime_error(
"GpuState::Initialize: Failed to create "
69 "and initialize the MPS state.");
71 throw std::runtime_error(
72 "GpuState::Initialize: Failed to create the MPS state.");
74 throw std::runtime_error(
"GpuState::Initialize: Invalid simulation "
75 "type for initializing the state.");
90 void InitializeState(
size_t num_qubits,
91 std::vector<std::complex<double>> &litudes)
override {
95 nrQubits = num_qubits;
98 if (simulationType != SimulationType::kStatevector)
99 throw std::runtime_error(
"GpuState::InitializeState: Invalid simulation "
100 "type for initializing the state.");
103 if (simulationType == SimulationType::kStatevector) {
104 state = SimulatorsFactory::CreateGpuLibStateVectorSim();
106 state->CreateWithState(
107 nrQubits,
reinterpret_cast<const double *
>(amplitudes.data()));
124 void InitializeState(
size_t num_qubits,
125 AER::Vector<std::complex<double>> &litudes)
override {
129 nrQubits = num_qubits;
132 if (simulationType != SimulationType::kStatevector)
133 throw std::runtime_error(
"GpuState::InitializeState: Invalid simulation "
134 "type for initializing the state.");
137 if (simulationType == SimulationType::kStatevector) {
138 state = SimulatorsFactory::CreateGpuLibStateVectorSim();
140 state->CreateWithState(
141 nrQubits,
reinterpret_cast<const double *
>(amplitudes.data()));
158 void InitializeState(
size_t num_qubits,
159 Eigen::VectorXcd &litudes)
override {
163 nrQubits = num_qubits;
166 if (simulationType != SimulationType::kStatevector)
167 throw std::runtime_error(
"GpuState::InitializeState: Invalid simulation "
168 "type for initializing the state.");
171 if (simulationType == SimulationType::kStatevector) {
172 state = SimulatorsFactory::CreateGpuLibStateVectorSim();
174 state->CreateWithState(
175 nrQubits,
reinterpret_cast<const double *
>(amplitudes.data()));
186 void Reset()
override {
201 void Configure(
const char *key,
const char *value)
override {
202 if (std::string(
"method") == key) {
203 if (std::string(
"statevector") == value)
204 simulationType = SimulationType::kStatevector;
205 else if (std::string(
"matrix_product_state") == value)
206 simulationType = SimulationType::kMatrixProductState;
207 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
209 singularValueThreshold = std::stod(value);
210 if (singularValueThreshold > 0.) {
211 limitEntanglement =
true;
213 mps->SetCutoff(singularValueThreshold);
215 limitEntanglement =
false;
216 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
217 chi = std::stoi(value);
221 mps->SetMaxExtent(chi);
235 if (std::string(
"method") == key) {
236 switch (simulationType) {
237 case SimulationType::kStatevector:
238 return "statevector";
239 case SimulationType::kMatrixProductState:
240 return "matrix_product_state";
244 }
else if (std::string(
"matrix_product_state_truncation_threshold") ==
246 if (limitEntanglement && singularValueThreshold > 0.)
247 return std::to_string(singularValueThreshold);
248 }
else if (std::string(
"matrix_product_state_max_bond_dimension") == key) {
249 if (limitSize && limitSize > 0)
250 return std::to_string(chi);
264 if ((simulationType == SimulationType::kStatevector && state) ||
265 (simulationType == SimulationType::kMatrixProductState && mps))
268 const size_t oldNrQubits = nrQubits;
269 nrQubits += num_qubits;
288 void Clear()
override {
310 if (simulationType == SimulationType::kStatevector) {
312 for (
size_t qubit : qubits) {
313 if (state->MeasureQubitCollapse(
static_cast<int>(qubit)))
317 }
else if (simulationType == SimulationType::kMatrixProductState) {
319 for (
size_t qubit : qubits) {
320 if (mps->Measure(
static_cast<unsigned int>(qubit)))
327 NotifyObservers(qubits);
340 if (simulationType == SimulationType::kStatevector) {
341 for (
size_t qubit : qubits)
342 if (state->MeasureQubitCollapse(
static_cast<int>(qubit)))
343 state->ApplyX(
static_cast<int>(qubit));
344 }
else if (simulationType == SimulationType::kMatrixProductState) {
345 for (
size_t qubit : qubits)
346 if (mps->Measure(
static_cast<unsigned int>(qubit)))
347 mps->ApplyX(
static_cast<unsigned int>(qubit));
351 NotifyObservers(qubits);
366 if (simulationType == SimulationType::kStatevector)
367 return state->BasisStateProbability(outcome);
368 else if (simulationType == SimulationType::kMatrixProductState) {
370 return std::norm(ampl);
390 if (simulationType == SimulationType::kStatevector)
391 state->Amplitude(outcome, &real, &imag);
392 else if (simulationType == SimulationType::kMatrixProductState) {
393 std::vector<long int> fixedValues(nrQubits);
394 for (
size_t i = 0; i < nrQubits; ++i)
395 fixedValues[i] = (outcome & (1ULL << i)) ? 1 : 0;
396 mps->Amplitude(nrQubits, fixedValues.data(), &real, &imag);
399 return std::complex<double>(real, imag);
415 const size_t numStates = 1ULL << nrQubits;
416 std::vector<double> result(numStates);
418 if (simulationType == SimulationType::kStatevector)
419 state->AllProbabilities(result.data());
420 else if (simulationType == SimulationType::kMatrixProductState) {
424 result[i] = std::norm(std::complex<double>(val.real(), val.imag()));
444 std::vector<double> result(qubits.size());
446 if (simulationType == SimulationType::kStatevector) {
447 for (
size_t i = 0; i < qubits.size(); ++i)
448 result[i] = state->BasisStateProbability(qubits[i]);
449 }
else if (simulationType == SimulationType::kMatrixProductState) {
450 for (
size_t i = 0; i < qubits.size(); ++i) {
452 result[i] = std::norm(ampl);
472 std::unordered_map<Types::qubit_t, Types::qubit_t>
474 size_t shots = 1000)
override {
475 if (qubits.empty() || shots == 0)
478 std::unordered_map<Types::qubit_t, Types::qubit_t> result;
482 if (simulationType == SimulationType::kStatevector) {
483 std::vector<long int> samples(shots);
484 state->SampleAll(shots, samples.data());
486 for (
auto outcome : samples)
488 }
else if (simulationType == SimulationType::kMatrixProductState) {
489 std::unordered_map<std::vector<bool>, int64_t> *map =
490 mps->GetMapForSample();
492 std::vector<unsigned int> qubitsIndices(qubits.begin(), qubits.end());
494 mps->Sample(shots, qubitsIndices.size(), qubitsIndices.data(), map);
497 for (
const auto &[meas, cnt] : *map) {
506 result[outcome] += cnt;
509 mps->FreeMapForSample(map);
513 NotifyObservers(qubits);
529 double ExpectationValue(
const std::string &pauliString)
override {
532 if (simulationType == SimulationType::kStatevector)
533 result = state->ExpectationValue(pauliString);
534 else if (simulationType == SimulationType::kMatrixProductState)
535 result = mps->ExpectationValue(pauliString);
547 SimulatorType GetType()
const override {
return SimulatorType::kGpuSim; }
567 void Flush()
override {}
580 if (simulationType == SimulationType::kStatevector)
581 state->SaveStateDestructive();
583 throw std::runtime_error(
584 "GpuState::SaveStateToInternalDestructive: Invalid simulation type "
585 "for saving the state destructively.");
595 if (simulationType == SimulationType::kStatevector)
596 state->RestoreStateFreeSaved();
598 throw std::runtime_error(
599 "GpuState::RestoreInternalDestructiveSavedState: Invalid simulation "
600 "type for restoring the state destructively.");
612 if (simulationType == SimulationType::kStatevector)
614 else if (simulationType == SimulationType::kMatrixProductState)
626 if (simulationType == SimulationType::kStatevector)
627 state->RestoreStateNoFreeSaved();
628 else if (simulationType == SimulationType::kMatrixProductState)
639 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override {
674 bool IsQcsim()
const override {
return false; }
690 if (simulationType == SimulationType::kStatevector)
691 return state->MeasureAllQubitsNoCollapse();
692 else if (simulationType == SimulationType::kMatrixProductState) {
694 std::iota(fixedValues.begin(), fixedValues.end(), 0);
702 throw std::runtime_error(
703 "QCSimState::MeasureNoCollapse: Invalid simulation type for measuring "
704 "all the qubits without collapsing the state.");
710 SimulationType simulationType =
711 SimulationType::kStatevector;
713 std::unique_ptr<GpuLibStateVectorSim>
715 std::unique_ptr<GpuLibMPSSim> mps;
718 bool limitSize =
false;
719 bool limitEntanglement =
false;
720 Eigen::Index chi = 10;
721 double singularValueThreshold = 0.;
double Probability(void *sim, unsigned long long int outcome)
char * GetConfiguration(void *sim, const char *key)
int RestoreState(void *sim)
int ApplyReset(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
unsigned long int AllocateQubits(void *sim, unsigned long int nrQubits)
unsigned long int GetNumberOfQubits(void *sim)
double * AllProbabilities(void *sim)
unsigned long long int MeasureNoCollapse(void *sim)
int GetMultithreading(void *sim)
unsigned long long int Measure(void *sim, const unsigned long int *qubits, unsigned long int nrQubits)
double * Amplitude(void *sim, unsigned long long int outcome)
double * Probabilities(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits)
int SetMultithreading(void *sim, int multithreading)
int SaveStateToInternalDestructive(void *sim)
int GetSimulationType(void *sim)
unsigned long long int * SampleCounts(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits, unsigned long int shots)
int RestoreInternalDestructiveSavedState(void *sim)
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.