2#if defined(INCLUDED_BY_FACTORY) && defined(__linux__)
20class ImmediateGpuSimulator :
public ISimulator
23 virtual const char *MethodName()
const = 0;
26 void ValidateMethod(
const char *value)
const
28 if (std::string(value) != MethodName())
29 throw std::invalid_argument(
"A concrete simulator cannot change method; select the backend through SimulatorsFactory");
32 virtual void RefreshRoutingCallback()
37 void InitializeState(
size_t num_qubits, std::vector<std::complex<double>> &litudes)
override
42 nrQubits = num_qubits;
44 throw std::runtime_error(
"GpuState::InitializeState: Invalid simulation "
45 "type for initializing the state.");
49 void InitializeState(
size_t num_qubits, AER::Vector<std::complex<double>> &litudes)
override
54 nrQubits = num_qubits;
56 throw std::runtime_error(
"GpuState::InitializeState: Invalid simulation "
57 "type for initializing the state.");
62 void InitializeState(
size_t num_qubits, Eigen::VectorXcd &litudes)
override
67 nrQubits = num_qubits;
69 throw std::runtime_error(
"GpuState::InitializeState: Invalid simulation "
70 "type for initializing the state.");
73 void InitializeToBasisState(
size_t num_qubits,
Types::qubit_t basisState)
override
78 nrQubits = num_qubits;
80 for (
size_t q = 0; q < num_qubits; ++q)
81 if ((basisState >> q) & 1ULL)
85 void InitializeToBasisState(
size_t num_qubits,
const std::vector<bool> &basisState)
override
90 nrQubits = num_qubits;
92 for (
size_t q = 0; q < num_qubits && q < basisState.size(); ++q)
97 void InitializeToMixtureOfBasisStates(
size_t num_qubits,
const std::vector<std::pair<Types::qubit_t, double>> &mixture)
override
102 nrQubits = num_qubits;
104 throw std::runtime_error(
"GpuState::InitializeToMixtureOfBasisStates: Invalid simulation "
105 "type for initializing to a mixture of basis states.");
108 void InitializeToMixtureOfBasisStates(
size_t num_qubits,
const std::vector<std::pair<std::vector<bool>,
double>> &mixture)
override
113 nrQubits = num_qubits;
115 throw std::runtime_error(
"GpuState::InitializeToMixtureOfBasisStates: Invalid simulation "
116 "type for initializing to a mixture of basis states.");
119 bool SupportsMPSSwapOptimization()
const override
124 void SetUpcomingGates(
const std::vector<std::shared_ptr<Circuits::IOperation<double>>> &gates)
override
126 upcomingGates = gates;
127 upcomingGateIndex = 0;
128 if (!gateCounterObserver)
129 gateCounterObserver = std::make_shared<GateCounterObserver>(upcomingGateIndex);
130 RegisterObserver(gateCounterObserver);
131 RefreshRoutingCallback();
134 long long int GetGatesCounter()
const override
136 return upcomingGateIndex;
139 void SetGatesCounter(
long long int counter)
override
141 upcomingGateIndex = counter;
144 void IncrementGatesCounter()
override
154 bool SupportsQuantumChannels()
const override
159 void ApplyQuantumChannel(
const Types::qubits_vector &targets,
const QuantumChannel &channel)
override
161 throw std::runtime_error(
"GPU quantum channels require an initialized density matrix or "
162 "matrix product operator");
165 double ProbabilityBits(
const std::vector<bool> &bits)
override
167 return IState::ProbabilityBits(bits);
170 std::complex<double> DensityMatrixElementBits(
const std::vector<bool> &row,
const std::vector<bool> &col)
const override
172 return IState::DensityMatrixElementBits(row, col);
175 Eigen::MatrixXcd GetDensityMatrix(
bool normalized =
true)
const override
177 return IState::GetDensityMatrix(normalized);
180 std::complex<double> ExpectationValueComplex(
const std::string &pauli,
bool normalized =
true)
const override
182 return IState::ExpectationValueComplex(pauli, normalized);
185 std::vector<std::complex<double>> ExpectationValuesComplex(
const std::vector<std::string> &paulis,
bool normalized =
true)
const override
187 return IState::ExpectationValuesComplex(paulis, normalized);
190 std::complex<double> ExpectationValueOperators(
const Types::qubits_vector &qubits,
const std::vector<Eigen::MatrixXcd> &matrices)
override
192 return IState::ExpectationValueOperators(qubits, matrices);
195 void ApplyOperator(
const Types::qubits_vector &qubits,
const Eigen::MatrixXcd &matrix,
bool normalize =
false)
override
197 return IState::ApplyOperator(qubits, matrix, normalize);
202 return IState::MoveAtBeginningOfChain(qubits);
205 std::vector<std::complex<double>> GetStateVector()
override
207 return IState::GetStateVector();
210 std::complex<double> DensityMatrixTrace()
const override
212 throw std::runtime_error(
"GPU mixed-state diagnostics require density_matrix or "
213 "matrix_product_operator");
216 std::complex<double> DensityMatrixOverlap(
const IState &other)
const override
218 throw std::invalid_argument(
"Density-matrix overlap requires two density matrices or two MPOs");
221 double DensityMatrixPurity()
const override
223 throw std::runtime_error(
"GPU mixed-state diagnostics require density_matrix or "
224 "matrix_product_operator");
227 std::complex<double> DensityMatrixTraceOfSquare()
const override
229 throw std::runtime_error(
"GPU mixed-state diagnostics require density_matrix or "
230 "matrix_product_operator");
233 double DensityMatrixHermiticityResidual()
const override
235 throw std::runtime_error(
"GPU mixed-state diagnostics require density_matrix or "
236 "matrix_product_operator");
239 bool IsDensityMatrixHermitian(
double eps = 1e-10)
const override
241 throw std::runtime_error(
"GPU mixed-state diagnostics require density_matrix or "
242 "matrix_product_operator");
247 std::vector<int> keep(qubits.begin(), qubits.end());
248 throw std::runtime_error(
"GPU partial trace requires a mixed-state backend");
251 double FidelityWithStatevector(
const Eigen::VectorXcd &psi)
const override
253 std::vector<double> raw(2 *
static_cast<size_t>(psi.size()));
254 for (Eigen::Index i = 0; i < psi.size(); ++i)
256 raw[2 * i] = psi[i].real();
257 raw[2 * i + 1] = psi[i].imag();
259 throw std::runtime_error(
"GPU mixed-state fidelity requires density_matrix or "
260 "matrix_product_operator");
263 void RestoreDensityMatrixTrace()
override
265 throw std::runtime_error(
"Trace restoration is only available for GPU MPO");
268 void HermitizeDensityMatrix()
override
270 throw std::runtime_error(
"Hermitization is only available for GPU MPO");
275 throw std::runtime_error(
"Trim is only available for GPU MPS and MPO");
278 void ReCanonicalize()
override
280 throw std::runtime_error(
"Canonicalization is only available for GPU MPS and MPO");
286 return std::norm(ampl);
289 std::complex<double> ProjectOnZero()
override
296 std::vector<double> result(qubits.size());
298 for (
size_t i = 0; i < qubits.size(); ++i)
301 result[i] = std::norm(ampl);
307 std::vector<double> ExpectationValues(
const std::vector<std::string> &paulis)
override
309 return IState::ExpectationValues(paulis);
314 return SimulatorType::kGpuSim;
317 void Flush()
override
319 const bool done =
true;
321 throw std::runtime_error(
"GpuState::Flush: device synchronization failed");
326 throw std::runtime_error(
"GpuState::SaveStateToInternalDestructive: Invalid simulation type "
327 "for saving the state destructively.");
332 throw std::runtime_error(
"GpuState::RestoreInternalDestructiveSavedState: Invalid simulation "
333 "type for restoring the state destructively.");
336 std::complex<double> AmplitudeRaw(
Types::qubit_t outcome)
override
358 std::cerr <<
"Warning: The number of qubits to measure is larger than the "
359 "number of bits in the Types::qubit_t type, the outcome will be "
363 std::iota(fixedValues.begin(), fixedValues.end(), 0);
367 return res.begin()->first;
370 std::vector<bool> MeasureNoCollapseMany()
override
373 std::iota(fixedValues.begin(), fixedValues.end(), 0);
374 const auto res = SampleCountsMany(fixedValues, 1);
376 return std::vector<bool>(nrQubits,
false);
377 return res.begin()->first;
382 return configuration;
385 const std::unordered_map<std::string, std::string> &GetConfigMap()
const override
387 return configuration.GetConfigMap();
392 throw std::runtime_error(
"GpuSimulator::ApplyGenericOneQubitGate: Not supported for GPU "
398 throw std::runtime_error(
"GpuSimulator::ApplyGenericTwoQubitGate: Not supported for GPU "
403 const Eigen::Matrix<std::complex<double>, 8, 8> &gate)
override
405 throw std::runtime_error(
"Generic three-qubit gates require GPU statevector");
408 void ApplyNop()
override
415 auto sorted = qubits;
416 std::sort(sorted.begin(), sorted.end());
417 sorted.erase(std::unique(sorted.begin(), sorted.end()), sorted.end());
418 std::vector<size_t> positions;
419 positions.reserve(qubits.size());
420 for (
const auto q : qubits)
421 positions.push_back(std::lower_bound(sorted.begin(), sorted.end(), q) - sorted.begin());
425 uint64_t nextSeedStream = 0;
429 std::vector<std::shared_ptr<Circuits::IOperation<>>> upcomingGates;
431 long long int upcomingGateIndex = 0;
433 class GateCounterObserver :
public ISimulatorObserver
436 GateCounterObserver(
long long int &indexRef) : index(indexRef)
446 long long int &index;
449 std::shared_ptr<GateCounterObserver> gateCounterObserver;
451 Configuration configuration;
double Probability(void *sim, unsigned long long int outcome)
char * GetConfiguration(void *sim, const char *key)
int ApplyX(void *sim, int qubit)
unsigned long int GetNumberOfQubits(void *sim)
unsigned long long int MeasureNoCollapse(void *sim)
int GetMultithreading(void *sim)
double * Amplitude(void *sim, unsigned long long int outcome)
int ApplyGenericThreeQubitGate(void *sim, unsigned long q0, unsigned long q1, unsigned long q2, const double *buffer)
double * Probabilities(void *sim, const unsigned long long int *qubits, unsigned long int nrQubits)
int SetMultithreading(void *sim, int multithreading)
int SaveStateToInternalDestructive(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)
int ApplyGenericOneQubitGate(void *sim, unsigned long q0, const double *buffer)
int ApplyGenericTwoQubitGate(void *sim, unsigned long q0, unsigned long q1, const double *buffer)
SimulatorType
The type of simulator.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
uint_fast64_t qubit_t
The type of a qubit.