def _add_layer(self, gate: gates.Gate): """Called automatically by `add` when `gate` is measurement.""" gate.prepare() for unitary in gate.unitaries: self.set_nqubits(unitary) self.queue.append(unitary) if gate.additional_unitary is not None: self.set_nqubits(gate.additional_unitary) self.queue.append(gate.additional_unitary)
def _add(self, gate: gates.Gate): if gate.density_matrix and not self.density_matrix: raise_error( ValueError, "Cannot add {} on circuits that uses state " "vectors. Please switch to density matrix " "circuit.".format(gate.name)) elif self.density_matrix: gate.density_matrix = True if self._final_state is not None: raise_error( RuntimeError, "Cannot add gates to a circuit after it is " "executed.") for q in gate.target_qubits: if q >= self.nqubits: raise_error( ValueError, "Attempting to add gate with target qubits {} " "on a circuit of {} qubits." "".format(gate.target_qubits, self.nqubits)) self.check_measured(gate.qubits) if isinstance(gate, gates.M): self._add_measurement(gate) elif isinstance(gate, gates.VariationalLayer): self._add_layer(gate) else: self.set_nqubits(gate) self.queue.append(gate) if isinstance(gate, gates.UnitaryChannel): self.repeated_execution = not self.density_matrix if isinstance(gate, gates.ParametrizedGate): self.parametrized_gates.append(gate) if gate.trainable: self.trainable_gates.append(gate)
def _add(self, gate: gates.Gate): """Adds a gate in the circuit (inherited from :class:`qibo.base.circuit.BaseCircuit`). Also checks that there are sufficient qubits to use as global. """ if not isinstance(gate, gate_module.TensorflowGate): raise_error( NotImplementedError, "Distributed circuit does not support " "native tensorflow gates.") if isinstance(gate, gates.VariationalLayer): gate._prepare() elif (self.nqubits - len(gate.target_qubits) < self.nglobal and not isinstance(gate, gates.M)): raise_error( ValueError, "Insufficient qubits to use for global in " "distributed circuit.") super(TensorflowDistributedCircuit, self)._add(gate)
def _add_measurement(self, gate: gates.Gate): """Called automatically by `add` when `gate` is measurement. This is because measurement gates (`gates.M`) are treated differently than all other gates. The user is not supposed to use the `add_measurement` method. """ # Set register's name and log the set of qubits in `self.measurement_tuples` name = gate.register_name if name is None: name = "register{}".format(len(self.measurement_tuples)) gate.register_name = name elif name in self.measurement_tuples: raise_error( KeyError, "Register name {} has already been used." "".format(name)) # Update circuit's global measurement gate if self.measurement_gate is None: self.measurement_gate = gate self.measurement_tuples[name] = tuple(gate.target_qubits) else: self.measurement_gate.add(gate) self.measurement_tuples[name] = gate.target_qubits