Beispiel #1
0
def save_qiskit_noise_model(noise_model: AerNoise.NoiseModel, filename: str) -> None:
    """Save a qiskit aer noise model to file
    Args:
        noise_model (qiskit.providers.aer.noise.NoiseModel): the noise model to be saved
        filename (str): the name of the file
    """

    data = {
        "module_name": "qeqiskit.utils",
        "function_name": "load_qiskit_noise_model",
        "schema": SCHEMA_VERSION + "-noise-model",
        "data": noise_model.to_dict(serializable=True),
    }

    with open(filename, "w") as f:
        f.write(json.dumps(data, indent=2))
Beispiel #2
0
    def test_from_dict(self):
        noise_ops_1q = [((IGate(), [0]), 0.9),
                     ((XGate(), [0]), 0.1)]

        noise_ops_2q = [((PauliGate('II'), [0, 1]), 0.9),
                     ((PauliGate('IX'), [0, 1]), 0.045),
                     ((PauliGate('XI'), [0, 1]), 0.045),
                     ((PauliGate('XX'), [0, 1]), 0.01)]

        noise_model = NoiseModel()
        with self.assertWarns(DeprecationWarning):
            noise_model.add_quantum_error(QuantumError(noise_ops_1q, 1), 'h', [0])
            noise_model.add_quantum_error(QuantumError(noise_ops_1q, 1), 'h', [1])
            noise_model.add_quantum_error(QuantumError(noise_ops_2q, 2), 'cx', [0, 1])
            noise_model.add_quantum_error(QuantumError(noise_ops_2q, 2), 'cx', [1, 0])
            deserialized = NoiseModel.from_dict(noise_model.to_dict())
            self.assertEqual(noise_model, deserialized)
Beispiel #3
0
def _process_model(noise_model: NoiseModel, gate_set: Set[OpType]) -> dict:
    # obtain approximations for gate errors from noise model by using probability of
    #  "identity" error
    assert OpType.CX in gate_set
    # TODO explicitly check for and separate 1 and 2 qubit gates
    supported_single_optypes = gate_set.difference({OpType.CX})
    supported_single_optypes.add(OpType.Reset)
    errors = [
        e for e in noise_model.to_dict()["errors"]
        if e["type"] == "qerror" or e["type"] == "roerror"
    ]
    link_ers_dict: dict = {}
    node_ers_dict: dict = defaultdict(
        lambda: QubitErrorContainer(supported_single_optypes))
    readout_errors_dict: dict = {}
    generic_single_qerrors_dict: dict = defaultdict(lambda: list())
    generic_2q_qerrors_dict: dict = defaultdict(lambda: list())

    node_ers_qubits: set = set()
    link_ers_qubits: set = set()

    coupling_map = []
    for error in errors:
        name = error["operations"]
        if len(name) > 1:
            raise RuntimeWarning("Error applies to multiple gates.")
        if "gate_qubits" not in error:
            raise RuntimeWarning(("Please define NoiseModel without using the"
                                  " add_all_qubit_quantum_error()"
                                  " or add_all_qubit_readout_error() method."))
        name = name[0]

        qubits = error["gate_qubits"][0]
        node_ers_qubits.add(qubits[0])
        gate_fid = error["probabilities"][-1]
        if len(qubits) == 1:
            if error["type"] == "qerror":
                node_ers_dict[qubits[0]].add_error(
                    (_gate_str_2_optype[name], 1 - gate_fid))
                generic_single_qerrors_dict[qubits[0]].append(
                    (error["instructions"], error["probabilities"]))
            elif error["type"] == "roerror":
                node_ers_dict[qubits[0]].add_readout(
                    error["probabilities"][0][1])
                readout_errors_dict[qubits[0]] = error["probabilities"]
            else:
                raise RuntimeWarning("Error type not 'qerror' or 'roerror'.")
        elif len(qubits) == 2:
            # note that if multiple multi-qubit errors are added to the CX gate,
            #  the resulting noise channel is composed and reflected in probabilities
            error_cont = QubitErrorContainer(
                {_gate_str_2_optype[name]: 1 - gate_fid})
            link_ers_qubits.add(qubits[0])
            link_ers_qubits.add(qubits[1])
            link_ers_dict[tuple(qubits)] = error_cont
            # to simulate a worse reverse direction square the fidelity
            rev_error_cont = QubitErrorContainer(
                {_gate_str_2_optype[name]: 1 - gate_fid**2})
            link_ers_dict[tuple(qubits[::-1])] = rev_error_cont
            generic_2q_qerrors_dict[tuple(qubits)].append(
                (error["instructions"], error["probabilities"]))
            coupling_map.append(qubits)

    free_qubits = node_ers_qubits - link_ers_qubits

    for q in free_qubits:
        for lq in link_ers_qubits:
            coupling_map.append([q, lq])
            coupling_map.append([lq, q])

    for pair in itertools.permutations(free_qubits, 2):
        coupling_map.append(pair)

    # convert qubits to architecture Nodes
    characterisation = {}
    node_ers_dict = {
        Node(q_index): ers
        for q_index, ers in node_ers_dict.items()
    }
    link_ers_dict = {(Node(q_indices[0]), Node(q_indices[1])): ers
                     for q_indices, ers in link_ers_dict.items()}

    characterisation["NodeErrors"] = node_ers_dict
    characterisation["EdgeErrors"] = link_ers_dict
    characterisation["ReadoutErrors"] = readout_errors_dict
    characterisation["GenericOneQubitQErrors"] = generic_single_qerrors_dict
    characterisation["GenericTwoQubitQErrors"] = generic_2q_qerrors_dict
    characterisation["Architecture"] = Architecture(coupling_map)

    return characterisation