Skip to content

Commit

Permalink
Merge pull request #1170 from mtreinish/prep-0.7.6
Browse files Browse the repository at this point in the history
Prepare 0.7.6 release
  • Loading branch information
mtreinish authored Mar 4, 2021
2 parents 350e421 + b5c1dc1 commit 020a509
Show file tree
Hide file tree
Showing 16 changed files with 164 additions and 38 deletions.
29 changes: 29 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
notifications:
email: false

cache:
pip: true

os: linux
dist: bionic
language: python
python: 3.7
jobs:
include:
- name: Build aarch64 wheels
arch: arm64
services:
- docker
install:
- echo ""
env:
- CIBW_BEFORE_ALL_LINUX="yum install -y https://dl.fedoraproject.org/pub/epel/7/aarch64/Packages/e/epel-release-7-12.noarch.rpm && yum install -y openblas-devel"
- CIBW_SKIP="cp27-* cp34-* cp35-* pp*"
- TWINE_USERNAME=qiskit
- CIBW_TEST_COMMAND="python {project}/tools/verify_wheels.py"
if: tag IS present
script:
- pip install -U twine importlib-metadata keyring cibuildwheel==1.9.0
- cibuildwheel --output-dir wheelhouse
- twine upload wheelhouse/*
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = '0.7.5'
release = '0.7.6'

# -- General configuration ---------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion qiskit/providers/aer/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.5
0.7.6
2 changes: 1 addition & 1 deletion qiskit/providers/aer/backends/qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class QasmSimulator(AerBackend):
to store a state vector. If a state vector needs more, an error
is thrown. In general, a state vector of n-qubits uses 2^n complex
values (16 Bytes). If set to 0, the maximum will be automatically
set to half the system memory size (Default: 0).
set to the system memory size (Default: 0).
* ``optimize_ideal_threshold`` (int): Sets the qubit threshold for
applying circuit optimization passes on ideal circuits.
Expand Down
2 changes: 1 addition & 1 deletion qiskit/providers/aer/backends/statevector_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class StatevectorSimulator(AerBackend):
to store a state vector. If a state vector needs more, an error
is thrown. In general, a state vector of n-qubits uses 2^n complex
values (16 Bytes). If set to 0, the maximum will be automatically
set to half the system memory size (Default: 0).
set to the system memory size (Default: 0).
* ``statevector_parallel_threshold`` (int): Sets the threshold that
"n_qubits" must be greater than to enable OpenMP
Expand Down
2 changes: 1 addition & 1 deletion qiskit/providers/aer/backends/unitary_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class UnitarySimulator(AerBackend):
to store a state vector. If a state vector needs more, an error
is thrown. In general, a state vector of n-qubits uses 2^n complex
values (16 Bytes). If set to 0, the maximum will be automatically
set to half the system memory size (Default: 0).
set to the system memory size (Default: 0).
* ``"statevector_parallel_threshold"`` (int): Sets the threshold that
2 * "n_qubits" must be greater than to enable OpenMP
Expand Down
7 changes: 6 additions & 1 deletion qiskit/providers/aer/noise/noise_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@

from qiskit.circuit import Instruction
from qiskit.providers import BaseBackend
try:
from qiskit.providers import Backend as _Backend
BACKEND = (BaseBackend, _Backend)
except ImportError:
BACKEND = BaseBackend
from qiskit.providers.models import BackendProperties

from ..backends.aerbackend import AerJSONEncoder
Expand Down Expand Up @@ -269,7 +274,7 @@ def from_backend(cls, backend,
Raises:
NoiseError: If the input backend is not valid.
"""
if isinstance(backend, BaseBackend):
if isinstance(backend, BACKEND):
properties = backend.properties()
basis_gates = backend.configuration().basis_gates
if not properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
from warnings import warn
from collections import OrderedDict
from qiskit.providers import BaseBackend
try:
from qiskit.providers import Backend as _Backend
Backend = (BaseBackend, _Backend)
except ImportError:
Backend = BaseBackend
from ...aererror import AerError
from .hamiltonian_model import HamiltonianModel

Expand Down Expand Up @@ -94,7 +99,7 @@ def from_backend(cls, backend, subsystem_list=None):
AerError: If channel or u_channel_lo are invalid.
"""

if not isinstance(backend, BaseBackend):
if not isinstance(backend, Backend):
raise AerError("{} is not a Qiskit backend".format(backend))

# get relevant information from backend
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
fixes:
- |
Fixes a bug ([#1153](https://github.com/Qiskit/qiskit-aer/issues/1153))
where noise on conditional gates was always being applied regardless of
whether the conditional gate was actually applied based on the classical
register value. Now noise on a conditional gate will only be applied in
the case where the conditional gate is applied.
7 changes: 7 additions & 0 deletions releasenotes/notes/issue1126-e2d51f660b0078db.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---

fixes:
- |
Fixed issue #1126: bug in reporting measurement of a single qubit. The bug
occured when copying the measured value to the output data structure.
2 changes: 1 addition & 1 deletion src/controllers/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void Controller::clear_parallelization() {
parallel_nested_ = false;

explicit_parallelization_ = false;
max_memory_mb_ = get_system_memory_mb() / 2;
max_memory_mb_ = get_system_memory_mb();
}

void Controller::set_parallelization_experiments(
Expand Down
2 changes: 2 additions & 0 deletions src/framework/linalg/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ template <class T>
Vector<T>::Vector(Vector<T> &&other) noexcept
: size_(other.size_), data_(other.data_) {
other.data_ = nullptr;
other.size_ = 0;
}

//-----------------------------------------------------------------------
Expand All @@ -214,6 +215,7 @@ template <class T> Vector<T> &Vector<T>::operator=(Vector<T> &&other) noexcept {
size_ = other.size_;
data_ = other.data_;
other.data_ = nullptr;
other.size_ = 0;
return *this;
}

Expand Down
69 changes: 44 additions & 25 deletions src/noise/noise_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,38 +284,57 @@ NoiseModel::param_gate_table_ = {

NoiseModel::NoiseOps NoiseModel::sample_noise(const Operations::Op &op,
RngEngine &rng) const {
// Noise operations
NoiseOps noise_ops;
// Look to see if gate is a waltz gate for this error model
// NOTE this is deprecated and waltz gate noise sampling should be removed
auto it = x90_gates_.find(op.name);
if (it == x90_gates_.end()) {
// Non-X90 based gate, run according to base model
return sample_noise_helper(op, rng);
noise_ops = sample_noise_helper(op, rng);
} else {
// Decompose ops in terms of their waltz implementation
auto gate = waltz_gate_table_.find(op.name);
if (gate != waltz_gate_table_.end()) {
switch (gate->second) {
case WaltzGate::u3:
noise_ops = sample_noise_x90_u3(op.qubits[0],
op.params[0], op.params[1], op.params[2],
rng);
break;
case WaltzGate::u2:
noise_ops = sample_noise_x90_u2(op.qubits[0],
op.params[0], op.params[1],
rng);
break;
case WaltzGate::x:
noise_ops = sample_noise_x90_u3(op.qubits[0], M_PI, 0., M_PI, rng);
break;
case WaltzGate::y:
noise_ops = sample_noise_x90_u3(op.qubits[0], M_PI, 0.5 * M_PI, 0.5 * M_PI, rng);
break;
case WaltzGate::h:
noise_ops = sample_noise_x90_u2(op.qubits[0], 0., M_PI, rng);
break;
default:
// The rest of the Waltz operations are noise free (u1 only)
noise_ops = {op};
break;
}
} else {
// something went wrong if we end up here
throw std::invalid_argument("Invalid waltz gate.");
}
}
// Decompose ops in terms of their waltz implementation
auto gate = waltz_gate_table_.find(op.name);
if (gate != waltz_gate_table_.end()) {
switch (gate->second) {
case WaltzGate::u3:
return sample_noise_x90_u3(op.qubits[0],
op.params[0], op.params[1], op.params[2],
rng);
case WaltzGate::u2:
return sample_noise_x90_u2(op.qubits[0],
op.params[0], op.params[1],
rng);
case WaltzGate::x:
return sample_noise_x90_u3(op.qubits[0], M_PI, 0., M_PI, rng);
case WaltzGate::y:
return sample_noise_x90_u3(op.qubits[0], M_PI, 0.5 * M_PI, 0.5 * M_PI, rng);
case WaltzGate::h:
return sample_noise_x90_u2(op.qubits[0], 0., M_PI, rng);
default:
// The rest of the Waltz operations are noise free (u1 only)
return {op};
// If original op is conditional, make all the noise operations also conditional
if (op.conditional) {
for (auto& noise_op : noise_ops) {
noise_op.conditional = op.conditional;
noise_op.conditional_reg = op.conditional_reg;
noise_op.bfunc = op.bfunc;
}
} else {
// something went wrong if we end up here
throw std::invalid_argument("Invalid waltz gate.");
}
return noise_ops;
}


Expand Down
7 changes: 3 additions & 4 deletions src/simulators/matrix_product_state/matrix_product_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,6 @@ rvector_t State::measure_probs(const reg_t &qubits) const {
std::vector<reg_t> State::sample_measure(const reg_t &qubits,
uint_t shots,
RngEngine &rng) {

// There are two alternative algorithms for sample measure
// We choose the one that is optimal relative to the total number
// of qubits,and the number of shots.
Expand Down Expand Up @@ -820,11 +819,11 @@ sample_measure_using_probabilities(const reg_t &qubits,
std::vector<reg_t> all_samples;
all_samples.reserve(shots);
for (int_t val : allbit_samples) {
reg_t allbit_sample = Utils::int2reg(val, 2, qreg_.num_qubits());
reg_t allbit_sample = Utils::int2reg(val, 2, qubits.size());
reg_t sample;
sample.reserve(qubits.size());
for (uint_t qubit : qubits) {
sample.push_back(allbit_sample[qubit]);
for (uint_t j=0; j<qubits.size(); j++){
sample.push_back(allbit_sample[j]);
}
all_samples.push_back(sample);
}
Expand Down
19 changes: 19 additions & 0 deletions test/terra/reference/ref_measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ def measure_circuits_deterministic(allow_sampling=True):
circuit.i(qr)
circuits.append(circuit)

# Measure a single qubit (qubit 1) in |1> state
qr = QuantumRegister(3)
cr = ClassicalRegister(1)
circuit = QuantumCircuit(qr, cr)
circuit.h(0)
circuit.x(1)
circuit.cx(0, 2)
circuit.barrier(qr)
circuit.measure(1, 0)
if not allow_sampling:
circuit.barrier(qr)
circuit.i(qr)
circuits.append(circuit)

return circuits


Expand All @@ -89,6 +103,8 @@ def measure_counts_deterministic(shots, hex_counts=True):
targets.append({'0x2': shots})
# Measure |11> state
targets.append({'0x3': shots})
# Measure a single qubit (qubit 1) in |1> state
targets.append({'0x1': shots})
else:
# Measure |00> state
targets.append({'00': shots})
Expand All @@ -98,6 +114,9 @@ def measure_counts_deterministic(shots, hex_counts=True):
targets.append({'10': shots})
# Measure |11> state
targets.append({'11': shots})
# Measure a single qubit (qubit 1) in |1> state
targets.append({'0x1': shots})

return targets


Expand Down
35 changes: 34 additions & 1 deletion test/terra/reference/ref_pauli_noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ def pauli_gate_error_circuits():
circuit.measure(qr, cr)
circuits.append(circuit)

# 50% Pauli error on conditional gate that doesn't get applied
circuit = QuantumCircuit(qr, cr)
circuit.x(qr).c_if(cr, 1)
circuit.barrier(qr)
circuit.measure(qr, cr)
circuits.append(circuit)

# 50% Pauli error on conditional gate that does get applied
circuit = QuantumCircuit(qr, cr)
circuit.x(qr).c_if(cr, 0)
circuit.barrier(qr)
circuit.measure(qr, cr)
circuits.append(circuit)

# 25% Pauli-X error on spectator for CX gate on [0, 1]
qr = QuantumRegister(3, 'qr')
cr = ClassicalRegister(3, 'cr')
Expand Down Expand Up @@ -106,6 +120,18 @@ def pauli_gate_error_noise_models():
noise_model.add_quantum_error(error, 'id', [0])
noise_models.append(noise_model)

# 50% Pauli error on conditional gate that doesn't get applied
error = pauli_error([('X', 0.5), ('I', 0.5)])
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(error, 'x')
noise_models.append(noise_model)

# 50% Pauli error on conditional gate that does get applied
error = pauli_error([('X', 0.5), ('I', 0.5)])
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(error, 'x')
noise_models.append(noise_model)

# 25% Pauli-X error on spectator for CX gate on [0, 1]
error = pauli_error([('XII', 0.25), ('III', 0.75)])
noise_model = NoiseModel()
Expand Down Expand Up @@ -135,11 +161,18 @@ def pauli_gate_error_counts(shots, hex_counts=True):
counts = [3 * shots / 4, shots / 4, 0, 0]
counts_lists.append(counts)

# 50% Pauli error on conditional gate that doesn't get applied
counts = [shots, 0, 0, 0]
counts_lists.append(counts)

# 50% Pauli error on conditional gate that does get applied
counts = 4 * [shots / 4]
counts_lists.append(counts)

# 25% Pauli-X error on spectator for CX gate on [0, 1]
counts = [3 * shots / 4, 0, 0, 0, shots / 4, 0, 0, 0]
counts_lists.append(counts)

# Convert to counts dict
return [list2dict(i, hex_counts) for i in counts_lists]


Expand Down

0 comments on commit 020a509

Please sign in to comment.