From afb7065e6564ce7f098d242fb78c27dd55931815 Mon Sep 17 00:00:00 2001 From: Kevin Tian Date: Fri, 18 Feb 2022 01:55:40 -0500 Subject: [PATCH 1/2] serialize ndarray --- qiskit/providers/ibmq/runtime/utils.py | 4 ++++ .../numpy-ndarray-encoder-12745f022ec8ef0b.yaml | 7 +++++++ test/ibmq/runtime/test_runtime.py | 13 +++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml diff --git a/qiskit/providers/ibmq/runtime/utils.py b/qiskit/providers/ibmq/runtime/utils.py index 75f910864..7e0bc7edd 100644 --- a/qiskit/providers/ibmq/runtime/utils.py +++ b/qiskit/providers/ibmq/runtime/utils.py @@ -185,6 +185,8 @@ def default(self, obj: Any) -> Any: # pylint: disable=arguments-differ if isinstance(obj, complex): return {'__type__': 'complex', '__value__': [obj.real, obj.imag]} if isinstance(obj, np.ndarray): + if obj.dtype == object: + return {"__type__": "ndarray", "__value__": obj.tolist()} value = _serialize_and_encode(obj, np.save, allow_pickle=False) return {'__type__': 'ndarray', '__value__': value} if isinstance(obj, set): @@ -255,6 +257,8 @@ def object_hook(self, obj: Any) -> Any: if obj_type == 'complex': return obj_val[0] + 1j * obj_val[1] if obj_type == 'ndarray': + if isinstance(obj_val, list): + return np.array(obj_val) return _decode_and_deserialize(obj_val, np.load) if obj_type == 'set': return set(obj_val) diff --git a/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml b/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml new file mode 100644 index 000000000..ca25ea0c7 --- /dev/null +++ b/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixed an issue where numpy ndarrays with object types could not be + serialized. :class:`qiskit.providers.ibmq.runtime.RuntimeEncoder` and + :class:`qiskit_ibm_runtime.utils.RuntimeDecoder` have been updated + to handle these ndarrays. diff --git a/test/ibmq/runtime/test_runtime.py b/test/ibmq/runtime/test_runtime.py index 9a519cc41..fb3bf446c 100644 --- a/test/ibmq/runtime/test_runtime.py +++ b/test/ibmq/runtime/test_runtime.py @@ -257,6 +257,19 @@ def test_encoder_datetime(self): decoded = json.loads(encoded, cls=RuntimeDecoder) self.assertEqual(decoded, obj) + def test_encoder_ndarray(self): + """Test encoding and decoding a numpy ndarray.""" + subtests = ( + {"ndarray": np.array([[1, 2, 3], [{"obj": 123}, 5, 6]], dtype=object)}, + {"ndarray": np.array([[1, 2, 3], [{"obj": 123}, 5, 6]])}, + {"ndarray": np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=int)}, + ) + for obj in subtests: + encoded = json.dumps(obj, cls=RuntimeEncoder) + self.assertIsInstance(encoded, str) + decoded = json.loads(encoded, cls=RuntimeDecoder) + self.assertTrue(np.array_equal(decoded["ndarray"], obj["ndarray"])) + def test_encoder_instruction(self): """Test encoding and decoding instructions""" subtests = ( From 5f4ec409c46b13badb87b1a4c31e66e3e1d2205c Mon Sep 17 00:00:00 2001 From: Kevin Tian Date: Fri, 18 Feb 2022 01:58:52 -0500 Subject: [PATCH 2/2] update reno --- releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml b/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml index ca25ea0c7..3771665b6 100644 --- a/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml +++ b/releasenotes/notes/numpy-ndarray-encoder-12745f022ec8ef0b.yaml @@ -3,5 +3,5 @@ fixes: - | Fixed an issue where numpy ndarrays with object types could not be serialized. :class:`qiskit.providers.ibmq.runtime.RuntimeEncoder` and - :class:`qiskit_ibm_runtime.utils.RuntimeDecoder` have been updated + :class:`qiskit.providers.ibmq.runtime.RuntimeDecoder` have been updated to handle these ndarrays.