{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "1fd07edc-2356-49d3-bf35-6e4e1256b61b",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Entradas e saídas do sampler\"\n",
        "description: \"Compreender os formatos de entrada e saída das primitivas do Sampler\"\n",
        "---\n",
        "\n",
        "<span id=\"sampler-inputs-and-outputs\" />\n",
        "\n",
        "# Entradas e saídas do sampler\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fcd633c9-366b-440f-8997-7c60692e5a4d",
      "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=\"Versões do pacote\">\n",
        "    O código desta página foi desenvolvido com base nos seguintes requisitos.\n",
        "    Recomendamos usar essas versões ou versões mais recentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "672f7038-64e7-42cc-9936-c30a03596791",
      "metadata": {},
      "source": [
        "Esta página apresenta uma visão geral das entradas e saídas da primitiva Sampler `qiskit-ibm-runtime` , que executa cargas de trabalho no Serviço de Computação do IBM Quantum®. O Sampler permite definir cargas de trabalho vetorizadas de maneira eficiente, utilizando uma estrutura de dados conhecida como [**Bloco Unificado Primitivo ( PUB )**](/docs/guides/primitive-input-output#pubs). Eles são utilizados como entradas para o método [`run()`](/docs/api/qiskit-ibm-runtime/sampler-v2#run) da primitiva Sampler, que executa a carga de trabalho definida como um trabalho. Em seguida, após a conclusão do trabalho, os resultados são retornados em um formato que depende tanto dos PUBs utilizados quanto das opções de execução especificadas na primitiva.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0115445a-d695-4806-8a9a-6bcd2451e418",
      "metadata": {},
      "source": [
        "<span id=\"inputs\" />\n",
        "\n",
        "## Entradas\n",
        "\n",
        "Cada arquivo `PUB` tem o seguinte formato:\n",
        "\n",
        "(`<single circuit>`, `<one or more optional parameter value>`, `<optional shots>`),\n",
        "\n",
        "Pode haver vários `parameter values` itens, e cada um deles pode ser uma matriz ou um único parâmetro, dependendo do circuito escolhido. Além disso, a entrada deve conter medidas.\n",
        "\n",
        "Para a primitiva Sampler, um `PUB` pode conter no máximo três valores:\n",
        "\n",
        "* Um único circuito `QuantumCircuit`, que pode conter um ou mais [`Parameter`](/docs/api/qiskit/qiskit.circuit.Parameter) objetos\n",
        "  *Observação: Esses circuitos também devem incluir instruções de medição para cada um dos qubits a serem amostrados.*\n",
        "* Um conjunto de valores de parâmetros para vincular o circuito a $\\theta_k$ (necessário apenas se forem utilizados `Parameter` objetos que precisem ser vinculados em tempo de execução)\n",
        "* (Opcionalmente) um número de medições para avaliar o circuito\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f2314472-55e7-4f31-824e-31b18179e18d",
      "metadata": {},
      "source": [
        "***\n",
        "\n",
        "O código a seguir mostra um exemplo de conjunto de entradas vetorizadas para a `Sampler` primitiva e as executa em um backend do tipo `IBM®` como um único `RuntimeJobV2 ` objeto.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "21687f88-51fc-4139-91b0-3fb4542716ca",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit import (\n",
        "    Parameter,\n",
        "    QuantumCircuit,\n",
        "    ClassicalRegister,\n",
        "    QuantumRegister,\n",
        ")\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.quantum_info import SparsePauliOp\n",
        "from qiskit.primitives.containers import BitArray\n",
        "\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    SamplerV2 as Sampler,\n",
        ")\n",
        "\n",
        "import numpy as np\n",
        "\n",
        "# Instantiate runtime service and get\n",
        "# the least busy backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Define a circuit with two parameters.\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.ry(Parameter(\"a\"), 0)\n",
        "circuit.rz(Parameter(\"b\"), 0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.h(0)\n",
        "circuit.measure_all()\n",
        "\n",
        "# Transpile the circuit\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "layout = transpiled_circuit.layout\n",
        "\n",
        "# Now define a sweep over parameter values, the last axis of dimension 2 is\n",
        "# for the two parameters \"a\" and \"b\"\n",
        "params = np.vstack(\n",
        "    [\n",
        "        np.linspace(-np.pi, np.pi, 100),\n",
        "        np.linspace(-4 * np.pi, 4 * np.pi, 100),\n",
        "    ]\n",
        ").T\n",
        "\n",
        "sampler_pub = (transpiled_circuit, params)\n",
        "\n",
        "# Instantiate the new Sampler object, then run the transpiled circuit\n",
        "# using the set of parameters and observables.\n",
        "sampler = Sampler(mode=backend)\n",
        "job = sampler.run([sampler_pub])\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9f1a6c43-a00c-421f-b11d-62d3237f1ccb",
      "metadata": {},
      "source": [
        "<span id=\"outputs\" />\n",
        "\n",
        "## Saídas\n",
        "\n",
        "Depois que um ou mais PUBs são enviados a uma QPU para execução e um trabalho é concluído com sucesso, os dados são retornados como um objeto [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) contêiner, acessado por meio da chamada ao `RuntimeJobV2.result()` método. O `PrimitiveResult` contém uma lista iterável de [`SamplerPubResult`](/docs/api/qiskit/qiskit.primitives.SamplerPubResult) objetos que contêm os resultados da execução de cada PUB. Esses dados são amostras da saída do circuito.\n",
        "\n",
        "Cada elemento desta lista corresponde a um objeto `PUB` enviado ao método da `run()` primitiva (por exemplo, um trabalho enviado com 20 PUBs retornará um `PrimitiveResult` objeto que contém uma lista de 20 `SamplerPubResult` objetos, um correspondendo a cada objeto `PUB`).\n",
        "\n",
        "Cada `SamplerPubResult` objeto possui um atributo `data` e um `metadata` atributo.\n",
        "\n",
        "* O `data` atributo é um campo personalizado [`DataBin`](/docs/api/qiskit/qiskit.primitives.DataBin) que contém os valores reais das medições, os desvios padrão e assim por diante. Os compartimentos de dados são objetos semelhantes a dicionários que contêm um `BitArray` por `ClassicalRegister` no circuito.\n",
        "* A `BitArray` classe é um contêiner para dados ordenados de tomadas. Ele armazena as sequências de bits amostradas como bytes dentro de uma matriz bidimensional. O eixo mais à esquerda dessa matriz abrange as imagens ordenadas, enquanto o eixo mais à direita abrange os bytes.\n",
        "* O `metadata` atributo contém informações sobre as opções de execução utilizadas (explicadas mais adiante na seção \"[Metadados do](#result-metadata) resultado\" desta página).\n",
        "\n",
        "A seguir, apresentamos um esboço visual da estrutura `PrimitiveResult` de dados:\n",
        "\n",
        "```\n",
        "    └── PrimitiveResult\n",
        "        ├── SamplerPubResult[0]\n",
        "        │   ├── metadata\n",
        "        │   └── data  ## In the form of a DataBin object\n",
        "        │       ├── NAME_OF_CLASSICAL_REGISTER\n",
        "        │       │   └── BitArray of count data (default is 'meas')\n",
        "        |       |\n",
        "        │       └── NAME_OF_ANOTHER_CLASSICAL_REGISTER\n",
        "        │           └── BitArray of count data (exists only if more than one\n",
        "        |                 ClassicalRegister was specified in the circuit)\n",
        "        ├── SamplerPubResult[1]\n",
        "        |   ├── metadata\n",
        "        |   └── data  ## In the form of a DataBin object\n",
        "        |       └── NAME_OF_CLASSICAL_REGISTER\n",
        "        |           └── BitArray of count data for second pub\n",
        "        ├── ...\n",
        "        ├── ...\n",
        "        └── ...\n",
        "```\n",
        "\n",
        "Em termos simples, uma única função retorna um [`PrimitiveResult`](/docs/api/qiskit/qiskit.primitives.PrimitiveResult) objeto e contém uma lista de um ou mais [`SamplerPubResult`](/docs/api/qiskit/qiskit.primitives.SamplerPubResult) objetos. Esses `SamplerPubResult` objetos armazenam, então, os dados de medição de cada `PUB` que foi enviado para a tarefa.\n",
        "\n",
        "Como primeiro exemplo, vamos analisar o seguinte circuito de dez qubits:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "e42b2fd8-0790-4a38-9082-f2334440e411",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Databin: DataBin(meas=BitArray(<shape=(), num_shots=4096, num_bits=10>))\n",
            "\n",
            "BitArray: BitArray(<shape=(), num_shots=4096, num_bits=10>)\n",
            "\n",
            "The shape of register `meas` is (4096, 2).\n",
            "\n",
            "The bytes in register `alpha`, shot by shot:\n",
            "[[  3 255]\n",
            " [  0   0]\n",
            " [  0   1]\n",
            " ...\n",
            " [  3   0]\n",
            " [  0   0]\n",
            " [  3 254]]\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# generate a ten-qubit GHZ circuit\n",
        "circuit = QuantumCircuit(10)\n",
        "circuit.h(0)\n",
        "circuit.cx(range(0, 9), range(1, 10))\n",
        "\n",
        "# append measurements with the `measure_all` method\n",
        "circuit.measure_all()\n",
        "\n",
        "# transpile the circuit\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "\n",
        "# run the Sampler job and retrieve the results\n",
        "sampler = Sampler(mode=backend)\n",
        "job = sampler.run([transpiled_circuit])\n",
        "result = job.result()\n",
        "\n",
        "# the data bin contains one BitArray\n",
        "data = result[0].data\n",
        "print(f\"Databin: {data}\\n\")\n",
        "\n",
        "# to access the BitArray, use the key \"meas\", which is the default name of\n",
        "# the classical register when this is added by the `measure_all` method\n",
        "array = data.meas\n",
        "print(f\"BitArray: {array}\\n\")\n",
        "print(f\"The shape of register `meas` is {data.meas.array.shape}.\\n\")\n",
        "print(f\"The bytes in register `alpha`, shot by shot:\\n{data.meas.array}\\n\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5926adf1-c7db-425a-a5cf-cb97eb5fa389",
      "metadata": {},
      "source": [
        "Às vezes, pode ser conveniente converter o formato de bytes em cadeias `BitArray` de bits. O `get_count` método retorna um dicionário que mapeia sequências de bits para o número de vezes que elas ocorreram.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "b4eb01c9-d438-46ca-9057-4e91b7656748",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Counts: {'1111111111': 1346, '0000000000': 1754, '0000000001': 55, '1000000000': 56, '1111111110': 92, '0111111111': 23, '1011111111': 15, '0001111111': 23, '1111011011': 1, '1111111101': 45, '1111111011': 108, '1111110111': 32, '0100000000': 10, '0000000111': 21, '0011111111': 21, '1111110000': 26, '1101111111': 47, '1111011111': 23, '1111111010': 6, '1100000000': 45, '1111100000': 32, '1110000000': 21, '1111101111': 13, '0010000000': 14, '0000000011': 19, '0000000101': 2, '0000001110': 2, '0000100000': 4, '0000001111': 20, '1111111100': 22, '0000010000': 5, '1101110111': 4, '1011111101': 1, '0000000010': 15, '0000001000': 12, '1111110110': 7, '1111000000': 3, '0010000001': 1, '0111011111': 3, '1001111111': 3, '1101111011': 3, '0000011111': 16, '0000011110': 3, '0001111011': 1, '1011111011': 3, '1111110011': 4, '1111101011': 2, '0000000100': 6, '1110111111': 12, '1111111000': 17, '0000111111': 5, '0001111101': 2, '1101100000': 2, '1101110001': 1, '1000001111': 2, '1111101110': 1, '1110111101': 1, '1101111101': 2, '1110000100': 1, '0100011111': 1, '1110000010': 1, '0011111110': 2, '0111111110': 1, '1111110010': 1, '0111110111': 1, '0000000110': 1, '0101111111': 1, '1101011111': 1, '1111001111': 1, '1110011111': 1, '0011111000': 2, '1101111110': 3, '1110111110': 1, '0110000000': 2, '1110000111': 1, '0000010111': 3, '0001000000': 3, '0111101111': 1, '0000011100': 1, '1000000001': 1, '1111011010': 1, '0000001010': 1, '1111100111': 2, '1111100011': 2, '0000001101': 1, '0111001111': 1, '1111111001': 1, '1101111000': 1, '0111110000': 1, '1111000111': 1, '1010000000': 1, '0011110000': 1, '1100000001': 1, '1011001101': 1, '0000001100': 1, '1100111111': 1, '1110111011': 1, '1111011101': 1, '1000011111': 1, '1101111001': 1, '0101101111': 1, '0000011011': 1, '0000111011': 1, '0111111100': 1, '1011100000': 1, '0011111011': 1, '0000010010': 1, '1001111011': 1}\n"
          ]
        }
      ],
      "source": [
        "# optionally, convert away from the native BitArray format to a dictionary format\n",
        "counts = data.meas.get_counts()\n",
        "print(f\"Counts: {counts}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e186d055-09e7-421c-8d70-0d27e7d0edaa",
      "metadata": {},
      "source": [
        "Quando um circuito contém mais de um registro clássico, os resultados são armazenados em objetos `BitArray` diferentes. O exemplo a seguir modifica o trecho anterior, dividindo o registro clássico em dois registros distintos:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "e81d87ce-2fd6-4498-a9a5-f3432209fccd",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "BitArray for register 'alpha': BitArray(<shape=(), num_shots=4096, num_bits=1>)\n",
            "BitArray for register 'beta': BitArray(<shape=(), num_shots=4096, num_bits=9>)\n"
          ]
        }
      ],
      "source": [
        "# generate a ten-qubit GHZ circuit with two classical registers\n",
        "circuit = QuantumCircuit(\n",
        "    qreg := QuantumRegister(10),\n",
        "    alpha := ClassicalRegister(1, \"alpha\"),\n",
        "    beta := ClassicalRegister(9, \"beta\"),\n",
        ")\n",
        "circuit.h(0)\n",
        "circuit.cx(range(0, 9), range(1, 10))\n",
        "\n",
        "# append measurements with the `measure_all` method\n",
        "circuit.measure([0], alpha)\n",
        "circuit.measure(range(1, 10), beta)\n",
        "\n",
        "# transpile the circuit\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "\n",
        "# run the Sampler job and retrieve the results\n",
        "sampler = Sampler(mode=backend)\n",
        "job = sampler.run([transpiled_circuit])\n",
        "result = job.result()\n",
        "\n",
        "# the data bin contains two BitArrays, one per register, and can be accessed\n",
        "# as attributes using the registers' names\n",
        "data = result[0].data\n",
        "print(f\"BitArray for register 'alpha': {data.alpha}\")\n",
        "print(f\"BitArray for register 'beta': {data.beta}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d93dd9f5-cc43-41b0-b350-f545a14d1f38",
      "metadata": {},
      "source": [
        "<span id=\"use-bitarray-objects-for-performant-post-processing\" />\n",
        "\n",
        "### Use `BitArray` objetos para um pós-processamento eficiente\n",
        "\n",
        "Como as matrizes geralmente oferecem melhor desempenho em comparação com os dicionários, é recomendável realizar qualquer pós-processamento diretamente nos `BitArray` objetos, em vez de nos dicionários de contagens. A `BitArray` classe oferece uma variedade de métodos para realizar algumas operações comuns de pós-processamento:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "6465d11b-9e5b-4078-a1be-75229297093a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The shape of register `alpha` is (4096, 1).\n",
            "The bytes in register `alpha`, shot by shot:\n",
            "[[0]\n",
            " [0]\n",
            " [0]\n",
            " ...\n",
            " [1]\n",
            " [0]\n",
            " [1]]\n",
            "\n",
            "The shape of register `beta` is (4096, 2).\n",
            "The bytes in register `beta`, shot by shot:\n",
            "[[  0   0]\n",
            " [  0   0]\n",
            " [  1 255]\n",
            " ...\n",
            " [  1 255]\n",
            " [  0   0]\n",
            " [  1 255]]\n",
            "\n",
            "The shape of `beta` after post-selection is (0, 2).\n",
            "The bytes in `beta` after post-selection:\n",
            "[]\n",
            "The shape of `beta` after bit-wise slicing is (4096, 1).\n",
            "The bytes in `beta` after bit-wise slicing:\n",
            "[[0]\n",
            " [0]\n",
            " [7]\n",
            " ...\n",
            " [7]\n",
            " [0]\n",
            " [7]]\n",
            "\n",
            "The shape of `beta` after shot-wise slicing is (5, 2).\n",
            "The bytes in `beta` after shot-wise slicing:\n",
            "[[  0   0]\n",
            " [  0   0]\n",
            " [  1 255]\n",
            " [  0   0]\n",
            " [  1 255]]\n",
            "\n",
            "Exp. val. for observable `SparsePauliOp(['ZZZZZZZZZ'],\n",
            "              coeffs=[1.+0.j])` is: 0.115234375\n",
            "Exp. val. for observable `SparsePauliOp(['IIIIIIIIZ'],\n",
            "              coeffs=[1.+0.j])` is: 0.02392578125\n",
            "\n",
            "The shape of the merged results is (4096, 2).\n",
            "The bytes of the merged results:\n",
            "[[  0   0]\n",
            " [  0   0]\n",
            " [  3 254]\n",
            " ...\n",
            " [  3 255]\n",
            " [  0   0]\n",
            " [  3 255]]\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(f\"The shape of register `alpha` is {data.alpha.array.shape}.\")\n",
        "print(f\"The bytes in register `alpha`, shot by shot:\\n{data.alpha.array}\\n\")\n",
        "\n",
        "print(f\"The shape of register `beta` is {data.beta.array.shape}.\")\n",
        "print(f\"The bytes in register `beta`, shot by shot:\\n{data.beta.array}\\n\")\n",
        "\n",
        "# post-select the bitstrings of `beta` based on having sampled \"1\" in `alpha`\n",
        "mask = data.alpha.array == \"0b1\"\n",
        "ps_beta = data.beta[mask[:, 0]]\n",
        "print(f\"The shape of `beta` after post-selection is {ps_beta.array.shape}.\")\n",
        "print(f\"The bytes in `beta` after post-selection:\\n{ps_beta.array}\")\n",
        "\n",
        "# get a slice of `beta` to retrieve the first three bits\n",
        "beta_sl_bits = data.beta.slice_bits([0, 1, 2])\n",
        "print(\n",
        "    f\"The shape of `beta` after bit-wise slicing is {beta_sl_bits.array.shape}.\"\n",
        ")\n",
        "print(f\"The bytes in `beta` after bit-wise slicing:\\n{beta_sl_bits.array}\\n\")\n",
        "\n",
        "# get a slice of `beta` to retrieve the bytes of the first five shots\n",
        "beta_sl_shots = data.beta.slice_shots([0, 1, 2, 3, 4])\n",
        "print(\n",
        "    f\"The shape of `beta` after shot-wise slicing is {beta_sl_shots.array.shape}.\"\n",
        ")\n",
        "print(\n",
        "    f\"The bytes in `beta` after shot-wise slicing:\\n{beta_sl_shots.array}\\n\"\n",
        ")\n",
        "\n",
        "# calculate the expectation value of diagonal operators on `beta`\n",
        "ops = [SparsePauliOp(\"ZZZZZZZZZ\"), SparsePauliOp(\"IIIIIIIIZ\")]\n",
        "exp_vals = data.beta.expectation_values(ops)\n",
        "for o, e in zip(ops, exp_vals):\n",
        "    print(f\"Exp. val. for observable `{o}` is: {e}\")\n",
        "\n",
        "# concatenate the bitstrings in `alpha` and `beta` to \"merge\" the results of the two\n",
        "# registers\n",
        "merged_results = BitArray.concatenate_bits([data.alpha, data.beta])\n",
        "print(f\"\\nThe shape of the merged results is {merged_results.array.shape}.\")\n",
        "print(f\"The bytes of the merged results:\\n{merged_results.array}\\n\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b3765ba4-ffaa-4f51-a657-1fdfb588b849",
      "metadata": {},
      "source": [
        "<span id=\"result-metadata\" />\n",
        "\n",
        "## Metadados do resultado\n",
        "\n",
        "Além dos resultados da execução, tanto o objeto `PrimitiveResult` quanto `SamplerPubResult` o objeto contêm um atributo de metadados sobre o trabalho que foi enviado. Os metadados que contêm informações sobre todos os PUBs enviados (como as diversas [opções de tempo de execução](/docs/api/qiskit-ibm-runtime/options) disponíveis) podem ser encontrados no `PrimitiveResult.metatada`, enquanto os metadados específicos de cada PUB se encontram no `SamplerPubResult.metadata`.\n",
        "\n",
        "Os metadados do resultado do Sampler também incluem informações sobre o tempo de execução, conhecidas como [*“execution span*](#execution-spans) ”.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  No campo de metadados, as implementações de primitivas podem retornar qualquer informação sobre a execução que seja relevante para elas, e não há pares chave-valor garantidos pela primitiva base. Portanto, os metadados retornados podem variar de acordo com as diferentes implementações das primitivas.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "9a40d177-917b-484a-a809-44554efcee28",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The metadata of the PrimitiveResult is:\n",
            "'execution' : {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-08-01 08:21:10', stop='2026-08-01 08:21:13', size=4096>)])},\n",
            "'version' : 2,\n",
            "\n",
            "The metadata of the PubResult result is:\n",
            "'circuit_metadata' : {},\n"
          ]
        }
      ],
      "source": [
        "# Print out the results metadata\n",
        "print(\"The metadata of the PrimitiveResult is:\")\n",
        "for key, val in result.metadata.items():\n",
        "    print(f\"'{key}' : {val},\")\n",
        "\n",
        "print(\"\\nThe metadata of the PubResult result is:\")\n",
        "for key, val in result[0].metadata.items():\n",
        "    print(f\"'{key}' : {val},\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "403dd006-33ec-4bd6-ad45-857535857077",
      "metadata": {},
      "source": [
        "<span id=\"execution-spans\" />\n",
        "\n",
        "<span id=\"view-execution-spans\" />\n",
        "\n",
        "### Exibir intervalos de execução\n",
        "\n",
        "Os resultados das tarefas [`SamplerV2`](/docs/api/qiskit-ibm-runtime/sampler-v2) executadas no Serviço de Computação do IBM Quantum contêm informações sobre o tempo de execução em seus metadados.\n",
        "Essas informações de tempo podem ser usadas para definir limites superior e inferior de data e hora em que determinadas instruções foram executadas na QPU.\n",
        "As tomadas são agrupadas em [`ExecutionSpan`](/docs/api/qiskit-ibm-runtime/execution-span-execution-span) objetos, cada um dos quais indica uma hora de início, uma hora de término e uma especificação das tomadas coletadas nesse intervalo.\n",
        "\n",
        "Um intervalo de execução especifica quais dados foram executados durante sua janela, por meio de um [`ExecutionSpan.mask`](/docs/api/qiskit-ibm-runtime/execution-span-execution-span#mask) método. Este método, recebendo como argumento um índice [de Bloco Unificado Primitivo ( PUB )](/docs/guides/primitive-input-output#pubs), retorna uma máscara booleana que é `True` verdadeira para todas as tomadas executadas durante sua janela. Os PUBs são indexados pela ordem em que foram passados à chamada de execução do Sampler. Se, por exemplo, uma máscara de imagem ( PUB ) tiver a forma `(2, 3)` e for executada com quatro fotos, então a forma da máscara é `(2, 3, 4)`. Consulte a página da API [`execution\\_span`](/docs/api/qiskit-ibm-runtime/execution-span) para obter todos os detalhes.\n",
        "\n",
        "Para visualizar as informações sobre o intervalo de execução, consulte os metadados do resultado retornado por `SamplerV2`, que é apresentado na forma de um `ExecutionSpans` objeto. Este objeto é um contêiner semelhante a uma lista que contém instâncias de subclasses de `ExecutionSpan`, como `SliceSpan`.\n",
        "\n",
        "Exemplo:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "480e553c-2e53-40ca-bafd-e350f173cbcc",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "ExecutionSpans([DoubleSliceSpan(<start='2026-08-01 08:21:37', stop='2026-08-01 08:21:38', size=24>)])\n"
          ]
        }
      ],
      "source": [
        "# Define two circuits, each with one parameter with two parameters.\n",
        "circuit = QuantumCircuit(2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.ry(Parameter(\"a\"), 0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.h(0)\n",
        "circuit.measure_all()\n",
        "\n",
        "\n",
        "pm = generate_preset_pass_manager(optimization_level=1, backend=backend)\n",
        "transpiled_circuit = pm.run(circuit)\n",
        "\n",
        "params = np.random.uniform(size=(2, 3)).T\n",
        "\n",
        "sampler_pub = (transpiled_circuit, params)\n",
        "\n",
        "# Instantiate the new Estimator object, then run the transpiled circuit\n",
        "# using the set of parameters and observables.\n",
        "\n",
        "job = sampler.run([sampler_pub], shots=4)\n",
        "\n",
        "result = job.result()\n",
        "spans = job.result().metadata[\"execution\"][\"execution_spans\"]\n",
        "print(spans)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "092fedcc-c4ac-4841-9846-f77b9ec90d2e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.primitives import BitArray\n",
        "\n",
        "# Get the mask of the 1st PUB for the 0th span.\n",
        "mask = spans[0].mask(0)\n",
        "\n",
        "# Decide whether the 0th shot of parameter set (1, 2) occurred in this span.\n",
        "in_this_span = mask[2, 1, 0]\n",
        "\n",
        "# Create a new bit array containing only the PUB-1 data collected during this span.\n",
        "bits = result[0].data.meas\n",
        "filtered_data = BitArray(bits.array[mask], bits.num_bits)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2ba13f59-c804-4e3b-85c9-90f26cb68e92",
      "metadata": {},
      "source": [
        "Os intervalos de execução podem ser filtrados para incluir informações relativas a PUBs específicas, selecionadas por seus índices:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "53dec6a3-57b9-41b0-8ebd-28c6257dd10e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "ExecutionSpans([DoubleSliceSpan(<start='2026-08-01 08:21:37', stop='2026-08-01 08:21:38', size=24>)])"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# take the subset of spans that reference data in PUBs 0 or 2\n",
        "spans.filter_by_pub([0, 2])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4f635472-60a9-4729-9880-5581fb3806f2",
      "metadata": {},
      "source": [
        "Exibir informações gerais sobre o conjunto de intervalos de execução:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "ba4aa14d-4182-47bf-93a6-df607fd82594",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Number of execution spans: 1\n",
            "  Start of the first span: 2026-08-01 08:21:37.606114\n",
            "     End of the last span: 2026-08-01 08:21:38.960352\n",
            "       Total duration (s): 1.354238\n"
          ]
        }
      ],
      "source": [
        "print(\"Number of execution spans:\", len(spans))\n",
        "print(\"  Start of the first span:\", spans.start)\n",
        "print(\"     End of the last span:\", spans.stop)\n",
        "print(\"       Total duration (s):\", spans.duration)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1392fbc0-0792-402c-9568-160313ab76c4",
      "metadata": {},
      "source": [
        "Extrair e inspecionar um intervalo específico:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "077a74ad-2780-4c61-8310-a4821efbfa68",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " Start of first span: 2026-08-01 08:21:37.606114\n",
            "   End of first span: 2026-08-01 08:21:38.960352\n",
            "#shots in first span: 24\n"
          ]
        }
      ],
      "source": [
        "spans.sort()\n",
        "print(\" Start of first span:\", spans[0].start)\n",
        "print(\"   End of first span:\", spans[0].stop)\n",
        "print(\"#shots in first span:\", spans[0].size)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "924e26ed-ece0-42ef-a985-ae1aaea86622",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  É possível que os intervalos de tempo especificados por intervalos de execução distintos se sobreponham. Isso não se deve ao fato de uma QPU estar realizando várias execuções ao mesmo tempo, mas sim a um efeito secundário de certos processos clássicos que podem ocorrer simultaneamente à execução quântica. A garantia oferecida é de que os dados referenciados ocorreram efetivamente no intervalo de execução relatado, mas não necessariamente de que os limites da janela de tempo sejam os mais restritos possíveis.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "celltoolbar": "Raw Cell Format",
    "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
}