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)
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