From 160798b8638d3ff54680f3fb763f01cc5e809eaf Mon Sep 17 00:00:00 2001 From: Max Rossmannek Date: Tue, 10 Sep 2024 11:41:47 +0200 Subject: [PATCH] fix: compatibility with Windows --- qiskit_addon_obp/backpropagation.py | 7 ++++++ test/test_backpropagation.py | 38 +++++++++++++++++------------ test/utils/test_metadata.py | 3 ++- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/qiskit_addon_obp/backpropagation.py b/qiskit_addon_obp/backpropagation.py index 5df49fe..bbf22ba 100644 --- a/qiskit_addon_obp/backpropagation.py +++ b/qiskit_addon_obp/backpropagation.py @@ -17,6 +17,7 @@ import copy import logging import signal +import sys from collections.abc import Sequence from qiskit import QuantumCircuit @@ -68,6 +69,9 @@ def backpropagate( the ``truncation_error_budget`` argument. Refer to the :func:`~qiskit_addon_obp.utils.truncating.setup_budget` documentation for more details. + .. warning:: + The ``max_seconds`` argument is not available on Windows! + Args: observables: The observable(s) onto which the circuit is backpropagated. slices: A sequence of ``QuantumCircuit`` objects representing a single circuit which @@ -92,6 +96,7 @@ def backpropagate( - A metadata container. Raises: + RuntimeError: If the ``max_seconds`` argument is attempted to be used on Windows. ValueError: All observables and slices must act on equivalent numbers of qubits. ValueError: An input observable is larger than the constraints specified by ``operator_budget``. ValueError: ``operator_budget.max_paulis`` or ``operator_budget.max_qwc_groups`` is less than 1. @@ -122,6 +127,8 @@ def backpropagate( ) if max_seconds is not None: + if sys.platform == "win32": + raise RuntimeError("The `max_seconds` argument is not available on Windows.") def handle_timeout(signum, frame): raise TimeoutException() diff --git a/test/test_backpropagation.py b/test/test_backpropagation.py index b0e89f5..8b60f5a 100644 --- a/test/test_backpropagation.py +++ b/test/test_backpropagation.py @@ -12,6 +12,7 @@ """Tests for operator backpropagation utility functions.""" +import sys import time import unittest from math import e @@ -875,17 +876,21 @@ def test_backpropagate_multi(self): backpropagate(obs, slices, operator_budget=op_budget) def test_backpropagate_timeout(self): + qc = QuantumCircuit(2) + qc.rx(0.1, 0) + qc.ry(0.1, 0) + qc.rz(0.1, 0) + qc.cx(0, 1) + slices = slice_by_depth(qc, 1) + obs = SparsePauliOp("IX") + + on_win = sys.platform == "win32" with self.subTest("Actual timeout"): - qc = QuantumCircuit(2) - qc.rx(0.1, 0) - qc.ry(0.1, 0) - qc.rz(0.1, 0) - qc.cx(0, 1) - slices = slice_by_depth(qc, 1) - slices = 100_000 * slices - obs = SparsePauliOp("IX") + if on_win: + pytest.skip("Does not run on Windows") + many_slices = 100_000 * slices t1 = time.time() - _, new_qc, _ = backpropagate(obs, slices, max_seconds=1) + _, new_qc, _ = backpropagate(obs, many_slices, max_seconds=1) t2 = time.time() with self.subTest("Time should be less than 2 seconds"): @@ -895,13 +900,8 @@ def test_backpropagate_timeout(self): assert len(new_qc) > 0 with self.subTest("Reset timeout"): - qc = QuantumCircuit(2) - qc.rx(0.1, 0) - qc.ry(0.1, 0) - qc.rz(0.1, 0) - qc.cx(0, 1) - slices = slice_by_depth(qc, 1) - obs = SparsePauliOp("IX") + if on_win: + pytest.skip("Does not run on Windows") t1 = time.time() _, new_qc, _ = backpropagate(obs, slices, max_seconds=1) t2 = time.time() @@ -910,3 +910,9 @@ def test_backpropagate_timeout(self): assert len(new_qc) == 0 sleep(1) + + with self.subTest("Handle windows"): + if not on_win: + pytest.skip("Only on Windows") + with self.assertRaises(RuntimeError): + _, _, _ = backpropagate(obs, slices, max_seconds=1) diff --git a/test/utils/test_metadata.py b/test/utils/test_metadata.py index 6ff0d09..52b0c6f 100644 --- a/test/utils/test_metadata.py +++ b/test/utils/test_metadata.py @@ -14,6 +14,7 @@ from __future__ import annotations +import sys import tempfile import unittest @@ -170,7 +171,7 @@ def test_from_json(self): self.assertEqual(metadata, self.expected) def test_to_json(self): - with tempfile.NamedTemporaryFile() as file: + with tempfile.NamedTemporaryFile(delete=sys.platform != "win32") as file: self.expected.to_json(file.name, indent=2) with (