Skip to content

Commit

Permalink
Merge branch 'Qiskit:main' into mps-cutensor
Browse files Browse the repository at this point in the history
  • Loading branch information
MozammilQ authored Oct 4, 2024
2 parents a1ae308 + 61a557f commit 859e946
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 41 deletions.
28 changes: 12 additions & 16 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,24 @@ jobs:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
name: Install Python
with:
python-version: '3.10'
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Install cibuildwheel
run: |
python -m pip install cibuildwheel==2.17.0
- name: Build wheels
run: |
python -m cibuildwheel --output-dir wheelhouse
uses: pypa/cibuildwheel@v2.19.2
env:
CIBW_BEFORE_ALL_LINUX: "sed -i -e 's/^mirrorlist/#mirrorlist/' -e 's/^#baseurl/baseurl/' -e 's/mirror.centos.org/vault.centos.org/' /etc/yum.repos.d/*.repo && 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_BEFORE_ALL_LINUX: "sed -i -e 's/^mirrorlist/#mirrorlist/' -e 's/^#baseurl/baseurl/' -e 's/mirror.centos.org/vault.centos.org/' /etc/yum.repos.d/*.repo && yum install -y https://dl.fedoraproject.org/pub/archive/epel/7/aarch64/Packages/e/epel-release-7-12.noarch.rpm && yum install -y openblas-devel"
CIBW_ARCHS_LINUX: aarch64
CIBW_TEST_SKIP: "cp38* cp39* cp310* cp311*"
CIBW_TEST_SKIP: "cp*"
- uses: actions/upload-artifact@v4
with:
path: ./wheelhouse/*.whl
Expand Down Expand Up @@ -226,15 +222,15 @@ jobs:
with:
toolchain: stable
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.16.2
uses: pypa/cibuildwheel@v2.19.2
env:
CIBW_ARCHS_LINUX: s390x
CIBW_TEST_SKIP: "cp*"
CIBW_BEFORE_ALL: "sed -i -e 's/^mirrorlist/#mirrorlist/' -e 's/^#baseurl/baseurl/' -e 's/mirror.centos.org/vault.centos.org/' /etc/yum.repos.d/*.repo && yum install -y epel-release && yum install -y openblas-devel"
CIBW_BEFORE_ALL: "sed -i -e 's/^mirrorlist/#mirrorlist/' -e 's/^#baseurl/baseurl/' -e 's/mirror.centos.org/vault.centos.org/' /etc/yum.repos.d/*.repo && yum install -y https://dl.fedoraproject.org/pub/epel/8/Everything/s390x/Packages/e/epel-release-8-21.el8.noarch.rpm && yum install -y openblas-devel"
- uses: actions/upload-artifact@v4
with:
path: ./wheelhouse/*.whl
Expand Down Expand Up @@ -262,15 +258,15 @@ jobs:
with:
toolchain: stable
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.16.2
uses: pypa/cibuildwheel@v2.19.2
env:
CIBW_BEFORE_ALL: "sed -i -e 's/^mirrorlist/#mirrorlist/' -e 's/^#baseurl/baseurl/' -e 's/mirror.centos.org/vault.centos.org/' /etc/yum.repos.d/*.repo && yum install -y https://dl.fedoraproject.org/pub/archive/epel/7/ppc64le/Packages/e/epel-release-7-14.noarch.rpm && yum install -y openblas-devel"
CIBW_ARCHS_LINUX: ppc64le
CIBW_TEST_SKIP: "cp*"
CIBW_BEFORE_ALL: "sed -i -e 's/^mirrorlist/#mirrorlist/' -e 's/^#baseurl/baseurl/' -e 's/mirror.centos.org/vault.centos.org/' /etc/yum.repos.d/*.repo && yum install -y epel-release && yum install -y openblas-devel"
- uses: actions/upload-artifact@v4
with:
path: ./wheelhouse/*.whl
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
timeout-minutes: 60
strategy:
matrix:
python-version: ['3.8']
python-version: ['3.9']
steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
needs: [docs]
strategy:
matrix:
python-version: ['3.8']
python-version: ['3.9']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -74,15 +74,14 @@ jobs:
pip install -U -r requirements-dev.txt -c constraints.txt
pip install -c constraints.txt git+https://github.com/Qiskit/qiskit
pip install -c constraints.txt .
pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf<1.7.4" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt
sudo apt install -y graphviz pandoc libopenblas-dev
pip check
shell: bash
- name: Run Tutorials
run: |
set -e
cd qiskit-tutorials
rm -rf tutorials/chemistry tutorials/circuits tutorials/circuits_advanced tutorials/finance tutorials/optimization tutorials/algorithms tutorials/operators tutorials/noise tutorials/machine_learning
rm -rf tutorials/circuits tutorials/circuits_advanced tutorials/algorithms tutorials/operators
sphinx-build -b html . _build/html
- uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
qiskit-extra: [""]
include:
- python-version: "3.10"
qiskit-extra: "'qiskit>=1.0.0rc1'"
qiskit-extra: "'qiskit>=1.3.0b1'"

env:
AER_THRUST_BACKEND: OMP
Expand Down
2 changes: 1 addition & 1 deletion qiskit_aer/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.15.0
0.16.0
102 changes: 101 additions & 1 deletion qiskit_aer/noise/noise_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@

import numpy as np

from qiskit.circuit import Instruction, Delay
from qiskit.circuit import QuantumCircuit, Instruction, Delay, Reset
from qiskit.circuit.library.generalized_gates import PauliGate, UnitaryGate
from qiskit.providers import QubitProperties
from qiskit.providers.exceptions import BackendPropertyError
from qiskit.providers.models.backendproperties import BackendProperties
Expand Down Expand Up @@ -959,6 +960,105 @@ def to_dict(self, serializable=False):

return ret

@staticmethod
def from_dict(noise_dict):
"""
Load NoiseModel from a dictionary.
Args:
noise_dict (dict): A serialized noise model.
Returns:
NoiseModel: the noise model.
Raises:
NoiseError: if dict cannot be converted to NoiseModel.
"""
warn(
"from_dict has been deprecated as of qiskit-aer 0.15.0"
" and will be removed no earlier than 3 months from that release date.",
DeprecationWarning,
stacklevel=2,
)

def inst_dic_list_to_circuit(dic_list):
num_qubits = max(max(dic["qubits"]) for dic in dic_list) + 1
circ = QuantumCircuit(num_qubits)
for dic in dic_list:
if dic["name"] == "reset":
circ.append(Reset(), qargs=dic["qubits"])
elif dic["name"] == "kraus":
circ.append(
Instruction(
name="kraus",
num_qubits=len(dic["qubits"]),
num_clbits=0,
params=dic["params"],
),
qargs=dic["qubits"],
)
elif dic["name"] == "unitary":
circ.append(UnitaryGate(data=dic["params"][0]), qargs=dic["qubits"])
elif dic["name"] == "pauli":
circ.append(PauliGate(dic["params"][0]), qargs=dic["qubits"])
else:
with catch_warnings():
filterwarnings(
"ignore",
category=DeprecationWarning,
module="qiskit_aer.noise.errors.errorutils",
)
circ.append(
UnitaryGate(
label=dic["name"], data=_standard_gate_unitary(dic["name"])
),
qargs=dic["qubits"],
)
return circ

# Return noise model
noise_model = NoiseModel()

# Get error terms
errors = noise_dict.get("errors", [])

for error in errors:
error_type = error["type"]

# Add QuantumError
if error_type == "qerror":
circuits = [inst_dic_list_to_circuit(dics) for dics in error["instructions"]]
noise_ops = tuple(zip(circuits, error["probabilities"]))
qerror = QuantumError(noise_ops)
qerror._id = error.get("id", None) or qerror.id
instruction_names = error["operations"]
all_gate_qubits = error.get("gate_qubits", None)
if all_gate_qubits is not None:
for gate_qubits in all_gate_qubits:
# Add local quantum error
noise_model.add_quantum_error(
qerror, instruction_names, gate_qubits, warnings=False
)
else:
# Add all-qubit quantum error
noise_model.add_all_qubit_quantum_error(
qerror, instruction_names, warnings=False
)

# Add ReadoutError
elif error_type == "roerror":
probabilities = error["probabilities"]
all_gate_qubits = error.get("gate_qubits", None)
roerror = ReadoutError(probabilities)
# Add local readout error
if all_gate_qubits is not None:
for gate_qubits in all_gate_qubits:
noise_model.add_readout_error(roerror, gate_qubits, warnings=False)
# Add all-qubit readout error
else:
noise_model.add_all_qubit_readout_error(roerror, warnings=False)
# Invalid error type
else:
raise NoiseError("Invalid error type: {}".format(error_type))
return noise_model

def _instruction_names_labels(self, instructions):
"""Return two lists of instruction name strings and label strings."""
if not isinstance(instructions, (list, tuple)):
Expand Down
4 changes: 3 additions & 1 deletion qiskit_aer/noise/passes/local_noise_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ def run(self, dag: DAGCircuit) -> DAGCircuit:
if isinstance(new_op, QuantumCircuit):
# If the new op is a quantum circuit, compose its DAG with the new dag
# so that it is unrolled rather than added as an opaque instruction
new_dag.compose(circuit_to_dag(new_op), qubits=node.qargs) # never touch clbits
new_dag.compose(
circuit_to_dag(new_op), qubits=list(node.qargs)
) # never touch clbits
else:
# Otherwise append the instruction returned by the function
new_dag.apply_operation_back(new_op, qargs=node.qargs) # never touch cargs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
fixes:
- |
SIGSEGV raised when the circuits with unsupported gates is
passed to MPS simulator, because of `std::set.find()` in
size estimator for MPS.
This fix avoids SIGSEGV if unsupported gates is passed.
7 changes: 7 additions & 0 deletions releasenotes/notes/fix_tests_0.15-dccf0acb3cf10571.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
fixes:
- |
Fixed tutorial build failure of Python version and unused tutorials.
Upgraded test for Qiskit 1.0.0rc1 to 1.3.0b1 this will need protection rules
for Aer repository. Also fixed noise/passes/local_noise_pass.py needed
conversion from tuple to list
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
deprecations:
- |
Reverting NoiseModel.from_dict temporary to extend deprecation period
for qiskit-ibm-runtime, but we will remove again in the future release
8 changes: 8 additions & 0 deletions releasenotes/notes/truncate_expval-7fa814c732cca8db.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
fixes:
- |
This fix truncates qubits of save_expval operation when EstimatorV2
is made from existing backends using `from_backend`.
By transpiling on the existing backends, ancilla qubits are filled
to all the qubits that causes memory error on the simulator.
So Aer removes unused qubits for save_expval operation.
55 changes: 50 additions & 5 deletions src/framework/circuit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Circuit {
uint_t num_qubits = 0; // maximum number of qubits needed for ops
uint_t num_memory = 0; // maximum number of memory clbits needed for ops
uint_t num_registers = 0; // maximum number of registers clbits needed for ops
uint_t num_original_qubits = 0; // number of qubits without ancilla qubits

// Measurement params
bool has_conditional = false; // True if any ops are conditional
Expand Down Expand Up @@ -419,7 +420,20 @@ void Circuit::reset_metadata() {
void Circuit::add_op_metadata(const Op &op) {
has_conditional |= op.conditional;
opset_.insert(op);
qubitset_.insert(op.qubits.begin(), op.qubits.end());
if (!qubitset_.empty() &&
(op.type == OpType::save_expval || op.type == OpType::save_expval_var)) {
for (int_t j = 0; j < op.expval_params.size(); j++) {
const std::string &pauli = std::get<0>(op.expval_params[j]);
for (int_t i = 0; i < op.qubits.size(); i++) {
// add qubit with non-I operator
if (pauli[pauli.size() - 1 - i] != 'I') {
qubitset_.insert(op.qubits[i]);
}
}
}
} else {
qubitset_.insert(op.qubits.begin(), op.qubits.end());
}
memoryset_.insert(op.memory.begin(), op.memory.end());
registerset_.insert(op.registers.begin(), op.registers.end());

Expand Down Expand Up @@ -589,6 +603,19 @@ void Circuit::set_params(bool truncation) {
}
if (remapped_qubits) {
remap_qubits(ops[pos]);
} else if (truncation && qubitmap_.size() < ops[pos].qubits.size()) {
// truncate save_expval here when remap is not needed
if (ops[pos].type == OpType::save_expval ||
ops[pos].type == OpType::save_expval_var) {
int_t nparams = ops[pos].expval_params.size();
for (int_t i = 0; i < nparams; i++) {
std::string &pauli = std::get<0>(ops[pos].expval_params[i]);
std::string new_pauli;
new_pauli.assign(pauli.end() - qubitmap_.size(), pauli.end());
pauli = new_pauli;
}
ops[pos].qubits.resize(qubitmap_.size());
}
}
if (pos != op_idx) {
ops[op_idx] = std::move(ops[pos]);
Expand Down Expand Up @@ -653,11 +680,29 @@ void Circuit::set_params(bool truncation) {
}

void Circuit::remap_qubits(Op &op) const {
reg_t new_qubits;
for (auto &qubit : op.qubits) {
new_qubits.push_back(qubitmap_.at(qubit));
// truncate save_expval
if (op.type == OpType::save_expval || op.type == OpType::save_expval_var) {
int_t nparams = op.expval_params.size();
for (int_t i = 0; i < nparams; i++) {
std::string &pauli = std::get<0>(op.expval_params[i]);
std::string new_pauli;
new_pauli.resize(qubitmap_.size());
for (auto q = qubitmap_.cbegin(); q != qubitmap_.cend(); q++) {
new_pauli[qubitmap_.size() - 1 - q->second] =
pauli[pauli.size() - 1 - q->first];
}
pauli = new_pauli;
}
for (int_t i = 0; i < qubitmap_.size(); i++) {
op.qubits[i] = i;
}
} else {
reg_t new_qubits;
for (auto &qubit : op.qubits) {
new_qubits.push_back(qubitmap_.at(qubit));
}
op.qubits = std::move(new_qubits);
}
op.qubits = std::move(new_qubits);
}

bool Circuit::check_result_ancestor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,19 @@ uint_t MPSSizeEstimator::estimate(const std::vector<Operations::Op> &ops,
case Operations::OpType::gate:
if (ops[i].qubits.size() > 1) {
auto it = gateset.find(ops[i].name);
switch (it->second) {
case Gates::rxx:
case Gates::ryy:
case Gates::rzx:
pi2 = std::real(ops[i].params[0]) / M_PI;
pi2_int = (double)std::round(pi2);
if (!AER::Linalg::almost_equal(pi2, pi2_int))
apply_qubits(ops[i].qubits);
break;
default:
break;
if (it != gateset.end()) {
switch (it->second) {
case Gates::rxx:
case Gates::ryy:
case Gates::rzx:
pi2 = std::real(ops[i].params[0]) / M_PI;
pi2_int = (double)std::round(pi2);
if (!AER::Linalg::almost_equal(pi2, pi2_int))
apply_qubits(ops[i].qubits);
break;
default:
break;
}
}
}
break;
Expand Down
Loading

0 comments on commit 859e946

Please sign in to comment.