diff --git a/src/qibo/core/distcircuit.py b/src/qibo/core/distcircuit.py index 84020054e5..f3ad68c0f8 100644 --- a/src/qibo/core/distcircuit.py +++ b/src/qibo/core/distcircuit.py @@ -219,7 +219,7 @@ def execute(self, initial_state=None, nshots=None): def get_initial_state(self, state=None): """""" - if not self.queues.queues and self.queue: + if not self.queues.queues: self.queues.set(self.queue) if state is None: diff --git a/src/qibo/core/distutils.py b/src/qibo/core/distutils.py index 07dd74cb8d..5f7b46bc41 100644 --- a/src/qibo/core/distutils.py +++ b/src/qibo/core/distutils.py @@ -116,15 +116,13 @@ def set(self, queue: List[gates.Gate]): This method also creates the ``DistributedQubits`` object holding the global qubits list. """ - if not queue: - raise_error(RuntimeError, "No gates available to set for distributed run.") - counter = self.count(queue, self.nqubits) if self.qubits is None: self.qubits = DistributedQubits(counter.argsort()[:self.nglobal], self.nqubits) - transformed_queue = self.transform(queue, counter) - self.create(transformed_queue) + if queue: + transformed_queue = self.transform(queue, counter) + self.create(transformed_queue) def _ids(self, calc_devices: Dict[str, int]) -> Tuple[str, List[int]]: """Generator of device piece indices.""" diff --git a/src/qibo/tests/test_core_distcircuit.py b/src/qibo/tests/test_core_distcircuit.py index e235f1929a..ddf8c6a3a8 100644 --- a/src/qibo/tests/test_core_distcircuit.py +++ b/src/qibo/tests/test_core_distcircuit.py @@ -72,11 +72,6 @@ def test_distributed_circuit_set_gates(backend): for queues in c.queues.queues[0]: assert len(queues) == 4 - # Attempt to set gates before adding any gate - c = DistributedCircuit(6, devices) - with pytest.raises(RuntimeError): - c.queues.set(c.queue) - def test_distributed_circuit_set_gates_controlled(backend): devices = {"/GPU:0": 2, "/GPU:1": 2} diff --git a/src/qibo/tests/test_core_distcircuit_execution.py b/src/qibo/tests/test_core_distcircuit_execution.py index 96a38831a3..bd422b6132 100644 --- a/src/qibo/tests/test_core_distcircuit_execution.py +++ b/src/qibo/tests/test_core_distcircuit_execution.py @@ -1,7 +1,7 @@ """Test functions defined in `qibo/core/distcircuit.py`.""" import pytest import numpy as np -from qibo import gates +from qibo import K, gates from qibo.models import Circuit from qibo.core.distcircuit import DistributedCircuit from qibo.tests.utils import random_state @@ -22,7 +22,7 @@ def test_distributed_circuit_execution(backend, accelerators, use_global_qubits) initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) - np.testing.assert_allclose(target_state, final_state) + K.assert_allclose(target_state, final_state) def test_distributed_circuit_execution_pretransformed(backend, accelerators): @@ -39,7 +39,7 @@ def test_distributed_circuit_execution_pretransformed(backend, accelerators): initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) - np.testing.assert_allclose(target_state, final_state) + K.assert_allclose(target_state, final_state) def test_distributed_circuit_execution_with_swap(backend, accelerators): @@ -55,7 +55,7 @@ def test_distributed_circuit_execution_with_swap(backend, accelerators): initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) - np.testing.assert_allclose(target_state, final_state) + K.assert_allclose(target_state, final_state) def test_distributed_circuit_execution_special_gate(backend, accelerators): @@ -67,7 +67,7 @@ def test_distributed_circuit_execution_special_gate(backend, accelerators): c = Circuit(6) c.add(gates.Flatten(np.copy(initial_state))) c.add((gates.H(i) for i in range(dist_c.nlocal))) - np.testing.assert_allclose(dist_c(), c()) + K.assert_allclose(dist_c(), c()) def test_distributed_circuit_execution_controlled_gate(backend, accelerators): @@ -81,7 +81,7 @@ def test_distributed_circuit_execution_controlled_gate(backend, accelerators): initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) - np.testing.assert_allclose(target_state, final_state) + K.assert_allclose(target_state, final_state) def test_distributed_circuit_execution_controlled_by_gates(backend, accelerators): @@ -102,7 +102,7 @@ def test_distributed_circuit_execution_controlled_by_gates(backend, accelerators initial_state = random_state(c.nqubits) final_state = dist_c(np.copy(initial_state)) target_state = c(np.copy(initial_state)) - np.testing.assert_allclose(target_state, final_state) + K.assert_allclose(target_state, final_state) def test_distributed_circuit_execution_addition(backend, accelerators): @@ -124,4 +124,22 @@ def test_distributed_circuit_execution_addition(backend, accelerators): c.add([gates.CNOT(i, i + 1) for i in range(5)]) c.add([gates.Z(i) for i in range(6)]) assert c.depth == dist_c.depth - np.testing.assert_allclose(dist_c(), c()) + K.assert_allclose(dist_c(), c()) + + +def test_distributed_circuit_empty_execution(backend, accelerators): + # test executing a circuit with the default initial state + c = DistributedCircuit(5, accelerators) + final_state = c().state() + target_state = np.zeros_like(final_state) + target_state[0] = 1 + K.assert_allclose(final_state, target_state) + # test re-executing the circuit with a given initial state + initial_state = random_state(c.nqubits) + K.assert_allclose(c(initial_state), initial_state) + # test executing a new circuit with a given initial state + c = DistributedCircuit(5, accelerators) + initial_state = random_state(c.nqubits) + K.assert_allclose(c(initial_state), initial_state) + # test re-executing the circuit with the default initial state + K.assert_allclose(c(), target_state)