Skip to content

Commit

Permalink
Fix required memory checks for QasmSimulator with custom method (#763)
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseclectic authored Jun 1, 2020
1 parent b2a8f05 commit f26cb6a
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Fixes issue where memory requirements of simulation were not being checked
on the QasmSimulator when using a non-automatic simulation method.
5 changes: 2 additions & 3 deletions src/controllers/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,8 @@ bool Controller::validate_memory_requirements(const state_t &state,
if(throw_except) {
std::string name = "";
JSON::get_value(name, "name", circ.header);
throw std::runtime_error("AER::Base::Controller: State " + state.name() +
" has insufficient memory to run the circuit " +
name);
throw std::runtime_error("Insufficient memory to run circuit \"" + name +
"\" using the " + state.name() + " simulator.");
}
return false;
}
Expand Down
57 changes: 38 additions & 19 deletions src/controllers/qasm_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,11 @@ QasmController::Method QasmController::simulation_method(
if (simulation_precision_ == Precision::single_precision) {
Statevector::State<QV::QubitVector<float>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
} else {
Statevector::State<QV::QubitVector<>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
}
return Method::statevector;
Expand All @@ -524,9 +526,11 @@ QasmController::Method QasmController::simulation_method(
if (simulation_precision_ == Precision::single_precision) {
Statevector::State<QV::QubitVectorThrust<float>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
} else {
Statevector::State<QV::QubitVectorThrust<>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
}
return Method::statevector_thrust_gpu;
Expand All @@ -542,9 +546,11 @@ QasmController::Method QasmController::simulation_method(
if (simulation_precision_ == Precision::single_precision) {
Statevector::State<QV::QubitVectorThrust<float>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
} else {
Statevector::State<QV::QubitVectorThrust<>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
}
return Method::statevector_thrust_cpu;
Expand All @@ -553,11 +559,13 @@ QasmController::Method QasmController::simulation_method(
case Method::density_matrix: {
if (validate) {
if (simulation_precision_ == Precision::single_precision) {
validate_state(DensityMatrix::State<QV::DensityMatrix<float>>(), circ,
noise_model, true);
DensityMatrix::State<QV::DensityMatrix<float>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
} else {
validate_state(DensityMatrix::State<QV::DensityMatrix<double>>(),
circ, noise_model, true);
DensityMatrix::State<QV::DensityMatrix<double>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
}
return Method::density_matrix;
Expand All @@ -570,12 +578,13 @@ QasmController::Method QasmController::simulation_method(
#else
if (validate) {
if (simulation_precision_ == Precision::single_precision) {
validate_state(DensityMatrix::State<QV::DensityMatrixThrust<float>>(),
circ, noise_model, true);
DensityMatrix::State<QV::DensityMatrixThrust<float>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
} else {
validate_state(
DensityMatrix::State<QV::DensityMatrixThrust<double>>(), circ,
noise_model, true);
DensityMatrix::State<QV::DensityMatrixThrust<double>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
}
return Method::density_matrix_thrust_gpu;
Expand All @@ -589,30 +598,40 @@ QasmController::Method QasmController::simulation_method(
#else
if (validate) {
if (simulation_precision_ == Precision::single_precision) {
validate_state(DensityMatrix::State<QV::DensityMatrixThrust<float>>(),
circ, noise_model, true);
DensityMatrix::State<QV::DensityMatrixThrust<float>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
} else {
validate_state(
DensityMatrix::State<QV::DensityMatrixThrust<double>>(), circ,
noise_model, true);
DensityMatrix::State<QV::DensityMatrixThrust<double>> state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
}
return Method::density_matrix_thrust_cpu;
#endif
}
case Method::stabilizer: {
if (validate)
if (validate) {
Stabilizer::State state;
validate_state(Stabilizer::State(), circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
return Method::stabilizer;
}
case Method::extended_stabilizer: {
if (validate)
validate_state(ExtendedStabilizer::State(), circ, noise_model, true);
if (validate) {
ExtendedStabilizer::State state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(ExtendedStabilizer::State(), circ, true);
}
return Method::extended_stabilizer;
}
case Method::matrix_product_state: {
if (validate)
validate_state(MatrixProductState::State(), circ, noise_model, true);
if (validate) {
MatrixProductState::State state;
validate_state(state, circ, noise_model, true);
validate_memory_requirements(state, circ, true);
}
return Method::matrix_product_state;
}
case Method::automatic: {
Expand Down
6 changes: 1 addition & 5 deletions src/simulators/density_matrix/densitymatrix_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,8 @@ template <class densmat_t>
size_t State<densmat_t>::required_memory_mb(uint_t num_qubits,
const std::vector<Operations::Op> &ops)
const {
// An n-qubit state vector as 2^n complex doubles
// where each complex double is 16 bytes
(void)ops; // avoid unused variable compiler warning
size_t shift_mb = std::max<int_t>(0, num_qubits + 4 - 20);
size_t mem_mb = 1ULL << shift_mb;
return mem_mb;
return BaseState::qreg_.required_memory_mb(2 * num_qubits);
}

template <class densmat_t>
Expand Down
2 changes: 0 additions & 2 deletions src/simulators/statevector/statevector_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,6 @@ template <class statevec_t>
size_t State<statevec_t>::required_memory_mb(uint_t num_qubits,
const std::vector<Operations::Op> &ops)
const {
// An n-qubit state vector as 2^n complex doubles
// where each complex double is 16 bytes
(void)ops; // avoid unused variable compiler warning
return BaseState::qreg_.required_memory_mb(num_qubits);
}
Expand Down

0 comments on commit f26cb6a

Please sign in to comment.