def convert_to_target(conf_dict: dict, props_dict: dict = None, defs_dict: dict = None) -> Target: """Uses configuration, properties and pulse defaults dicts to construct and return Target class. """ name_mapping = { "id": IGate(), "sx": SXGate(), "x": XGate(), "cx": CXGate(), "rz": RZGate(Parameter("λ")), "reset": Reset(), } custom_gates = {} qubit_props = None if props_dict: qubit_props = qubit_props_from_props(props_dict) target = Target(qubit_properties=qubit_props) # Parse from properties if it exsits if props_dict is not None: # Parse instructions gates = {} for gate in props_dict["gates"]: name = gate["gate"] if name in name_mapping: if name not in gates: gates[name] = {} elif name not in custom_gates: custom_gate = Gate(name, len(gate["qubits"]), []) custom_gates[name] = custom_gate gates[name] = {} qubits = tuple(gate["qubits"]) gate_props = {} for param in gate["parameters"]: if param["name"] == "gate_error": gate_props["error"] = param["value"] if param["name"] == "gate_length": gate_props["duration"] = apply_prefix( param["value"], param["unit"]) gates[name][qubits] = InstructionProperties(**gate_props) for gate, props in gates.items(): if gate in name_mapping: inst = name_mapping.get(gate) else: inst = custom_gates[gate] target.add_instruction(inst, props) # Create measurement instructions: measure_props = {} count = 0 for qubit in props_dict["qubits"]: qubit_prop = {} for prop in qubit: if prop["name"] == "readout_length": qubit_prop["duration"] = apply_prefix( prop["value"], prop["unit"]) if prop["name"] == "readout_error": qubit_prop["error"] = prop["value"] measure_props[(count, )] = InstructionProperties(**qubit_prop) count += 1 target.add_instruction(Measure(), measure_props) # Parse from configuration because properties doesn't exist else: for gate in conf_dict["gates"]: name = gate["name"] gate_props = {tuple(x): None for x in gate["coupling_map"]} if name in name_mapping: target.add_instruction(name_mapping[name], gate_props) else: custom_gate = Gate(name, len(gate["coupling_map"][0]), []) target.add_instruction(custom_gate, gate_props) measure_props = {(n, ): None for n in range(conf_dict["n_qubits"])} target.add_instruction(Measure(), measure_props) # parse global configuration properties dt = conf_dict.get("dt") if dt: target.dt = dt * 1e-9 if "timing_constraints" in conf_dict: target.granularity = conf_dict["timing_constraints"].get("granularity") target.min_length = conf_dict["timing_constraints"].get("min_length") target.pulse_alignment = conf_dict["timing_constraints"].get( "pulse_alignment") target.aquire_alignment = conf_dict["timing_constraints"].get( "acquire_alignment") # If pulse defaults exists use that as the source of truth if defs_dict is not None: # TODO remove the usage of PulseDefaults as it will be deprecated in the future pulse_defs = PulseDefaults.from_dict(defs_dict) inst_map = pulse_defs.instruction_schedule_map for inst in inst_map.instructions: for qarg in inst_map.qubits_with_instruction(inst): sched = inst_map.get(inst, qarg) if inst in target: try: qarg = tuple(qarg) except TypeError: qarg = (qarg, ) if inst == "measure": for qubit in qarg: target[inst][(qubit, )].calibration = sched else: target[inst][qarg].calibration = sched target.add_instruction(Delay(Parameter("t")), {(bit, ): None for bit in range(target.num_qubits)}) return target
def convert_to_target( configuration: BackendConfiguration, properties: BackendProperties = None, defaults: PulseDefaults = None, ) -> Target: """Uses configuration, properties and pulse defaults to construct and return Target class. """ name_mapping = { "id": IGate(), "sx": SXGate(), "x": XGate(), "cx": CXGate(), "rz": RZGate(Parameter("λ")), "reset": Reset(), } custom_gates = {} target = None # Parse from properties if it exsits if properties is not None: qubit_properties = qubit_props_list_from_props(properties=properties) target = Target( num_qubits=configuration.n_qubits, qubit_properties=qubit_properties ) # Parse instructions gates: Dict[str, Any] = {} for gate in properties.gates: name = gate.gate if name in name_mapping: if name not in gates: gates[name] = {} elif name not in custom_gates: custom_gate = Gate(name, len(gate.qubits), []) custom_gates[name] = custom_gate gates[name] = {} qubits = tuple(gate.qubits) gate_props = {} for param in gate.parameters: if param.name == "gate_error": gate_props["error"] = param.value if param.name == "gate_length": gate_props["duration"] = apply_prefix(param.value, param.unit) gates[name][qubits] = InstructionProperties(**gate_props) for gate, props in gates.items(): if gate in name_mapping: inst = name_mapping.get(gate) else: inst = custom_gates[gate] target.add_instruction(inst, props) # Create measurement instructions: measure_props = {} for qubit, _ in enumerate(properties.qubits): measure_props[(qubit,)] = InstructionProperties( duration=properties.readout_length(qubit), error=properties.readout_error(qubit), ) target.add_instruction(Measure(), measure_props) # Parse from configuration because properties doesn't exist else: target = Target(num_qubits=configuration.n_qubits) for gate in configuration.gates: name = gate.name gate_props = ( {tuple(x): None for x in gate.coupling_map} # type: ignore[misc] if hasattr(gate, "coupling_map") else {None: None} ) gate_len = len(gate.coupling_map[0]) if hasattr(gate, "coupling_map") else 0 if name in name_mapping: target.add_instruction(name_mapping[name], gate_props) else: custom_gate = Gate(name, gate_len, []) target.add_instruction(custom_gate, gate_props) target.add_instruction(Measure()) # parse global configuration properties if hasattr(configuration, "dt"): target.dt = configuration.dt if hasattr(configuration, "timing_constraints"): target.granularity = configuration.timing_constraints.get("granularity") target.min_length = configuration.timing_constraints.get("min_length") target.pulse_alignment = configuration.timing_constraints.get("pulse_alignment") target.aquire_alignment = configuration.timing_constraints.get( "acquire_alignment" ) # If a pulse defaults exists use that as the source of truth if defaults is not None: inst_map = defaults.instruction_schedule_map for inst in inst_map.instructions: for qarg in inst_map.qubits_with_instruction(inst): sched = inst_map.get(inst, qarg) if inst in target: try: qarg = tuple(qarg) except TypeError: qarg = (qarg,) if inst == "measure": for qubit in qarg: target[inst][(qubit,)].calibration = sched else: target[inst][qarg].calibration = sched if "delay" not in target: target.add_instruction( Delay(Parameter("t")), {(bit,): None for bit in range(target.num_qubits)} ) return target