Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions qiskit/providers/aer/backends/unitary_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ def _default_options(cls):
fusion_verbose=False,
fusion_max_qubit=5,
fusion_threshold=14,
blocking_qubits=None,
blocking_enable=False,
# statevector options
statevector_parallel_threshold=14)

Expand Down
5 changes: 5 additions & 0 deletions releasenotes/notes/fix-gpu-memory-cf50e1def7072f38.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Fixes a bug introduced in 0.8.0 where GPU simulations would allocate
unneeded host memory in addition to the GPU memory.
83 changes: 59 additions & 24 deletions src/controllers/aer_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "simulators/statevector/statevector_state_chunk.hpp"
#include "simulators/superoperator/superoperator_state.hpp"
#include "simulators/unitary/unitary_state.hpp"
#include "simulators/unitary/unitary_state_chunk.hpp"

namespace AER {

Expand Down Expand Up @@ -1399,33 +1400,67 @@ void Controller::run_circuit(const Circuit &circ,
}
case Method::unitary: {
if (sim_device_ == Device::CPU) {
if (sim_precision_ == Precision::Double) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<double>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<float>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
if (multiple_chunk_required(circ, noise)) {
if (sim_precision_ == Precision::Double) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrix<double>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrix<float>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
}
}
else{
if (sim_precision_ == Precision::Double) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<double>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<float>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
}
}
} else {
#ifdef AER_THRUST_SUPPORTED
if (sim_precision_ == Precision::Double) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<double>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<float>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
if (multiple_chunk_required(circ, noise)) {
if (sim_precision_ == Precision::Double) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrixThrust<double>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrixThrust<float>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
}
}
else{
if (sim_precision_ == Precision::Double) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<double>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<float>>>(
circ, noise, config, shots, rng_seed, Method::unitary,
false, result);
}
}
#endif
}
Expand Down
1 change: 1 addition & 0 deletions src/controllers/statevector_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ void StatevectorController::run_circuit_helper(
}

Transpile::CacheBlocking cache_block_pass = transpile_cache_blocking(opt_circ,dummy_noise,config,(precision_ == Precision::single_precision) ? sizeof(std::complex<float>) : sizeof(std::complex<double>),false);
cache_block_pass.set_save_state(true);
cache_block_pass.optimize_circuit(opt_circ, dummy_noise, state.opset(), result);

uint_t block_bits = 0;
Expand Down
80 changes: 60 additions & 20 deletions src/controllers/unitary_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "controller.hpp"
#include "simulators/unitary/unitary_state.hpp"
#include "simulators/unitary/unitary_state_chunk.hpp"
#include "transpile/fusion.hpp"

namespace AER {
Expand Down Expand Up @@ -196,30 +197,60 @@ void UnitaryController::run_circuit(const Circuit &circ,
switch (method_) {
case Method::automatic:
case Method::unitary_cpu: {
if (precision_ == Precision::double_precision) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<double>>>(circ, noise, config,
shots, rng_seed, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<float>>>(circ, noise, config,
shots, rng_seed, result);
if(Base::Controller::multiple_chunk_required(circ,noise)){
if (precision_ == Precision::double_precision) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrix<double>>>(circ, noise, config,
shots, rng_seed, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrix<float>>>(circ, noise, config,
shots, rng_seed, result);
}
}
else{
if (precision_ == Precision::double_precision) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<double>>>(circ, noise, config,
shots, rng_seed, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrix<float>>>(circ, noise, config,
shots, rng_seed, result);
}
}
}
case Method::unitary_thrust_gpu: {
#ifdef AER_THRUST_CUDA
if (precision_ == Precision::double_precision) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<double>>>(
circ, noise, config, shots, rng_seed, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<float>>>(
circ, noise, config, shots, rng_seed, result);
if(Base::Controller::multiple_chunk_required(circ,noise)){
if (precision_ == Precision::double_precision) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrixThrust<double>>>(
circ, noise, config, shots, rng_seed, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitaryChunk::State<QV::UnitaryMatrixThrust<float>>>(
circ, noise, config, shots, rng_seed, result);
}
}
else{
if (precision_ == Precision::double_precision) {
// Double-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<double>>>(
circ, noise, config, shots, rng_seed, result);
} else {
// Single-precision unitary simulation
return run_circuit_helper<
QubitUnitary::State<QV::UnitaryMatrixThrust<float>>>(
circ, noise, config, shots, rng_seed, result);
}
}
#else
throw std::runtime_error(
Expand Down Expand Up @@ -309,6 +340,15 @@ void UnitaryController::run_circuit_helper(
fusion_pass.optimize_circuit(opt_circ, dummy_noise, state.opset(), result);
}

Transpile::CacheBlocking cache_block_pass = transpile_cache_blocking(opt_circ,dummy_noise,config,(precision_ == Precision::single_precision) ? sizeof(std::complex<float>) : sizeof(std::complex<double>),true);
cache_block_pass.set_save_state(true);
cache_block_pass.optimize_circuit(opt_circ, dummy_noise, state.opset(), result);

uint_t block_bits = 0;
if(cache_block_pass.enabled())
block_bits = cache_block_pass.block_bits();
state.allocate(Base::Controller::max_qubits_,block_bits);

// Run single shot collecting measure data or snapshots

if (initial_unitary_.empty()) {
Expand Down
Loading