2
$\begingroup$

Right now I'm trying to figure out how to create custom fake backends using qiskit with data we are retrieving from our real backends in the laboratory.
As I understand, the best way to create one is to use GenericBackendV2.

Documentations says, that we can specify:

  • Number of qubits
  • List of basis gate names
  • Coupling map for the backend
  • Instruction calibration settings

But what about other characteristics? For instance, I want to set T1 / T2 times or each qubit's frequency and maybe even some measurement errors.

Documentations says:

The remainder of the backend properties are generated by randomly sampling from default ranges extracted from historical IBM backend data.

But can I somehow set it manually?

$\endgroup$

2 Answers 2

1
$\begingroup$

For setting T1/T2 times, measurement error, and other errors (like reset errors etc.) you can make a custom noise model by using the NoiseModel() function from the qiskit_aer.noise module.

Here is a high-level overview of how you can achieve this:

  1. To use this function, you first define what errors you want to model and on what gates you want to apply this errors.

  2. Then you add these errors to a noise model, and here you get to pick if you want to apply the noise models to all the qubits or just some specific qubits.

  3. After doing this, you can use your noise model in the AerSimulator() to simulate your circuit on the simulator or you can specify your custom backend to transpile and run your circuit.

Here is the link to the documentation for building noise models. Hope this helps!

$\endgroup$
4
  • $\begingroup$ Thank you for this clear explanation! And how can I apply such a Noise model to my GenericBackend instance? $\endgroup$
    – Ikaryssik
    Commented Apr 4 at 13:55
  • $\begingroup$ I just now realized that maybe you can achieve what you want in an easy way (I might be wrong). Take a look at the GenericBackendV2 python code from the qiskit GitHub. In this code on line 70 they define _QUBIT_PROPERTIES which consists of T1 and T2 information. Modify these for your custom backend. Now to include measurement noise, change the measure error in the _NOISE_DEFAULTS defined on line 50 and probably this will do the trick $\endgroup$ Commented Apr 5 at 0:29
  • $\begingroup$ Yes, I consider it recently too. Maybe, the answer that @Egretta.Thula proposed is the most convenient option. Looks like it is a "don't overthink" situation:) $\endgroup$
    – Ikaryssik
    Commented Apr 5 at 7:03
  • $\begingroup$ I still don't think it will be that simple. I think after you create your custom backend you might also have to make a custom passmanager to transpile your circuits. And this might be challenging. Hope you make it to work! Also, one more thing, the function that Egretta gave is not complete, use the full code from the github (the link in my answer) to create your custom backend because you will need other methods included in that code. $\endgroup$ Commented Apr 6 at 3:35
1
$\begingroup$

One option is to create a new class that inherits from GenericBackendV2 and accepts "noise settings". The below code shows how to do that

class MyFakeBackend(GenericBackendV2):
    def __init__(
        self,
        num_qubits: int,
        basis_gates: list[str] | None = None,
        *,
        coupling_map: list[list[int]] | CouplingMap | None = None,
        control_flow: bool = False,
        calibrate_instructions: bool | InstructionScheduleMap | None = None,
        noise_settings: dict,
        dtm: float | None = None,
        seed: int | None = None,
    ):

        self.noise_settings = noise_settings
        super().__init__(num_qubits, basis_gates,
            coupling_map=coupling_map,
            control_flow=control_flow,
            calibrate_instructions=calibrate_instructions,
            dtm=dtm,
            seed=seed)

    def _get_noise_defaults(self, name: str, num_qubits: int) -> tuple:
        if name in self.noise_settings:
            return self.noise_settings[name]

        if num_qubits == 1:
            return _NOISE_DEFAULTS_FALLBACK["1-q"]
        return _NOISE_DEFAULTS_FALLBACK["multi-q"]

Now, you can instantiate your fake backend as follow:

cmap = CouplingMap.from_full(27)
noise_settings = {
    "cz": (7.992e-08, 8.99988e-07, 1e-5, 5e-3),
    "id": (2.997e-08, 5.994e-08, 9e-5, 1e-4),
    "rz": (0.0, 0.0),
    "sx": (2.997e-08, 5.994e-08, 9e-5, 1e-4),
    "x": (2.997e-08, 5.994e-08, 9e-5, 1e-4),
    "measure": (6.99966e-07, 1.500054e-06, 1e-5, 5e-3),
    "delay": (None, None),
    "reset": (None, None),
}

fake = MyFakeBackend(num_qubits=27,
    basis_gates=['cz', 'id', 'rz', 'sx', 'x'],
    coupling_map=cmap,
    noise_settings=noise_settings)

Note that, noise_settings follows the same structure used internally in GenericBackendV2 for defining _NOISE_DEFAULTS, where there are two possible formats:

  • (min_duration, max_duration, min_error, max_error), for ranges.
  • (duration, error), for fixed values.
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.