Ejemplo n.º 1
0
def _hardware_aware_reset(
    mapping: ty.Dict[Qubit, int],
    circuit: QuantumCircuit,
    hardware: IBMQHardwareArchitecture,
) -> ty.Dict[Qubit, int]:
    starting_qubit = random.randint(0, hardware.qubit_number - 1)
    qubits: ty.List[int] = [starting_qubit]
    weights: ty.Dict[int, float] = dict()
    while len(qubits) < len(mapping):
        # 1. Update the weights
        for neighbour in hardware.neighbors(qubits[-1]):
            if neighbour not in qubits:
                if neighbour not in weights.keys():
                    weights[neighbour] = 0.5 * (
                        1 - hardware.get_qubit_readout_error(neighbour))
                else:
                    weights[neighbour] += (
                        weights.get(neighbour, 0) + 1 -
                        hardware.get_link_error_rate(qubits[-1], neighbour))
        # Find the best weighted qubit
        best_weight, best_qubit = 0, None
        for qubit, weight in weights.items():
            if weight > best_weight:
                best_qubit = qubit
                best_weight = weight
        # Insert it in the qubit list
        qubits.append(best_qubit)
        del weights[best_qubit]
    # Finally, return a mapping with the chosen qubits
    return {qubit: idx for qubit, idx in zip(mapping.keys(), qubits)}
Ejemplo n.º 2
0
def _hardware_aware_expand(
    mapping: ty.Dict[Qubit, int],
    circuit: QuantumCircuit,
    hardware: IBMQHardwareArchitecture,
) -> ty.Dict[Qubit, int]:
    qubits = list(mapping.values())
    idle_qubits = {mapping[qubit] for qubit in _get_idle_qubits(circuit)}
    used_qubits = list(set(qubits) - idle_qubits)
    if not idle_qubits:
        return _random_shuffle(mapping, circuit, hardware)
    # Compute a weight for each qubit.
    # A qubit with a lot of links to other qubits in the mapping is good.
    # A qubit with bad links is not that good.
    weights: ty.List[float] = list()
    outside_qubits_weights = dict()
    for qubit in used_qubits:
        weights.append(0.5 * (1 - hardware.get_qubit_readout_error(qubit)))
        for neighbour in hardware.neighbors(qubit):
            # Only count the neighbour if it is also in the mapping.
            if neighbour in used_qubits:
                weights[-1] += 1 - hardware.get_link_error_rate(
                    qubit, neighbour)
            # Else, we keep an eye on the qubits that are not in the mapping because
            # we will need the best of them to add it to the mapping.
            else:
                if neighbour not in outside_qubits_weights.keys():
                    outside_qubits_weights[neighbour] = 0.5 * (
                        1 - hardware.get_qubit_readout_error(qubit))
                else:
                    outside_qubits_weights[neighbour] += (
                        outside_qubits_weights.get(neighbour, 0) + 1 -
                        hardware.get_link_error_rate(qubit, neighbour))
    worst_qubit_index = _argmin(weights)
    best_outside_qubit_index = None
    best_outside_weight = 0
    for neighbour, weight in outside_qubits_weights.items():
        if weight > best_outside_weight:
            best_outside_qubit_index = neighbour
            best_outside_weight = weight
    # Now exchange the 2 qubits
    inverse_mapping = {v: k for k, v in mapping.items()}
    inverse_mapping[worst_qubit_index], inverse_mapping[
        best_outside_qubit_index] = (
            inverse_mapping[best_outside_qubit_index],
            inverse_mapping[worst_qubit_index],
        )
    return {v: k for k, v in inverse_mapping.items()}
Ejemplo n.º 3
0
def _get_swap_error_cost(node, hardware: IBMQHardwareArchitecture) -> float:
    source, sink = node
    cnot_fidelity = 1 - hardware.get_link_error_rate(source, sink)
    reversed_cnot_fidelity = 1 - hardware.get_link_error_rate(sink, source)
    return 1 - cnot_fidelity * reversed_cnot_fidelity * max(
        cnot_fidelity, reversed_cnot_fidelity)