Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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