{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "c08a245a-82c1-4c6f-b1e1-d0a27f093b7a",
      "metadata": {},
      "source": [
        "---\n",
        "title: Local testing mode\n",
        "description: Use local testing mode to simulate quantum hardware with IBM Quantum Compute\n",
        "---\n",
        "\n",
        "{/* cspell:ignore superop */}\n",
        "\n",
        "<span id=\"test-locally\" />\n",
        "\n",
        "# Local testing mode\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "14778d9c-4e0e-4b84-8575-90e4efab25a2",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Package versions\">\n",
        "    The code on this page was developed using the following requirements.\n",
        "    We recommend using these versions or newer.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    qiskit-aer~=0.17\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "435ec827-a348-4b70-b1ef-582849c0a76a",
      "metadata": {},
      "source": [
        "Use local testing mode (available with `qiskit-ibm-runtime` v0.22.0 or later) to test programs before fine-tuning them and sending them to real quantum hardware.  After using local testing mode to verify your program, all you need to change is the backend name to run it on a QPU.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  The Executor primitive does not support local testing mode.\n",
        "</Admonition>\n",
        "\n",
        "To use local testing mode, specify one of the fake backends from `qiskit_ibm_runtime.fake_provider` or specify a Qiskit Aer backend when instantiating an IBM Quantum primitive or a session.\n",
        "\n",
        "* **Fake backends**: The [fake backends](/docs/api/qiskit-ibm-runtime/fake-provider)  in `qiskit_ibm_runtime.fake_provider` mimic the behaviors of IBM® QPUs by using QPU snapshots. The QPU snapshots contain important information about the QPU, such as the coupling map, basis gates, and qubit properties, which are useful for testing the transpiler and performing noisy simulations of the QPU. The noise model from the snapshot is automatically applied during simulation.\n",
        "* **Aer simulator**: Simulators from [Qiskit Aer](/docs/guides/simulate-with-qiskit-aer) provide higher-performance simulation that can handle larger circuits and [custom noise models](/docs/guides/build-noise-models). A list of simulation method options are available when you use `AerSimulator` in local testing mode. See the [Clifford simulation mode example](#clifford-sim), which demonstrates how to efficiently simulate Clifford circuits with a large number of qubits.\n",
        "\n",
        "  <Accordion>\n",
        "    <AccordionItem title=\"**List of simulation methods available from Qiskit Aer**\">\n",
        "      See the [`AerSimulator`](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator) documentation for more information.\n",
        "\n",
        "      * `\"automatic\"`: Default simulation method. Select the simulation method automatically, based on the circuit and noise model.\n",
        "\n",
        "      * `\"statevector\"`: A dense statevector simulation that can sample measurement outcomes from *ideal* circuits with all measurements at the end of the circuit. For noisy simulations, each shot samples a randomly sampled noisy circuit from the noise model.\n",
        "\n",
        "      * `\"density_matrix\"`: A density matrix simulation that can sample measurement outcomes from *noisy* circuits with all measurements at the end of the circuit.\n",
        "\n",
        "      * `\"stabilizer\"`: An efficient Clifford stabilizer state simulator that can simulate noisy Clifford circuits if all errors in the noise model are also Clifford errors.\n",
        "\n",
        "      * `\"extended_stabilizer\"`: An approximate simulator for Clifford + T circuits based on decomposing the state into a ranked-stabilizer state. The number of terms grows with the number of non-Clifford (T) gates.\n",
        "\n",
        "      * `\"matrix_product_state\"`: A tensor-network statevector simulator that uses a Matrix Product State (MPS) representation for the state. This can be done with or without truncating the MPS bond dimensions, depending on the simulator options. The default behavior is no truncation.\n",
        "\n",
        "      * `\"unitary\"`: A dense unitary matrix simulation of an ideal circuit. This simulates the unitary matrix of the circuit itself, rather than the evolution of an initial quantum state. This method can only simulate gates; it does not support measurement, reset, or noise.\n",
        "\n",
        "      * `\"superop\"`: A dense superoperator matrix simulation of an ideal or noisy circuit. This simulates the superoperator matrix of the circuit itself, rather than the evolution of an initial quantum state. This method can simulate ideal and noisy gates and resets, but it does not support measurements.\n",
        "\n",
        "      * `\"tensor_network\"`: A tensor-network-based simulation that supports both statevector and density matrix. Currently this is only available for GPU and is accelerated by using cuQuantum `cuTensorNet` APIs.\n",
        "    </AccordionItem>\n",
        "  </Accordion>\n",
        "\n",
        "<Admonition type=\"note\" title=\"Notes\">\n",
        "  - You can specify all IBM Quantum Compute options in local testing mode.  However, all options except shots are ignored when run on a local simulator.\n",
        "  - It is recommended that you install Qiskit Aer before using fake backends or Aer simulators by running `pip install qiskit-aer`. The fake backends use Aer simulators under the cover if available, to take advantage of their performance.\n",
        "</Admonition>\n",
        "\n",
        "{/* If you currently use the Qiskit SDK, you can use the existing Qiskit Aer primitives for local testing.  See [exact and noisy simulation with Qiskit Aer primitives](/docs/guides/simulate-with-qiskit-aer) for details. */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "366b1216-fb2f-4d06-afd8-fe374ab6ed9a",
      "metadata": {},
      "source": [
        "## Fake backends example\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "efda5007-260a-49c0-ab6f-eac91fdbdf84",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import QuantumCircuit\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import SamplerV2 as Sampler\n",
        "from qiskit_ibm_runtime.fake_provider import FakeManilaV2\n",
        "\n",
        "# Bell Circuit\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "# Run the Sampler job locally using FakeManilaV2\n",
        "fake_manila = FakeManilaV2()\n",
        "pm = generate_preset_pass_manager(backend=fake_manila, optimization_level=1)\n",
        "isa_qc = pm.run(qc)\n",
        "\n",
        "# You can use a fixed seed to get fixed results.\n",
        "options = {\"simulator\": {\"seed_simulator\": 42}}\n",
        "sampler = Sampler(mode=fake_manila, options=options)\n",
        "\n",
        "result = sampler.run([isa_qc]).result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b51e77c0-31c9-4dfa-950c-0a9ea9247aac",
      "metadata": {},
      "source": [
        "## AerSimulator examples\n",
        "\n",
        "Example with sessions, without noise:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "63407a34-0c70-400a-bc34-f85ccd581c4d",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_aer import AerSimulator\n",
        "from qiskit.circuit import QuantumCircuit\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import Session, SamplerV2 as Sampler\n",
        "\n",
        "# Bell Circuit\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "# Run the Sampler job locally using AerSimulator.\n",
        "# Session syntax is supported but ignored because local mode doesn't support sessions.\n",
        "aer_sim = AerSimulator()\n",
        "pm = generate_preset_pass_manager(backend=aer_sim, optimization_level=1)\n",
        "isa_qc = pm.run(qc)\n",
        "with Session(backend=aer_sim) as session:\n",
        "    sampler = Sampler(mode=session)\n",
        "    result = sampler.run([isa_qc]).result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6a511de6-dc37-4ac4-87f8-bee90e3014a3",
      "metadata": {},
      "source": [
        "To simulate with noise, specify a QPU (quantum hardware) and submit it to Aer.  Aer builds a noise model based on the calibration data from that QPU, and instantiates an Aer backend with that model.  If you prefer, you can [build a noise model](/docs/guides/build-noise-models).\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  A QPU can be affected by different kinds of noise. The Qiskit Aer noise model used here only simulates some of them and therefore is likely to be less severe than the noise on a real QPU.\n",
        "\n",
        "  For details on what errors are included when initializing a noise model from a QPU, see the Aer [`NoiseModel`](https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.noise.NoiseModel.html#qiskit_aer.noise.NoiseModel.from_backend) API reference.\n",
        "</Admonition>\n",
        "\n",
        "Example with noise:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "0878eec8-9959-4e98-aff7-bf114352b838",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_aer import AerSimulator\n",
        "from qiskit.circuit import QuantumCircuit\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeService\n",
        "\n",
        "# Bell Circuit\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "\n",
        "# Specify a QPU to use for the noise model\n",
        "real_backend = service.backend(\"ibm_fez\")\n",
        "aer = AerSimulator.from_backend(real_backend)\n",
        "\n",
        "# Run the Sampler job locally using AerSimulator.\n",
        "pm = generate_preset_pass_manager(backend=aer, optimization_level=1)\n",
        "isa_qc = pm.run(qc)\n",
        "sampler = Sampler(mode=aer)\n",
        "result = sampler.run([isa_qc]).result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2a2815a4-19f9-4ebd-8e53-4e29bea4a8db",
      "metadata": {},
      "source": [
        "<span id=\"clifford-sim\" />\n",
        "\n",
        "### Clifford simulation\n",
        "\n",
        "Because Clifford circuits can be simulated efficiently with verifiable results, Clifford simulation is a very useful tool. For an in-depth example, see [Efficient simulation of stabilizer circuits with Qiskit Aer primitives](/docs/guides/simulate-stabilizer-circuits).\n",
        "\n",
        "Example:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "b9d0fdac-ba2e-4c4e-8c49-c924fb8b5c43",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "from qiskit_ibm_runtime import SamplerV2 as Sampler\n",
        "\n",
        "n_qubits = 500  # <---- note this uses 500 qubits!\n",
        "circuit = efficient_su2(n_qubits)\n",
        "circuit.measure_all()\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "params = rng.choice(\n",
        "    [0, np.pi / 2, np.pi, 3 * np.pi / 2],\n",
        "    size=circuit.num_parameters,\n",
        ")\n",
        "\n",
        "# Tell Aer to use the stabilizer (Clifford) simulation method\n",
        "aer_sim = AerSimulator(method=\"stabilizer\")\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=aer_sim, optimization_level=1)\n",
        "isa_qc = pm.run(qc)\n",
        "sampler = Sampler(mode=aer_sim)\n",
        "result = sampler.run([isa_qc]).result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ee461e4d-ee50-4430-9e83-c3b49cd7a1ef",
      "metadata": {},
      "source": [
        "## Next steps\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommendations\">\n",
        "  * Use the [`Neat` class](/docs/guides/debug-qiskit-runtime-jobs) to analyze the noise impact on an Estimator workload.\n",
        "  * Review detailed [Sampler examples](/docs/guides/sampler-examples).\n",
        "  * Review detailed [Estimator examples](/docs/guides/estimator-examples).\n",
        "  * Practice with primitives by working through the [Cost function lesson](/learning/courses/variational-algorithm-design/cost-functions) in IBM Quantum Learning.\n",
        "  * Learn how to transpile locally in the [Transpile](/docs/guides/transpile) section.\n",
        "  * Try the [Compare transpiler settings](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) tutorial.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}