diff --git a/src/qibo/models/circuit.py b/src/qibo/models/circuit.py index 94a8f8ab28..3e5d132b1f 100644 --- a/src/qibo/models/circuit.py +++ b/src/qibo/models/circuit.py @@ -158,8 +158,9 @@ def __init__(self, nqubits, accelerators=None, density_matrix=False): self._final_state = None self.compiled = None - self.repeated_execution = False + self.has_collapse = False + self.has_unitary_channel = False self.density_matrix = density_matrix # for distributed circuits @@ -249,13 +250,14 @@ def __add__(self, circuit): for gate in circuit.queue: newcircuit.add(gate) - # Re-execute full circuit when sampling if one of the circuits - # has repeated_execution ``True`` - newcircuit.repeated_execution = ( - self.repeated_execution or circuit.repeated_execution - ) return newcircuit + @property + def repeated_execution(self): + return self.has_collapse or ( + self.has_unitary_channel and not self.density_matrix + ) + def on_qubits(self, *qubits): """Generator of gates contained in the circuit acting on specified qubits. @@ -591,7 +593,7 @@ def add(self, gate): gate.result.circuit = self if gate.collapse: - self.repeated_execution = True + self.has_collapse = True else: self.measurements.append(gate) return gate.result @@ -601,11 +603,11 @@ def add(self, gate): for measurement in list(self.measurements): if set(measurement.qubits) & set(gate.qubits): measurement.collapse = True - self.repeated_execution = True + self.has_collapse = True self.measurements.remove(measurement) if isinstance(gate, gates.UnitaryChannel): - self.repeated_execution = not self.density_matrix + self.has_unitary_channel = True if isinstance(gate, gates.ParametrizedGate): self.parametrized_gates.append(gate) if gate.trainable: diff --git a/tests/test_models_circuit_execution.py b/tests/test_models_circuit_execution.py index 1a5705bedc..260c59a3b9 100644 --- a/tests/test_models_circuit_execution.py +++ b/tests/test_models_circuit_execution.py @@ -64,7 +64,7 @@ def test_repeated_execute(backend, accelerators): c.add((gates.RY(i, t) for i, t in enumerate(thetas))) target_state = backend.execute_circuit(c).state(numpy=True) target_state = np.array(20 * [target_state]) - c.repeated_execution = True + c.has_collapse = True final_state = backend.execute_circuit(c, nshots=20) final_state = [backend.to_numpy(x) for x in final_state] backend.assert_allclose(final_state, target_state)