Skip to content

Commit

Permalink
Remove circuit & observable indicies (#971)
Browse files Browse the repository at this point in the history
* remove circuit/observable indicies

* remove data caching tests

* fix reno
  • Loading branch information
kt474 authored Aug 3, 2023
1 parent bf4af5a commit d5c2c4a
Show file tree
Hide file tree
Showing 8 changed files with 6 additions and 394 deletions.
24 changes: 0 additions & 24 deletions qiskit_ibm_runtime/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,33 +174,9 @@ def _run( # pylint: disable=arguments-differ
Returns:
Submitted job
"""
# TODO: Re-enable data caching when ntc 1748 is fixed
# circuits_map = {}
# circuit_ids = []
# for circuit in circuits:
# circuit_id = _hash(json.dumps(_circuit_key(circuit), cls=RuntimeEncoder))
# circuit_ids.append(circuit_id)
# if circuit_id in self._session._circuits_map:
# continue
# self._session._circuits_map[circuit_id] = circuit
# circuits_map[circuit_id] = circuit

# if self._first_run:
# self._first_run = False
# circuits_map.update(self._circuits_map)

# inputs = {
# "circuits": circuits_map,
# "circuit_ids": circuit_ids,
# "observables": observables,
# "observable_indices": list(range(len(observables))),
# "parameter_values": parameter_values,
# }
inputs = {
"circuits": circuits,
"circuit_indices": list(range(len(circuits))),
"observables": observables,
"observable_indices": list(range(len(observables))),
"parameters": [circ.parameters for circ in circuits],
"parameter_values": parameter_values,
}
Expand Down
21 changes: 0 additions & 21 deletions qiskit_ibm_runtime/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,30 +143,9 @@ def _run( # pylint: disable=arguments-differ
Returns:
Submitted job.
"""
# TODO: Re-enable data caching when ntc 1748 is fixed
# circuits_map = {}
# circuit_ids = []
# for circuit in circuits:
# circuit_id = _hash(json.dumps(_circuit_key(circuit), cls=RuntimeEncoder))
# circuit_ids.append(circuit_id)
# if circuit_id in self._session._circuits_map:
# continue
# self._session._circuits_map[circuit_id] = circuit
# circuits_map[circuit_id] = circuit

# if self._first_run:
# self._first_run = False
# circuits_map.update(self._circuits_map)

# inputs = {
# "circuits": circuits_map,
# "circuit_ids": circuit_ids,
# "parameter_values": parameter_values,
# }
inputs = {
"circuits": circuits,
"parameters": [circ.parameters for circ in circuits],
"circuit_indices": list(range(len(circuits))),
"parameter_values": parameter_values,
}
return self._run_primitive(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
The ``circuit_indices`` and ``observable_indices`` run inputs for
:class:`~qiskit_ibm_runtime.Estimator` and :class:`~qiskit_ibm_runtime.Sampler`
have been completely removed.
88 changes: 0 additions & 88 deletions test/integration/test_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

"""Integration tests for Estimator primitive."""

import unittest

import numpy as np

from qiskit.circuit import QuantumCircuit, Parameter
Expand Down Expand Up @@ -109,92 +107,6 @@ def test_estimator_session(self, service):
self.assertEqual(len(result5.metadata), len(circuits5))
session.close()

@unittest.skip("Skip until data caching is reenabled.")
@run_integration_test
def test_estimator_session_circuit_caching(self, service):
"""Verify if estimator primitive circuit caching works"""

backend = "ibmq_qasm_simulator"

qc1 = QuantumCircuit(2)
qc1.x(range(2))
qc1.measure_all()
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc3 = QuantumCircuit(2)
qc3.h(range(2))
qc3.measure_all()

# pylint: disable=invalid-name
H = SparsePauliOp.from_list([("IZ", 1)])

with Session(service, backend) as session:
estimator = Estimator(session=session)

job = estimator.run(
circuits=[qc1, qc2],
observables=[H, H],
)
result = job.result()
self.assertEqual(len(result.values), 2)
self.assertEqual(len(result.metadata), 2)
self.assertEqual(result.values[0], -1)
self.assertEqual(result.values[1], 1)

job = estimator.run(
circuits=[qc3],
observables=[H],
)
result = job.result()
self.assertEqual(len(result.values), 1)
self.assertEqual(len(result.metadata), 1)
self.assertNotEqual(result.values[0], -1)
self.assertNotEqual(result.values[0], 1)

job = estimator.run(
circuits=[qc1, qc3],
observables=[H, H],
)
result = job.result()
self.assertEqual(len(result.values), 2)
self.assertEqual(len(result.metadata), 2)
self.assertEqual(result.values[0], -1)
self.assertNotEqual(result.values[1], -1)
self.assertNotEqual(result.values[1], 1)
session.close()

@unittest.skip("Skip until data caching is reenabled.")
@run_integration_test
def test_estimator_circuit_caching_with_transpilation_options(self, service):
"""Verify if circuit caching works in estimator primitive
by passing correct and incorrect transpilation options."""

qc1 = QuantumCircuit(2)
qc1.x(range(2))
qc1.measure_all()

# pylint: disable=invalid-name
H = SparsePauliOp.from_list([("IZ", 1)])

with Session(service, self.backend) as session:
estimator = Estimator(session=session)
# pass correct initial_layout
transpilation = {"initial_layout": [0, 1]}
job = estimator.run(circuits=[qc1], observables=[H], transpilation=transpilation)
result = job.result()
self.assertEqual(len(result.values), 1)
self.assertEqual(len(result.metadata), 1)
self.assertEqual(result.values[0], -1)

# pass incorrect initial_layout
# since a new transpilation option is passed it should not use the
# cached transpiled circuit from the first run above
transpilation = {"initial_layout": [0]}
job = estimator.run(circuits=[qc1], observables=[H], transpilation=transpilation)
with self.assertRaises(RuntimeJobFailureError):
job.result()
session.close()

@run_integration_test
def test_estimator_callback(self, service):
"""Test Estimator callback function."""
Expand Down
79 changes: 0 additions & 79 deletions test/integration/test_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

"""Integration tests for Sampler primitive."""

import unittest
from math import sqrt

from qiskit.circuit import QuantumCircuit, Gate
Expand Down Expand Up @@ -73,84 +72,6 @@ def test_sampler_non_parameterized_circuits(self, service):
self.assertAlmostEqual(result3.quasi_dists[i][0], 0.5, delta=0.1)
session.close()

@unittest.skip("Skip until data caching is reenabled.")
@run_integration_test
def test_sampler_non_parameterized_circuit_caching(self, service):
"""Verify if circuit caching works in sampler primitive
and returns expected results for non-parameterized circuits."""

qc1 = QuantumCircuit(2)
qc1.x(range(2))
qc1.measure_all()
qc2 = QuantumCircuit(3)
qc2.x(range(3))
qc2.measure_all()
qc3 = QuantumCircuit(4)
qc3.x(range(4))
qc3.measure_all()
qc4 = QuantumCircuit(5)
qc4.x(range(5))
qc4.measure_all()

with Session(service, self.backend) as session:
sampler = Sampler(session=session)
self.assertIsInstance(sampler, BaseSampler)
job = sampler.run(circuits=[qc1, qc2])
result = job.result()
self.assertEqual(len(result.quasi_dists), 2)
self.assertEqual(len(result.metadata), 2)
self.assertEqual(result.quasi_dists[0][3], 1)
self.assertEqual(result.quasi_dists[1][7], 1)

job = sampler.run(circuits=[qc1])
result = job.result()
self.assertEqual(len(result.quasi_dists), 1)
self.assertEqual(len(result.metadata), 1)
self.assertEqual(result.quasi_dists[0][3], 1)

job = sampler.run(circuits=[qc3])
result = job.result()
self.assertEqual(len(result.quasi_dists), 1)
self.assertEqual(len(result.metadata), 1)
self.assertEqual(result.quasi_dists[0][15], 1)

job = sampler.run(circuits=[qc1, qc4])
result = job.result()
self.assertEqual(len(result.quasi_dists), 2)
self.assertEqual(len(result.metadata), 2)
self.assertEqual(result.quasi_dists[0][3], 1)
self.assertEqual(result.quasi_dists[1][31], 1)
session.close()

@unittest.skip("Skip until data caching is reenabled.")
@run_integration_test
def test_sampler_non_parameterized_circuit_caching_with_transpilation_options(self, service):
"""Verify if circuit caching works in sampler primitive
by passing correct and incorrect transpilation options."""

qc1 = QuantumCircuit(2)
qc1.x(range(2))
qc1.measure_all()

with Session(service, self.backend) as session:
sampler = Sampler(session=session)
# pass correct initial_layout
transpilation = {"initial_layout": [0, 1]}
job = sampler.run(circuits=[qc1], transpilation=transpilation)
result = job.result()
self.assertEqual(len(result.quasi_dists), 1)
self.assertEqual(len(result.metadata), 1)
self.assertEqual(result.quasi_dists[0][3], 1)

# pass incorrect initial_layout
# since a new transpilation option is passed it should not use the
# cached transpiled circuit from the first run above
transpilation = {"initial_layout": [0]}
job = sampler.run(circuits=[qc1], transpilation=transpilation)
with self.assertRaises(RuntimeJobFailureError):
job.result()
session.close()

@run_integration_test
def test_sampler_primitive_parameterized_circuits(self, service):
"""Verify if sampler primitive returns expected results for parameterized circuits."""
Expand Down
60 changes: 0 additions & 60 deletions test/unit/test_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,9 @@

"""Tests for estimator class."""

import unittest
import json
from unittest.mock import patch

from qiskit import QuantumCircuit
from qiskit.circuit.library import RealAmplitudes
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives.utils import _circuit_key

from qiskit_ibm_runtime.utils.json import RuntimeEncoder
from qiskit_ibm_runtime.utils.utils import _hash
from qiskit_ibm_runtime import Estimator, Session

from ..ibm_test_case import IBMTestCase
Expand All @@ -32,58 +24,6 @@
class TestEstimator(IBMTestCase):
"""Class for testing the Estimator class."""

@unittest.skip("Skip until data caching is reenabled.")
def test_estimator_circuit_caching(self):
"""Test circuit caching in Estimator class"""
psi1 = RealAmplitudes(num_qubits=2, reps=2)
psi2 = RealAmplitudes(num_qubits=2, reps=3)
psi3 = RealAmplitudes(num_qubits=2, reps=2)
psi4 = RealAmplitudes(num_qubits=2, reps=3)
psi1_id = _hash(json.dumps(_circuit_key(psi1), cls=RuntimeEncoder))
psi2_id = _hash(json.dumps(_circuit_key(psi2), cls=RuntimeEncoder))
psi3_id = _hash(json.dumps(_circuit_key(psi3), cls=RuntimeEncoder))
psi4_id = _hash(json.dumps(_circuit_key(psi4), cls=RuntimeEncoder))

# pylint: disable=invalid-name
H1 = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
H2 = SparsePauliOp.from_list([("IZ", 1)])

with Session(
service=FakeRuntimeService(channel="ibm_quantum", token="abc"),
backend="ibmq_qasm_simulator",
) as session:
estimator = Estimator(session=session)

# calculate [ <psi1(theta1)|H1|psi1(theta1)> ]
with patch.object(estimator._session, "run") as mock_run:
estimator.run([psi1, psi2], [H1, H2], [[1] * 6, [1] * 8])
_, kwargs = mock_run.call_args
inputs = kwargs["inputs"]
self.assertDictEqual(inputs["circuits"], {psi1_id: psi1, psi2_id: psi2})
self.assertEqual(inputs["circuit_ids"], [psi1_id, psi2_id])

# calculate [ <psi2(theta2)|H2|psi2(theta2)> ]
with patch.object(estimator._session, "run") as mock_run:
estimator.run([psi2], [H1], [[1] * 8])
_, kwargs = mock_run.call_args
inputs = kwargs["inputs"]
self.assertDictEqual(inputs["circuits"], {})
self.assertEqual(inputs["circuit_ids"], [psi2_id])

with patch.object(estimator._session, "run") as mock_run:
estimator.run([psi3], [H1], [[1] * 6])
_, kwargs = mock_run.call_args
inputs = kwargs["inputs"]
self.assertDictEqual(inputs["circuits"], {psi3_id: psi3})
self.assertEqual(inputs["circuit_ids"], [psi3_id])

with patch.object(estimator._session, "run") as mock_run:
estimator.run([psi4, psi1], [H2, H1], [[1] * 8, [1] * 6])
_, kwargs = mock_run.call_args
inputs = kwargs["inputs"]
self.assertDictEqual(inputs["circuits"], {psi4_id: psi4})
self.assertEqual(inputs["circuit_ids"], [psi4_id, psi1_id])

def test_unsupported_values_for_estimator_options(self):
"""Test exception when options levels are not supported."""
options_bad = [
Expand Down
Loading

0 comments on commit d5c2c4a

Please sign in to comment.