def create_from_backend(cls, backend: Backend):
        """Initialize a class with backend information provided by provider.

        Args:
            backend: Backend object.

        Returns:
            OpenPulseBackendInfo: New configured instance.
        """
        configuration = backend.configuration()
        defaults = backend.defaults()

        # load name
        name = backend.name()

        # load cycle time
        dt = configuration.dt

        # load frequencies
        chan_freqs = {}

        chan_freqs.update({
            pulse.DriveChannel(qind): freq
            for qind, freq in enumerate(defaults.qubit_freq_est)
        })
        chan_freqs.update({
            pulse.MeasureChannel(qind): freq
            for qind, freq in enumerate(defaults.meas_freq_est)
        })
        for qind, u_lo_mappers in enumerate(configuration.u_channel_lo):
            temp_val = 0.0 + 0.0j
            for u_lo_mapper in u_lo_mappers:
                temp_val += defaults.qubit_freq_est[
                    u_lo_mapper.q] * u_lo_mapper.scale
            chan_freqs[pulse.ControlChannel(qind)] = temp_val.real

        # load qubit channel mapping
        qubit_channel_map = defaultdict(list)
        for qind in range(configuration.n_qubits):
            qubit_channel_map[qind].append(configuration.drive(qubit=qind))
            qubit_channel_map[qind].append(configuration.measure(qubit=qind))
            for tind in range(configuration.n_qubits):
                try:
                    qubit_channel_map[qind].extend(
                        configuration.control(qubits=(qind, tind)))
                except BackendConfigurationError:
                    pass

        return OpenPulseBackendInfo(name=name,
                                    dt=dt,
                                    channel_frequency_map=chan_freqs,
                                    qubit_channel_map=qubit_channel_map)
Example #2
0
    def get_error_dict_from_backend(
        backend: Backend, qubits: Sequence[int]
    ) -> Dict[Tuple[Sequence[int], str], float]:
        """Attempts to extract error estimates for gates from the backend
        properties.
        Those estimates are used to assign weights for different gate types
        when computing error per gate.

        Args:
            backend: The backend from which the properties are taken
            qubits: The qubits participating in the experiment, used
              to filter irrelevant gates from the result.

        Returns:
            A dictionary of the form (qubits, gate) -> value that for each
            gate on the given qubits gives its recorded error estimate.
        """
        error_dict = {}
        try:
            for backend_gate in backend.properties().gates:
                backend_gate = backend_gate.to_dict()
                gate_qubits = tuple(backend_gate["qubits"])
                if all(gate_qubit in qubits for gate_qubit in gate_qubits):
                    for p in backend_gate["parameters"]:
                        if p["name"] == "gate_error":
                            error_dict[(gate_qubits, backend_gate["gate"])] = p["value"]
        except AttributeError:
            # might happen if the backend has no properties (e.g. qasm simulator)
            return None
        return error_dict
 def test_invalid_backend(self):
     """Test from_backend() with an invalid backend."""
     with self.assertRaises(AttributeError):
         PassManagerConfig.from_backend(Backend())
    def run(
        self,
        backend: Backend,
        analysis: bool = True,
        experiment_data: Optional[ExperimentData] = None,
        **run_options,
    ) -> ExperimentData:
        """Run an experiment and perform analysis.

        Args:
            backend: The backend to run the experiment on.
            analysis: If True run analysis on the experiment data.
            experiment_data: Optional, add results to existing
                experiment data. If None a new ExperimentData object will be
                returned.
            run_options: backend runtime options used for circuit execution.

        Returns:
            The experiment data object.

        Raises:
            QiskitError: if experiment is run with an incompatible existing
                         ExperimentData container.
        """
        # Create experiment data container
        experiment_data = self._initialize_experiment_data(
            backend, experiment_data)

        # Run options
        run_opts = copy.copy(self.run_options)
        run_opts.update_options(**run_options)
        run_opts = run_opts.__dict__

        # Scheduling parameters
        if backend.configuration().simulator is False and isinstance(
                backend, FakeBackend) is False:
            timing_constraints = getattr(self.transpile_options.__dict__,
                                         "timing_constraints", {})
            timing_constraints["acquire_alignment"] = getattr(
                timing_constraints, "acquire_alignment", 16)
            scheduling_method = getattr(self.transpile_options.__dict__,
                                        "scheduling_method", "alap")
            self.set_transpile_options(timing_constraints=timing_constraints,
                                       scheduling_method=scheduling_method)

        # Generate and transpile circuits
        transpile_opts = copy.copy(self.transpile_options.__dict__)
        transpile_opts["initial_layout"] = list(self._physical_qubits)
        circuits = transpile(self.circuits(backend), backend, **transpile_opts)
        self._postprocess_transpiled_circuits(circuits, backend, **run_options)

        # Run experiment jobs
        max_experiments = getattr(backend.configuration(), "max_experiments",
                                  None)
        if max_experiments and len(circuits) > max_experiments:
            # Split jobs for backends that have a maximum job size
            job_circuits = [
                circuits[i:i + max_experiments]
                for i in range(0, len(circuits), max_experiments)
            ]
        else:
            # Run as single job
            job_circuits = [circuits]

        # Run jobs
        jobs = []
        for circs in job_circuits:
            if isinstance(backend, LegacyBackend):
                qobj = assemble(circs, backend=backend, **run_opts)
                job = backend.run(qobj)
            else:
                job = backend.run(circs, **run_opts)
            jobs.append(job)

        # Add experiment option metadata
        self._add_job_metadata(experiment_data, jobs, **run_opts)

        # Add jobs
        experiment_data.add_data(jobs)

        # Optionally run analysis
        if analysis and self.__analysis_class__:
            experiment_data.add_analysis_callback(self.run_analysis)

        # Return the ExperimentData future
        return experiment_data