Skip to content

Commit

Permalink
use deepdiff to get differences between gpu and cpu results
Browse files Browse the repository at this point in the history
  • Loading branch information
olliesilvester committed Sep 5, 2024
1 parent 99b8f49 commit 149c2bd
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ dev = [
"types-mock",
"types-PyYAML",
"types-aiofiles",
"deepdiff",
]

[project.scripts]
Expand Down
21 changes: 16 additions & 5 deletions src/dodal/devices/zocalo/zocalo_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import workflows.recipe
import workflows.transport
from bluesky.protocols import Descriptor, Triggerable
from deepdiff import DeepDiff
from numpy.typing import NDArray
from ophyd_async.core import HintedSignal, StandardReadable, soft_signal_r_and_setter
from ophyd_async.core.async_status import AsyncStatus
Expand Down Expand Up @@ -60,11 +61,21 @@ def get_dict_differences(
dict1: dict, dict1_source: str, dict2: dict, dict2_source: str
) -> str:
differences_str = ""
for key in dict1.keys():
if not dict1[key] == dict2[key]:
differences_str += f"Results differed in {key}: {dict1_source} contains {dict1[key]} while {dict2_source} contains {dict2[key]} \n"
if differences_str:
LOGGER.warning(differences_str)
diff = DeepDiff(dict1, dict2, math_epsilon=1e-5, ignore_numeric_type_changes=True)
# diff is None if there are no differences, otherwise a dictionary with various keys depending
# on the type of difference detected. Eg 'values_changed', dictionary_item_added', 'iterable_item_added'

if diff:
differences_str += (
f"Differences found between {dict1_source} and {dict2_source} results:\n"
)

# Format the difference more nicely in a string
for key, value in diff.items():
if key == "values_changed":
differences_str += f" {key}: {str(value).replace('old_value', dict1_source).replace('new_value', dict2_source)}\n"
else:
differences_str += f" {key}: {value}\n"
return differences_str


Expand Down
48 changes: 43 additions & 5 deletions tests/devices/unit_tests/test_zocalo_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,48 @@ async def test_if_cpu_results_arrive_before_gpu_then_warn(
)


@pytest.mark.parametrize(
"dict1,dict2,output",
[
(
{"ispyb_ids": {"gpu": True}, "results": [{"test": 0}]},
{"ispyb_ids": {}, "results": [{"test": 1}]},
"Differences found between GPU and CPU results:\n values_changed: {\"root['test']\": {'CPU': 1, 'GPU': 0}}\n",
),
(
{
"ispyb_ids": {"gpu": True},
"results": [{"test": [[1, 2 + 1e-6, 3], [1, 2, 3]]}],
},
{"ispyb_ids": {}, "results": [{"test": [[1, 2, 3], [1, 2, 3]]}]},
None,
),
(
{
"ispyb_ids": {"gpu": True},
"results": [
{"test": [[1, 2 + 1e-6, 3], [1, 2, 3]], "extra_key": "test"}
],
},
{"ispyb_ids": {}, "results": [{"test": [[1, 2, 3], [1, 2, 3]]}]},
"Differences found between GPU and CPU results:\n dictionary_item_removed: SetOrdered([\"root['extra_key']\"])\n",
),
(
{
"ispyb_ids": {"gpu": False},
"results": [
{"test": [[1, 2 + 1e-6, 3], [1, 2, 3]], "extra_key": "test"}
],
},
{"ispyb_ids": {}, "results": [{"test": [[1, 3, 3], [1, 2, 3]]}]},
"Differences found between CPU and GPU results:\n dictionary_item_removed: SetOrdered([\"root['extra_key']\"])\n values_changed: {\"root['test'][0][1]\": {'GPU': 3, 'CPU': 2.000001}}\n",
),
],
)
@patch("dodal.devices.zocalo.zocalo_results.LOGGER")
@patch("dodal.devices.zocalo.zocalo_results._get_zocalo_connection", autospec=True)
async def test_warning_if_results_are_different(
mock_connection, mock_logger, RE: RunEngine
mock_connection, mock_logger, RE: RunEngine, dict1, dict2, output
):
zocalo_results = ZocaloResults(
name="zocalo", zocalo_environment="dev_artemis", use_cpu_and_gpu_zocalo=True
Expand All @@ -369,14 +407,14 @@ async def test_warning_if_results_are_different(
await zocalo_results.stage()
zocalo_results._raw_results_received.get = MagicMock(
side_effect=[
{"ispyb_ids": {}, "results": [{"test": 0}]},
{"ispyb_ids": {}, "results": [{"test": 1}]},
dict1,
dict2,
]
)
RE(bps.trigger(zocalo_results, wait=False))
mock_logger.warning.assert_called_with(
"Results differed in test: CPU contains 0 while GPU contains 1 \n"
)
output
) if output else mock_logger.warning.assert_not_called()


@patch("dodal.devices.zocalo.zocalo_results._get_zocalo_connection", autospec=True)
Expand Down

0 comments on commit 149c2bd

Please sign in to comment.