{ "cells": [ { "cell_type": "markdown", "id": "b7d5a67e-f8bd-4531-9469-a6202fec3770", "metadata": {}, "source": [ "# Architecture-dependent physical costs\n", "\n", "While Qualtran provides tooling for expressing and reasoning about quantum algorithms, a\n", "particularly compelling use case for such a software tool is to provide estimates of resource\n", "requirements for quantum algorithms that could be executed on a future quantum computer. In\n", "particular, we’re interested in resource estimates compatible with the hardware roadmaps of quantum\n", "hardware providers. \n", "\n", "A complete quantum computing system will be built with layers of abstraction\n", "Algorithms expressed as Qualtran bloqs are encoded at the\n", "architecture-agnostic level \"application\" and \"logical\" levels of abstraction. We anticipate that\n", "future tools or interoperability software will consume the output of a full decomposition of a\n", "Qualtran program and explicitly compile it to a specific error-corrected architecture or platform.\n", "\n", "In lieu of the existence of such tools, we provide access to common literature models for converting\n", "\"logical costs\" to \"physical costs\". We define these terms: logical costs are hardware\n", "architecture-agnostic properties of an algorithm that we desire to minimize. Common logical costs\n", "are the number of (logical) qubits or the number of (logical) gates. Physical costs are those that\n", "matter in the physical world, such as the number of physical qubits (e.g. individual transmons or\n", "trapped ions) and the wall-clock time required to physically execute an algorithm." ] }, { "cell_type": "markdown", "id": "24e10c34-ef6c-48c9-a25f-953d6560a93f", "metadata": {}, "source": [ "## `PhysicalCostModel`\n", "\n", "We contain all the components for doing an estimation of physical costs within the\n", "`qualtran.surface_code.PhysicalCostModel` class.\n", "The model is parameterized by 1) properties of the target hardware architecture and 2) Execution protocol design choices.\n", "We further factor the design choices into a) the data block design for storing\n", "algorithm qubits, b) the magic state factory construction, and c) the error suppression\n", "ability of the code. In total, the model is composed of\n", "\n", " - `physical_params: PhysicalParameters`\n", " - `data_block: DataBlock`\n", " - `factory: MagicStateFactory`\n", " - `qec_scheme: QECScheme`\n", "\n", "Each method for computing physical costs take algorithmcounts inputs: the number of\n", "algorithm qubits and the number of algorithm gates. Output quantities\n", "include the wall-clock time, the number of physical qubits, and the probability of failure\n", "due to the physical realization of the algorithm." ] }, { "cell_type": "code", "execution_count": 1, "id": "89e99ea2-2359-4ea8-8c51-da617e40c746", "metadata": {}, "outputs": [], "source": [ "from qualtran.surface_code import AlgorithmSummary\n", "from qualtran.resource_counting import GateCounts\n", "\n", "# Set up some example parameters\n", "alg = AlgorithmSummary(\n", " n_algo_qubits=100,\n", " n_logical_gates=GateCounts(toffoli=1e8),\n", ")" ] }, { "cell_type": "code", "execution_count": 2, "id": "111b15b8-3b22-4af5-b9b9-e1c558de744a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Duration 4.74 hr \n", "Physical Qubits 335,404 \n", "Error 0.031\n" ] } ], "source": [ "from qualtran.surface_code import PhysicalCostModel\n", "\n", "# For minimal configuration, you can use a set of defaults from\n", "# the literature. Here: Gidney and Fowler (2018).\n", "cost_model = PhysicalCostModel.make_gidney_fowler(data_d=25)\n", "\n", "print(\n", " f'Duration {cost_model.duration_hr(alg):.2f} hr',\n", " f'\\nPhysical Qubits {cost_model.n_phys_qubits(alg):,d}',\n", " f'\\nError {cost_model.error(alg):.2g}'\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "id": "dc41868c-20d4-4d7a-b5b0-010f5f11d294", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Duration 2.50 hr \n", "Physical Qubits 188,646 \n", "Error 8.1e+03\n" ] } ], "source": [ "# Compare with the defaults based on another set of literature-based defaults\n", "cost_model_2 = PhysicalCostModel.make_beverland_et_al(data_d=25)\n", "\n", "print(\n", " f'Duration {cost_model_2.duration_hr(alg):.2f} hr',\n", " f'\\nPhysical Qubits {cost_model_2.n_phys_qubits(alg):,d}',\n", " f'\\nError {cost_model_2.error(alg):.2g}'\n", ")" ] }, { "cell_type": "markdown", "id": "979618b3-1a16-4ede-86fe-bd702466c0d4", "metadata": {}, "source": [ "## `DataBlock`\n", "\n", "The `DataBlock` interface prescribes methods for modeling the costs of the data block of a surface code compilation.\n", "\n", "The number of algorithm qubits is reported by Qualtran as a logical cost of a bloq. The\n", "surface code is a rate-1 code, so each bit of data needs at least one surface code tile. Due\n", "to locality constraints imposed by the 2D surface code combined with the need to interact\n", "qubits that aren’t necessarily local, additional tiles are needed to actually execute a program.\n", "\n", "Each data block is responsible for reporting the number of tiles required to store a certain\n", "number of algorithm qubits; as well as the number of time steps required to consume a magic\n", "state. Different data blocks exist in the literature, and data block provides a different\n", "space-time tradeoff.\n", "\n", "The space occupied by the data block is to be contrasted with the space used for magic\n", "state distillation." ] }, { "cell_type": "code", "execution_count": 4, "id": "27ac134b-771f-4f2d-827e-7298fd06417f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "86700" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qualtran.surface_code import SimpleDataBlock, FastDataBlock\n", "\n", "simple_data_block = SimpleDataBlock(\n", " data_d=17,\n", " routing_overhead=0.5\n", ")\n", "simple_data_block.n_physical_qubits(n_algo_qubits=100)" ] }, { "cell_type": "code", "execution_count": 5, "id": "c66b42dc-edd9-4036-a12a-9c71e0312d2e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "132940" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fast_data_block = FastDataBlock(data_d=17)\n", "fast_data_block.n_physical_qubits(n_algo_qubits=100)" ] }, { "cell_type": "markdown", "id": "a7515d8f-99fa-40f8-89af-f3ce498a99dc", "metadata": {}, "source": [ "## `MagicStateFactory`\n", "\n", "The `MagicStateFactory` interface prescribes methods for modeling the costs of the magic state factories of a surface code compilation.\n", "\n", "An important consideration for a surface code compilation is how to execute arbitrary gates\n", "to run the desired algorithm. The surface code can execute Clifford gates in a fault-tolerant\n", "manner. Non-Clifford gates like the T gate, Toffoli or CCZ gate, or non-Clifford rotation\n", "gates require more expensive gadgets to implement. Executing a T or CCZ gate requires first\n", "using the technique of state distillation in an area of the computation called a \"magic state\n", "factory\" to distill a noisy T or CCZ state into a \"magic state\" of sufficiently low error.\n", "Such quantum states can be used to enact the non-Clifford quantum gate through gate\n", "teleportation.\n", "\n", "Magic state production is thought to be an important runtime and qubit-count bottleneck in\n", "foreseeable fault-tolerant quantum computers.\n", "\n", "This abstract interface specifies that each magic state factory must report its required\n", "number of physical qubits, the number of error correction cycles to produce enough magic\n", "states to enact a given number of logical gates and an error model, and the expected error\n", "associated with generating those magic states." ] }, { "cell_type": "code", "execution_count": 6, "id": "e79e04c5-5199-48d2-910e-419174cdce71", "metadata": {}, "outputs": [], "source": [ "from qualtran.surface_code import LogicalErrorModel, QECScheme\n", "err_model = LogicalErrorModel(qec_scheme=QECScheme.make_gidney_fowler(), physical_error=1e-3)" ] }, { "cell_type": "code", "execution_count": 7, "id": "19cd3152-4a4c-45f9-a0d5-fc2361827ba8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "170500000000" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qualtran.resource_counting import GateCounts\n", "from qualtran.surface_code import CCZ2TFactory, FifteenToOne\n", "\n", "gate_counts = GateCounts(toffoli=1e9)\n", "ccz_factory = CCZ2TFactory(distillation_l1_d=15, distillation_l2_d=31)\n", "ccz_factory.n_cycles(gate_counts, logical_error_model=err_model)" ] }, { "cell_type": "markdown", "id": "30f4b175-e4e6-4478-bd63-ecf269acf425", "metadata": {}, "source": [ "## `QECScheme`\n", "\n", "Error correcting codes suppress error but do not eliminate it. The construction of the\n", "surface code takes a parameter $d$ that scales the amount of error suppression by using more\n", "physical qubits per tile. The exact relationship between $d$ and the resulting logical\n", "error rate will likely be experimentally determined when sufficiently large quantum\n", "computers are available, but in the interim we can model the relationship with an\n", "equation of the form\n", "\\begin{equation} \\label{eq:logical_error_rate}\n", "p_l(d) = A \\left(\\frac{p_p}{p^*}\\right)^\\frac{d + 1}{2}\n", "\\end{equation}\n", "relating the logical error rate $p_l$ to the physical error rate $p_p$\n", "for a code distance $d$. The coefficients $A$ and $p^*$ can be fit to\n", "numerical simulations of a surface code, but common resource estimates in the\n", "literature use back of the envelope values. $p^*$ is sometimes identified with\n", "the error threshold of the surface code. Sometimes $p^*/p_p = \\Lambda$ is treated as the fit\n", "parameter.\n", "\n", "In Qualtran, we provide presets for Fowler parameters $A=0.1$, $p^*=0.01$ and\n", "Beverland parameters $A=0.03$, $p^*=0.01$.\n" ] }, { "cell_type": "code", "execution_count": 8, "id": "f012a1b9-8ad2-40f4-96b1-9fd1d7c1ef36", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Gidney Fowler QECScheme(error_rate_scaler=0.1, error_rate_threshold=0.01)\n", "Beverland et al. QECScheme(error_rate_scaler=0.03, error_rate_threshold=0.01)\n" ] } ], "source": [ "print(\"Gidney Fowler \", QECScheme.make_gidney_fowler())\n", "print(\"Beverland et al. \", QECScheme.make_beverland_et_al())" ] }, { "cell_type": "markdown", "id": "47ac0d49-21f8-4c1e-9b67-87d4c4fb70ff", "metadata": {}, "source": [ "## `PhysicalParameters`\n", "\n", "The physical parameters of the device include the physical error rate and the cycle time." ] }, { "cell_type": "code", "execution_count": 9, "id": "5b782138-f1fa-4525-aecb-ec8782cfd552", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Beverland el. al. PhysicalParameters(physical_error=0.001, cycle_time_us=0.4)\n", "Gidney Fowler PhysicalParameters(physical_error=0.001, cycle_time_us=1.0)\n" ] } ], "source": [ "from qualtran.surface_code import PhysicalParameters\n", "\n", "print('Beverland el. al.', PhysicalParameters.make_beverland_et_al())\n", "print('Gidney Fowler ', PhysicalParameters.make_gidney_fowler())" ] }, { "cell_type": "markdown", "id": "a5a938fb-76ef-4ad7-9cd8-4039beffbff5", "metadata": {}, "source": [ "## Modeling details\n", "\n", "### Time costs\n", "\n", "The amount of time to run an algorithm is modeled as the greater of two quantities:\n", "The number of cycles required to generate enough magic states (via the `factory`), and\n", "the number of cycles required to consume the magic states (via the `data_block`). The model\n", "assumes that the rate of magic state generation is slower than the reaction limit. Each\n", "cycle takes a fixed amount of wall-clock time, given by the physical parameters." ] }, { "cell_type": "markdown", "id": "350b235d-fe6b-4ca6-b770-a5e3c7e955bd", "metadata": {}, "source": [ "### Space costs\n", "\n", "The number of physical qubits is the sum of the number of factory qubits and data block qubits." ] }, { "cell_type": "markdown", "id": "ab026bae-a2d2-4a92-9fd3-a2f667ecbe19", "metadata": {}, "source": [ "### Error\n", "\n", "We assume the constituent error probabilities are sufficiently low to permit a first-order\n", "approximation for combining sources of error. The total error is the sum of error probabilities\n", "due to magic state production (via `factory`) and data errors (via `data_block`). Note that\n", "the total error in data storage depends on the number of cycles, which depends on the\n", "factory design." ] }, { "cell_type": "markdown", "id": "f552589f-697d-4ed5-8667-b2bc00dcddc5", "metadata": {}, "source": [ "## Mixing and Matching\n", "\n", "In this section of the notebook, we show how the various components can be interchanged to explore the variety of the modelling space -- even when just using the default parameters and a fixed code distance $d$. Additional variety can be found by adjusting the design parameters." ] }, { "cell_type": "code", "execution_count": 10, "id": "f5c17f8e-3762-45b5-a02e-b42bc9acdb3b", "metadata": {}, "outputs": [], "source": [ "from qualtran.surface_code import SimpleDataBlock, CompactDataBlock, FastDataBlock\n", "\n", "data_d = 25\n", "data_blocks = [\n", " SimpleDataBlock(data_d=data_d),\n", " CompactDataBlock(data_d=data_d),\n", " FastDataBlock(data_d=data_d),\n", "]\n", "\n", "from qualtran.surface_code import CCZ2TFactory, FifteenToOne\n", "factories = [\n", " CCZ2TFactory(),\n", " FifteenToOne(data_d, data_d, data_d),\n", "]\n", "\n", "schemes = [\n", " QECScheme.make_gidney_fowler(),\n", " QECScheme.make_beverland_et_al(),\n", "]\n", "\n", "phys_params = [\n", " PhysicalParameters.make_beverland_et_al(),\n", " PhysicalParameters.make_beverland_et_al(optimistic_err_rate=True),\n", " PhysicalParameters.make_gidney_fowler(),\n", " PhysicalParameters.make_gidney_fowler(optimistic_err_rate=True),\n", "]" ] }, { "cell_type": "code", "execution_count": 11, "id": "453ba8ae-7507-4e8f-a86d-780e56a40a81", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHWCAYAAAD6oMSKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAANKRJREFUeJzt3Xl0VFW+/v+nkpABklTClBDJpCAiEFABBRsQARG9BPSqoDSCdqMCNoo40QqCqAG7BfSConQLCjL0bQGRptFmCJOgTBGuDAIGCLNKTBGGQJL9+8Mf9TWQhKpQlao6eb/WqrWoc/Y59Sk2O3k4wz42Y4wRAAAAAl6QrwsAAACAZxDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwiBBfF+BtxcXFOnz4sKKiomSz2XxdDgAAgFuMMTp58qQSEhIUFFT+MTnLB7vDhw8rMTHR12UAAABckZycHNWvX7/cNpYPdlFRUZJ+/cuIjo72cTUAAADucTgcSkxMdGaa8lg+2F04/RodHU2wAwAAAcuVS8q4eQIAAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWYflHilWG/LOFGjp3iw7knlFSbIQm9LpBkeH81QLedq6wWDPW7dP+E6eVXLO6+rZJUWgI/18FUHXZjDHG10V4k8PhkN1uV15enleeFZs+abW2HnRcsjytfrQWPtnO458H4FcZi7dr6upsFf/mJ1iQTRrQLlXD77red4UBgIe5k2X4r+0VKCvUSdLWgw6lT1pdyRUBVUPG4u16f1XJUCdJxUZ6f1W2MhZv901hAOBjBLsKyj9bWGaou2DrQYfyzxZWUkVA1XCusFhTV2eX22bq6mydKyyupIoAwH8Q7Cpo6NwtHm0HwDUz1u275EjdxYrNr+0AoKoh2FXQgdwzHm0HwDX7T5z2aDsAsBKCXQUlxUZ4tB0A1yTXrO7RdgBgJQS7ChrTo5lH2wFwTa9WSR5tBwBWQrCroBGfbfNoOwCumbvhgEfbAYCVEOwqiGvsAN/gGjsAKBvBroK4xg7wDa6xA4CyEewqaEKvGzzaDoBr+rZJUZCt/DZBtl/bAUBVQ7CroMjwEKXVL/+xHmn1o3lmLOBhoSFBGtAutdw2A9ql8sxYAFUSP/muwMIn25UZ7nhWLOA9w++6Xo+3T73kyF2QTXq8Pc+KBVB12Ywxl5nDPbC58+Dciso/W6ihc7foQO4ZJcVGaEKvGzhSB1SCc4XFmrFun/afOK3kmtXVt00KR+oAWI47WYZgBwAA4MfcyTL81xYAAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBE+DXarVq1S9+7dlZCQIJvNpgULFlzSZseOHUpPT5fdbleNGjXUqlUrHThwoPKLBQAA8HM+DXanTp1S8+bNNXny5FLX7927V7/73e903XXXKTMzU1u3btWIESMUHh5eyZUCAAD4P7+ZoNhms2n+/Pnq2bOnc1nv3r1VrVo1zZgxo8L7ZYJiAAAQyCwxQXFxcbH+9a9/6dprr1XXrl1Vt25d3XzzzaWerv2tgoICORyOEi8AAICqwG+D3fHjx5Wfn6+xY8fqzjvv1Jdffql77rlH9957r1auXFnmdhkZGbLb7c5XYmJiJVYNAADgO357Kvbw4cO66qqr9OCDD2rWrFnOdunp6apRo4Zmz55d6n4KCgpUUFDgfO9wOJSYmMipWAAAEJDcORUbUkk1ua127doKCQnR9ddfX2J548aNtWbNmjK3CwsLU1hYmLfLAwAA8Dt+eyo2NDRUrVq10q5du0os//7775WcnOyjqgAAAPyXT4/Y5efna8+ePc732dnZysrKUs2aNZWUlKTnnntOvXr1Uvv27dWxY0ctWbJEn3/+uTIzM31XNAAAgJ/y6TV2mZmZ6tix4yXL+/Xrp+nTp0uSPvzwQ2VkZOjgwYNq1KiRRo8erR49erj8GUx3AgAAApk7WcZvbp7wFoIdAAAIZJaYxw4AAADuIdgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEX4NNitWrVK3bt3V0JCgmw2mxYsWFBm2yeeeEI2m00TJ06stPoAAAACiU+D3alTp9S8eXNNnjy53Hbz58/X+vXrlZCQUEmVAQAABJ4QX354t27d1K1bt3LbHDp0SH/605/0xRdf6O67766kygAAAAKPX19jV1xcrL59++q5555TkyZNfF0OAACAX/PpEbvLGTdunEJCQjRkyBCXtykoKFBBQYHzvcPh8EZpAAAAfsdvj9ht2rRJb7/9tqZPny6bzebydhkZGbLb7c5XYmKiF6sEAADwH34b7FavXq3jx48rKSlJISEhCgkJ0f79+zVs2DClpKSUud3w4cOVl5fnfOXk5FRe0QAAAD7kt6di+/btq86dO5dY1rVrV/Xt21ePPPJImduFhYUpLCzM2+UBAAD4HZ8Gu/z8fO3Zs8f5Pjs7W1lZWapZs6aSkpJUq1atEu2rVaum+Ph4NWrUqLJLBQAA8Hs+DXYbN25Ux44dne+feeYZSVK/fv00ffp0H1UFAAAQmHwa7G677TYZY1xuv2/fPu8VAwAAEOD89uYJAAAAuIdgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCJ8Gu1WrVql79+5KSEiQzWbTggULnOvOnz+vF154Qc2aNVONGjWUkJCghx9+WIcPH/ZdwQAAAH7Mp8Hu1KlTat68uSZPnnzJutOnT2vz5s0aMWKENm/erHnz5mnXrl1KT0/3QaUAAAD+z2aMMb4uQpJsNpvmz5+vnj17ltlmw4YNat26tfbv36+kpCSX9utwOGS325WXl6fo6GgPVQsAAFA53MkyIZVUk0fk5eXJZrMpJiamzDYFBQUqKChwvnc4HJVQGQAAgO8FzM0TZ8+e1QsvvKAHH3yw3LSakZEhu93ufCUmJlZilQAAAL4TEMHu/PnzeuCBB2SM0XvvvVdu2+HDhysvL8/5ysnJqaQqAQAAfMvvT8VeCHX79+/X8uXLL3tuOSwsTGFhYZVUHQAAgP/w62B3IdTt3r1bK1asUK1atXxdEgAAgN/yabDLz8/Xnj17nO+zs7OVlZWlmjVrql69errvvvu0efNmLVq0SEVFRTp69KgkqWbNmgoNDfVV2QAAAH7Jp9OdZGZmqmPHjpcs79evn0aNGqXU1NRSt1uxYoVuu+02lz6D6U4AAEAgC5jpTm677TaVlyv9ZIo9AACAgBAQd8UCAADg8gh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLcCvYFRYW6uOPP9axY8e8VQ8AAAAqyK1gFxISoieeeEJnz571Vj0AAACoILdPxbZu3VpZWVleKAUAAABXIsTdDQYNGqRnnnlGOTk5uummm1SjRo0S69PS0jxWHAAAAFxnM8YYdzYICrr0IJ/NZpMxRjabTUVFRR4rzhMcDofsdrvy8vIUHR3t63IAAADc4k6WcfuIXXZ2doULAwAAgPe4HeySk5O9UQcAAACukNvBTpJ2796tFStW6Pjx4youLi6xbuTIkR4pDAAAAO5xO9hNnTpVAwcOVO3atRUfHy+bzeZcZ7PZCHYAAAA+4nawe+211/T666/rhRde8EY9AAAAqCC357HLzc3V/fff741aAAAAcAXcDnb333+/vvzyS2/UAgAAgCvg0qnYd955x/nnBg0aaMSIEVq/fr2aNWumatWqlWg7ZMgQz1YIAAAAl7g0QXFqaqprO7PZ9MMPP1xxUZ7EBMUAACCQeXyCYiYlBgAA8H9uX2MHAAAA/0SwAwAAsAiCHQAAgEUQ7AAAACzC5WD34Ycf6qeffvJmLQAAALgCLge7mTNnqn79+mrbtq3GjRunHTt2eLMuAAAAuMnlYLd8+XIdOXJEgwYN0qZNm3TzzTerYcOGGjZsmFatWqXi4mJv1gkAAIDLcGmC4tKcO3dOy5cv18KFC/X555/rzJkzuuuuu5Senq5u3bqpRo0anq61QpigGAAABDJ3skyFb54IDQ3VnXfeqXfffVc5OTlasmSJUlJSNGbMGI0fP96lfaxatUrdu3dXQkKCbDabFixYUGK9MUYjR45UvXr1FBERoc6dO2v37t0VLRkAAMDSPHZXbMuWLfXqq6/q22+/1YsvvujSNqdOnVLz5s01efLkUte/+eabeueddzRlyhR9/fXXqlGjhrp27aqzZ896qmwAAADLcOmRYu6qVq2aS+26deumbt26lbrOGKOJEyfq5ZdfVo8ePSRJH3/8seLi4rRgwQL17t3bY/UCAABYgd/OY5edna2jR4+qc+fOzmV2u10333yz1q1b58PKAAAA/JNXjth5wtGjRyVJcXFxJZbHxcU515WmoKBABQUFzvcOh8M7BQIAAPgZvz1iV1EZGRmy2+3OV2Jioq9LAgAAqBQVOmL3yy+/6JtvvtHx48cvmb/u4Ycf9khh8fHxkqRjx46pXr16zuXHjh1TixYtytxu+PDheuaZZ5zvHQ4H4Q4AAFQJbge7zz//XH369FF+fr6io6Nls9mc62w2m8eCXWpqquLj47Vs2TJnkHM4HPr66681cODAMrcLCwtTWFiYR2oAAAAIJG4Hu2HDhunRRx/VG2+8oerVq1/Rh+fn52vPnj3O99nZ2crKylLNmjWVlJSkp59+Wq+99poaNmyo1NRUjRgxQgkJCerZs+cVfS4AAIAVuR3sDh06pCFDhlxxqJOkjRs3qmPHjs73F06h9uvXT9OnT9fzzz+vU6dO6bHHHtMvv/yi3/3ud1qyZInCw8Ov+LMBAACsxu1Hit17773q3bu3HnjgAW/V5FE8UgwAAAQyd7KM20fs7r77bj333HPavn27mjVrdslkxOnp6e7uEgAAAB7g9hG7oKCyZ0ix2WwqKiq64qI8iSN2AAAgkHn1iN3F05sAAADAP1hugmIAAICqqkLBbuXKlerevbsaNGigBg0aKD09XatXr/Z0bQAAAHCD28Fu5syZ6ty5s6pXr64hQ4ZoyJAhioiIUKdOnTRr1ixv1AgAAAAXuH3zROPGjfXYY49p6NChJZaPHz9eU6dO1Y4dOzxa4JXi5gkAABDI3Mkybh+x++GHH9S9e/dLlqenpys7O9vd3QEAAMBD3A52iYmJWrZs2SXLly5dqsTERI8UBQAAAPdV6FmxQ4YMUVZWltq2bStJWrt2raZPn663337b4wUCAADANW4Hu4EDByo+Pl5vvfWW/vGPf0j69bq7uXPnqkePHh4vEAAAAK5x++aJQMPNEwAAIJB59eYJAAAA+CeXTsXWrFlT33//vWrXrq3Y2FjZbLYy2544ccJjxQEAAMB1LgW7CRMmKCoqyvnn8oIdAAAAfINr7AAAAPyYV6+xCw4O1vHjxy9Z/vPPPys4ONjd3QEAAMBD3A52ZR3gKygoUGho6BUXBAAAgIpxeR67d955R5Jks9n0t7/9TZGRkc51RUVFWrVqla677jrPVwgAAACXuBzsJkyYIOnXI3ZTpkwpcdo1NDRUKSkpmjJliucrBAAAgEtcDnbZ2dmSpI4dO2revHmKjY31WlEAAABwn9uPFFuxYoU36gAAAMAVcjvYSdLBgwe1cOFCHThwQOfOnSuxbvz48R4pDAAAAO5xO9gtW7ZM6enpuvrqq7Vz5041bdpU+/btkzFGN954ozdqBAAAgAvcnu5k+PDhevbZZ7Vt2zaFh4fr008/VU5Ojjp06KD777/fGzUCAADABW4Hux07dujhhx+WJIWEhOjMmTOKjIzUq6++qnHjxnm8QAAAALjG7WBXo0YN53V19erV0969e53rfvrpJ89VBgAAALe4fY3dLbfcojVr1qhx48a66667NGzYMG3btk3z5s3TLbfc4o0aAQAA4AK3g9348eOVn58vSRo9erTy8/M1d+5cNWzYkDtiAQAAfMitYFdUVKSDBw8qLS1N0q+nZXnaBAAAgH9w6xq74OBg3XHHHcrNzfVWPQAAAKggt2+eaNq0qX744Qdv1AIAAIAr4Hawe+211/Tss89q0aJFOnLkiBwOR4kXAAAAfMNmjDHubBAU9P+yoM1mc/7ZGCObzaaioiLPVecBDodDdrtdeXl5io6O9nU5AAAAbnEny7h9V+yKFSsqXBgAAAC8x+1g16FDB2/UAQAAgCvkdrBbtWpVuevbt29f4WIAAABQcW4Hu9tuu+2SZb+91s7frrEDAACoKty+KzY3N7fE6/jx41qyZIlatWqlL7/80hs1AgAAwAVuBzu73V7iVbt2bXXp0kXjxo3T888/79HiioqKNGLECKWmpioiIkLXXHONxowZIzdv5AUAAKgS3D4VW5a4uDjt2rXLU7uTJI0bN07vvfeePvroIzVp0kQbN27UI488IrvdriFDhnj0swAAAAKd28Fu69atJd4bY3TkyBGNHTtWLVq08FRdkqSvvvpKPXr00N133y1JSklJ0ezZs/XNN9949HMAAACswO1g16JFC9lstktOh95yyy368MMPPVaYJLVt21YffPCBvv/+e1177bX69ttvtWbNGo0fP77MbQoKClRQUOB8z9MwAABAVeF2sMvOzi7xPigoSHXq1FF4eLjHirrgxRdflMPh0HXXXafg4GAVFRXp9ddfV58+fcrcJiMjQ6NHj/Z4LQAAAP7O7UeKVaY5c+boueee01/+8hc1adJEWVlZevrppzV+/Hj169ev1G1KO2KXmJjII8UAAEBAcueRYm4Fu+LiYk2fPl3z5s3Tvn37ZLPZlJqaqvvuu099+/YtMZ+dJyQmJurFF1/U4MGDnctee+01zZw5Uzt37nRpHzwrFgAABDJ3sozL050YY5Senq4//vGPOnTokJo1a6YmTZpo//796t+/v+65554rLvxip0+fVlBQyRKDg4NVXFzs8c8CAAAIdC5fYzd9+nStWrVKy5YtU8eOHUusW758uXr27KmPP/5YDz/8sMeK6969u15//XUlJSWpSZMm2rJli8aPH69HH33UY58BAABgFS6fir3jjjt0++2368UXXyx1/RtvvKGVK1fqiy++8FhxJ0+e1IgRIzR//nwdP35cCQkJevDBBzVy5EiFhoa6tA9OxQIAgEDmlWvs4uPjtWTJkjLnqtuyZYu6deumo0ePul2wNxHsAABAIPPKNXYnTpxQXFxcmevj4uKUm5vrepUAAADwKJeDXVFRkUJCyr4kLzg4WIWFhR4pCgAAAO5z+eYJY4z69++vsLCwUtf/du44AAAAVD6Xg11ZEwL/lifviAUAAIB7XA5206ZN82YdAAAAuEIuX2MHAAAA/0awAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwAwAAsAiCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLCPF1AVaQf7ZQQ+du0YHcM0qKjdCEXjcoMpy/WsDbzhUWa8a6fdp/4rSSa1ZX3zYpCg3h/6sAqi6bMcb4ughvcjgcstvtysvLU3R0tMf3nz5ptbYedFyyPK1+tBY+2c7jnwfgVxmLt2vq6mwV/+YnWJBNGtAuVcPvut53hQGAh7mTZfiv7RUoK9RJ0taDDqVPWl3JFQFVQ8bi7Xp/VclQJ0nFRnp/VbYyFm/3TWEA4GMEuwrKP1tYZqi7YOtBh/LPFlZSRUDVcK6wWFNXZ5fbZurqbJ0rLK6kigDAfxDsKmjo3C0ebQfANTPW7bvkSN3Fis2v7QCgqiHYVVD2T/kebQfANT+4OKZcbQcAVkKwq6BfTp/3aDsArjnuKPBoOwCwEoJdBcXUCPVoOwCuqRsd7tF2AGAlBLsKSq1Vw6PtALjm6tqujSlX2wGAlRDsKmhCrxs82g6Aa/q2SVGQrfw2QbZf2wFAVUOwq6DI8BCl1S9/ksC0+tE8gQLwsNCQIA1ol1pumwHtUnkCBYAqiZ98V2Dhk+3KDHc8eQLwnuF3Xa/H26decuQuyCY93p4nTwCounikmAfwrFjAN3hWLD9/gKrAnSxDsAOAAMWzqoGqgWfFAoDF8axqAKUh2AFAgOFZ1QDKQrADgADDs6oBlIVgBwAB5kDuGY+2A2AdBDsACDBJsREebQfAOvw+2B06dEi///3vVatWLUVERKhZs2bauHGjr8sCAJ/hyTcAyuLXkx3l5ubq1ltvVceOHfXvf/9bderU0e7duxUbG+vr0gDAZy48+aa8Gyh48g1QNfn1PHYvvvii1q5dq9WrK37bPvPYAbAq5rEDqgbLTFB8/fXXq2vXrjp48KBWrlypq666SoMGDdKAAQNc3gfBDoCV8eQJwPosE+zCw8MlSc8884zuv/9+bdiwQU899ZSmTJmifv36lbpNQUGBCgoKnO8dDocSExMJdgAAICBZJtiFhoaqZcuW+uqrr5zLhgwZog0bNmjdunWlbjNq1CiNHj36kuUEOwAAEIgs80ixevXq6frrry+xrHHjxjpw4ECZ2wwfPlx5eXnOV05OjrfLBAAA8At+fSHGrbfeql27dpVY9v333ys5ObnMbcLCwhQWFubt0gAAAPyOXx+xGzp0qNavX6833nhDe/bs0axZs/TBBx9o8ODBvi4NAADA7/h1sGvVqpXmz5+v2bNnq2nTphozZowmTpyoPn36+Lo0AAAAv+PXN094AtOdAACAQGaZmycAAADgOoIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEhvi4AAFBx+WcLNXTuFh3IPaOk2AhN6HWDIsP50Q54m7+OPZsxxvi6CG9yOByy2+3Ky8tTdHS0r8sBAI9Jn7RaWw86LlmeVj9aC59s54OKgKqhsseeO1mGU7EAEIDK+sUiSVsPOpQ+aXUlVwRUDf4+9gh2ABBg8s8WlvmL5YKtBx3KP1tYSRUBVUMgjD2CHQAEmKFzt3i0HQDXBMLYI9gBQIA5kHvGo+0AuCYQxh7BDgACTFJshEfbAXBNIIw9gh0ABJgJvW7waDsArgmEsUewA4AAExkeorT65U95kFY/2i/m1AKsJBDGHsEOAALQwifblfkLhnnsAO/x97HHBMUAEMD8dfZ7wOoqc+y5k2UIdgAAAH6MJ08AAABUQQQ7AAAAiyDYAQAAWATBDgAAwCIIdgAAABZBsAMAALAIgh0AAIBFBFSwGzt2rGw2m55++mlflwIAAOB3AibYbdiwQe+//77S0tJ8XQoAAIBfCohgl5+frz59+mjq1KmKjY31dTkAAAB+KSCC3eDBg3X33Xerc+fOl21bUFAgh8NR4gUAAFAV+P2ToufMmaPNmzdrw4YNLrXPyMjQ6NGjvVwVAACA//HrI3Y5OTl66qmn9Mknnyg8PNylbYYPH668vDznKycnx8tVAgAA+AebMcb4uoiyLFiwQPfcc4+Cg4Ody4qKimSz2RQUFKSCgoIS60rjcDhkt9uVl5en6Ohob5cMAADgUe5kGb8+FdupUydt27atxLJHHnlE1113nV544YXLhjoAAICqxK+DXVRUlJo2bVpiWY0aNVSrVq1LlgMAAFR1fn2NHQAAAFzn10fsSpOZmenrEgAAAPwSR+wAAAAsgmAHAABgEQQ7AAAAiyDYAQAAWATBDgAAwCIIdgAAABZBsAMAALAIgh0AAIBFEOwAAAAsgmAHAABgEQQ7AAAAiyDYAQAAWATBDgAAwCIIdgAAABZBsAMAALAIgh0AAIBFEOwAAAAsgmAHAABgEQQ7AAAAiyDYAQAAWATBDgAAwCIIdgAAABZBsAMAALAIgh0AAIBFEOwAAAAsIsTXBQAAKi7/bKGGzt2iA7lnlBQboQm9blBkOD/agaqK0Q8AASp90mptPehwvt919KSajvpCafWjtfDJdj6sDICvcCoWAALQxaHut7YedCh90upKrgiAPyDYAUCAyT9bWGaou2DrQYfyzxZWUkUA/AXBDgACzNC5WzzaDoB1EOwAIMAcyD3j0XYArINgBwABJik2wqPtAFgHwQ4AAsyEXjd4tB0A6yDYAUCAiQwPUVr96HLbpNWPZj47oAoi2AFAAFr4ZLsywx3z2AFVF/+dA4AAtfDJdjx5AkAJjH4ACGCR4SGa2q+Vr8sA4Cc4FQsAAGARfh/sMjIy1KpVK0VFRalu3brq2bOndu3a5euyAAAA/I7fB7uVK1dq8ODBWr9+vf7zn//o/PnzuuOOO3Tq1ClflwYAAOBXbMYY4+si3PHjjz+qbt26Wrlypdq3b3/Z9g6HQ3a7XXl5eYqOLn96AAAINNw8AfhGZY49d7JMwI3+vLw8SVLNmjV9XAkA+Fb6pNXaetDhfL/r6Ek1HfUF050AXubPY8/vT8X+VnFxsZ5++mndeuutatq0aaltCgoK5HA4SrwAwGou/sXyW1sPOpQ+aXUlVwRUDf4+9gIq2A0ePFj/93//pzlz5pTZJiMjQ3a73flKTEysxAoBwPvyzxaW+Yvlgq0HHco/W1hJFQFVQyCMvYAJdk8++aQWLVqkFStWqH79+mW2Gz58uPLy8pyvnJycSqwSALxv6NwtHm0HwDWBMPb8/ho7Y4z+9Kc/af78+crMzFRqamq57cPCwhQWFlZJ1QFA5TuQe8aj7QC4JhDGnt8fsRs8eLBmzpypWbNmKSoqSkePHtXRo0d15gw/sABUTUmxER5tB8A1gTD2/H66E5vNVuryadOmqX///pfdnulOAFhN/tlCNR31xWXb/d+orkx9AniQr8aepaY78fPcCQCVLjI8RGn1o8u9iDutfjShDvCwQBh7fn8qFgBwqYVPtlNa/dL/5+4Pc2kBVuXvY8/vT8VeKU7FArAynjwB+Ia/PnmCYAcAAODH3MkynIoFAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAiCHYAAAAWQbADAACwCIIdAACARRDsAAAALMLyT4q+8Chch8Ph40oAAADcdyHDXMg05bF8sDt58qQkKTEx0ceVAAAAVNzJkydlt9vLbWMzrsS/AFZcXKzDhw8rKipKNput3LYOh0OJiYnKyclRdHR0JVUIT6H/Ahv9F9jov8BF3/k/Y4xOnjyphIQEBQWVfxWd5Y/YBQUFqX79+m5tEx0dzT/uAEb/BTb6L7DRf4GLvvNvlztSdwE3TwAAAFgEwQ4AAMAiCHa/ERYWpldeeUVhYWG+LgUVQP8FNvovsNF/gYu+sxbL3zwBAABQVXDEDgAAwCIIdgAAABZBsAMAALAIywe7yZMnKyUlReHh4br55pv1zTfflNl26tSpateunWJjYxUbG6vOnTtf0t4Yo5EjR6pevXqKiIhQ586dtXv3bm9/jSrL0/3Xv39/2Wy2Eq8777zT21+jSnKn7+bNm6eWLVsqJiZGNWrUUIsWLTRjxowSbRh7lcvT/cfYq1zu9N9vzZkzRzabTT179iyxnPEXQIyFzZkzx4SGhpoPP/zQfPfdd2bAgAEmJibGHDt2rNT2Dz30kJk8ebLZsmWL2bFjh+nfv7+x2+3m4MGDzjZjx441drvdLFiwwHz77bcmPT3dpKammjNnzlTW16oyvNF//fr1M3feeac5cuSI83XixInK+kpVhrt9t2LFCjNv3jyzfft2s2fPHjNx4kQTHBxslixZ4mzD2Ks83ug/xl7lcbf/LsjOzjZXXXWVadeunenRo0eJdYy/wGHpYNe6dWszePBg5/uioiKTkJBgMjIyXNq+sLDQREVFmY8++sgYY0xxcbGJj483f/nLX5xtfvnlFxMWFmZmz57t2eLh8f4z5tdfLhf/wILnXWnfGWPMDTfcYF5++WVjDGOvsnm6/4xh7FWmivRfYWGhadu2rfnb3/52SV8x/gKLZU/Fnjt3Tps2bVLnzp2dy4KCgtS5c2etW7fOpX2cPn1a58+fV82aNSVJ2dnZOnr0aIl92u123XzzzS7vE67xRv9dkJmZqbp166pRo0YaOHCgfv75Z4/WXtVdad8ZY7Rs2TLt2rVL7du3l8TYq0ze6L8LGHveV9H+e/XVV1W3bl394Q9/uGQd4y+wWPZZsT/99JOKiooUFxdXYnlcXJx27tzp0j5eeOEFJSQkOP8xHz161LmPi/d5YR08wxv9J0l33nmn7r33XqWmpmrv3r3685//rG7dumndunUKDg726Heoqirad3l5ebrqqqtUUFCg4OBgvfvuu+rSpYskxl5l8kb/SYy9ylKR/luzZo3+/ve/Kysrq9T1jL/AYtlgd6XGjh2rOXPmKDMzU+Hh4b4uB24qq/969+7t/HOzZs2Ulpama665RpmZmerUqZMvSsX/LyoqSllZWcrPz9eyZcv0zDPP6Oqrr9Ztt93m69Lggsv1H2PPP508eVJ9+/bV1KlTVbt2bV+XAw+wbLCrXbu2goODdezYsRLLjx07pvj4+HK3/etf/6qxY8dq6dKlSktLcy6/sN2xY8dUr169Evts0aKF54qHV/qvNFdffbVq166tPXv28MvFQyrad0FBQWrQoIEkqUWLFtqxY4cyMjJ02223MfYqkTf6rzSMPe9wt//27t2rffv2qXv37s5lxcXFkqSQkBDt2rWL8RdgLHuNXWhoqG666SYtW7bMuay4uFjLli1TmzZtytzuzTff1JgxY7RkyRK1bNmyxLrU1FTFx8eX2KfD4dDXX39d7j7hPm/0X2kOHjyon3/+ucQPK1yZivbdxYqLi1VQUCCJsVeZvNF/pWHseYe7/Xfddddp27ZtysrKcr7S09PVsWNHZWVlKTExkfEXaHx994Y3zZkzx4SFhZnp06eb7du3m8cee8zExMSYo0ePGmOM6du3r3nxxRed7ceOHWtCQ0PNP//5zxK35J88ebJEm5iYGPPZZ5+ZrVu3mh49enDLt5d4uv9Onjxpnn32WbNu3TqTnZ1tli5dam688UbTsGFDc/bsWZ98R6tyt+/eeOMN8+WXX5q9e/ea7du3m7/+9a8mJCTETJ061dmGsVd5PN1/jL3K5W7/Xay0O5gZf4HD0sHOGGP+53/+xyQlJZnQ0FDTunVrs379eue6Dh06mH79+jnfJycnG0mXvF555RVnm+LiYjNixAgTFxdnwsLCTKdOncyuXbsq8RtVLZ7sv9OnT5s77rjD1KlTx1SrVs0kJyebAQMGOH/YwbPc6buXXnrJNGjQwISHh5vY2FjTpk0bM2fOnBL7Y+xVLk/2H2Ov8rnTfxcrLdgx/gKHzRhjfHW0EAAAAJ5j2WvsAAAAqhqCHQAAgEUQ7AAAACyCYAcAAGARBDsAAACLINgBAABYBMEOAADAIgh2AAAAFkGwA3BFMjMzZbPZ9Msvv3hl//v27ZPNZlNWVpbH9mmz2bRgwQKP7a88rtTv7b9DT0tJSdHEiROd73/793nx9w207wYEOoIdUIX8+OOPCg0N1alTp3T+/HnVqFFDBw4cKHebUaNGyWazyWazKSQkRCkpKRo6dKjy8/MrpebExEQdOXJETZs2rZTPuyAnJ0ePPvqoEhISFBoaquTkZD311FP6+eefPf5Zbdu21ZEjR2S32yVJ06dPV0xMjEf2vXLlSiUmJnpkXxds2LBBjz32mEttL/5uALyLYAdUIevWrVPz5s1Vo0YNbd68WTVr1lRSUtJlt2vSpImOHDmiffv2ady4cfrggw80bNiwSqhYCg4OVnx8vEJCQirl8yTphx9+UMuWLbV7927Nnj1be/bs0ZQpU7Rs2TK1adNGJ06c8OjnhYaGKj4+XjabzaP7laTPPvtM3bt39+g+69Spo+rVq7vU1pvfDcClCHZAFfLVV1/p1ltvlSStWbPG+efLCQkJUXx8vOrXr69evXqpT58+WrhwYYk2mzZtUsuWLVW9enW1bdtWu3btkvTrqbmgoCBt3LixRPuJEycqOTlZxcXFys3NVZ8+fVSnTh1FRESoYcOGmjZtmnP7i09lfvfdd/qv//ovRUdHKyoqSu3atdPevXsl/Xo0qUuXLqpdu7bsdrs6dOigzZs3u/X3NHjwYIWGhurLL79Uhw4dlJSUpG7dumnp0qU6dOiQXnrpJWfb0k7rxsTEaPr06SWW7dy5U23btlV4eLiaNm2qlStXOtf99nRlZmamHnnkEeXl5TmPlI4aNUqS9O6776phw4YKDw9XXFyc7rvvvst+l4ULFyo9Pb3UdReODC5atEiNGjVS9erVdd999+n06dP66KOPlJKSotjYWA0ZMkRFRUXO7S4+FVue0k7Ffvrpp2rSpInCwsKUkpKit956q8Q2KSkpeuONN/Too48qKipKSUlJ+uCDD1z6PKCqI9gBFnfgwAHFxMQoJiZG48eP1/vvv6+YmBj9+c9/1oIFCxQTE6NBgwa5tc+IiAidO3euxLKXXnpJb731ljZu3KiQkBA9+uijkn79Jd25c2dnULtg2rRp6t+/v4KCgjRixAht375d//73v7Vjxw699957ql27dqmffejQIbVv315hYWFavny5Nm3apEcffVSFhYWSpJMnT6pfv35as2aN1q9fr4YNG+quu+7SyZMnXfpuJ06c0BdffKFBgwYpIiKixLr4+Hj16dNHc+fOlTHGpf1d8Nxzz2nYsGHasmWL2rRpo+7du5d6Wrdt27aaOHGioqOjdeTIER05ckTPPvusNm7cqCFDhujVV1/Vrl27tGTJErVv377cz/zuu+90/Phx3X777WW2OX36tN555x3NmTNHS5YsUWZmpu655x4tXrxYixcv1owZM/T+++/rn//8p1vftyybNm3SAw88oN69e2vbtm0aNWqURowYcUkQfuutt9SyZUtt2bJFgwYN0sCBA53/WQBQDgPA0s6fP2+ys7PNt99+a6pVq2a+/fZbs2fPHhMZGWlWrlxpsrOzzY8//ljm9q+88opp3ry58/3GjRtN7dq1zX333WeMMWbFihVGklm6dKmzzb/+9S8jyZw5c8YYY8zcuXNNbGysOXv2rDHGmE2bNhmbzWays7ONMcZ0797dPPLII6V+fnZ2tpFktmzZYowxZvjw4SY1NdWcO3fOpe9fVFRkoqKizOeff+5cJsnMnz+/1Pbr168vd/348eONJHPs2LEy92W32820adNK1D927Fjn+vPnz5v69eubcePGGWP+399hbm6uMcaYadOmGbvdXmKfn376qYmOjjYOh8Ol722MMa+//rqzn0ozbdo0I8ns2bPHuezxxx831atXNydPnnQu69q1q3n88ced75OTk82ECROc73/7d3Bxf1383R566CHTpUuXEnU899xz5vrrry+x/9///vfO98XFxaZu3brmvffec/m7A1UVR+wAi7tww8POnTvVqlUrpaWl6ejRo4qLi1P79u2VkpJS5tGxC7Zt26bIyEhFRESodevWatOmjSZNmlSiTVpamvPP9erVkyQdP35cktSzZ08FBwdr/vz5kn49BdixY0elpKRIkgYOHKg5c+aoRYsWev755/XVV1+VWUtWVpbatWunatWqlbr+2LFjGjBggBo2bCi73a7o6Gjl5+df9iaRi5nLHJELDQ11a39t2rRx/jkkJEQtW7bUjh07XN6+S5cuSk5O1tVXX62+ffvqk08+0enTp8vd5rPPPivzNOwF1atX1zXXXON8HxcXp5SUFEVGRpZYdqEvr9SOHTsuuQTg1ltv1e7du0uc7v3tvyebzab4+HiP1QBYGcEOsLgmTZooMjJSffv21TfffKPIyEh16tRJ+/btU2RkpJo0aXLZfTRq1EhZWVnasWOHzpw5o4ULFyouLq5Em98GrQsXyhcXF0v6NQQ9/PDDmjZtms6dO6dZs2Y5T9VKUrdu3bR//34NHTpUhw8fVqdOnfTss8+WWsvFp0cv1q9fP2VlZentt9/WV199paysLNWqVeuSU8dladCggWw2W5mha8eOHapTp47zrlWbzXZJCDx//rxLn+WOqKgobd68WbNnz1a9evU0cuRINW/evMxpRI4cOaItW7bo7rvvLne/Fwdkm81W6rILfVlZ/KEGIBAR7ACLW7x4sbKyshQfH6+ZM2cqKytLTZs21cSJE5WVlaXFixdfdh+hoaFq0KCBUlJS3D5SdcEf//hHLV26VO+++64KCwt17733llhfp04d9evXTzNnztTEiRPLvFg+LS1Nq1evLjM8rV27VkOGDNFdd93lvED/p59+crnOWrVqqUuXLnr33Xd15syZEuuOHj2qTz75RP379y9R95EjR5zvd+/eXeqRtPXr1zv/XFhYqE2bNqlx48al1hAaGlri6NUFISEh6ty5s958801t3bpV+/bt0/Lly0vdx+eff662bduqZs2a5X7fyta4cWOtXbu2xLK1a9fq2muvVXBwsI+qAqyDYAdYXHJysiIjI3Xs2DH16NFDiYmJ+u677/Tf//3fatCggZKTkyuljsaNG+uWW27RCy+8oAcffLDEkbeRI0fqs88+0549e/Tdd99p0aJFZYaeJ598Ug6HQ71799bGjRu1e/duzZgxw3lhfcOGDTVjxgzt2LFDX3/9tfr06XPZo3wXmzRpkgoKCtS1a1etWrVKOTk5WrJkibp06aJrr71WI0eOdLa9/fbbNWnSJG3ZskUbN27UE088Uepp4smTJ2v+/PnauXOnBg8erNzc3BJHLX8rJSVF+fn5WrZsmX766SedPn1aixYt0jvvvKOsrCzt379fH3/8sYqLi9WoUaNS91He3bC+NGzYMC1btkxjxozR999/r48++kiTJk0q8wgtAPcQ7IAqIDMzU61atVJ4eLi++eYb1a9f33kdXGX6wx/+oHPnzl0SaEJDQzV8+HClpaWpffv2Cg4O1pw5c0rdR61atbR8+XLl5+erQ4cOuummmzR16lRnmPr73/+u3Nxc3Xjjjerbt6+GDBmiunXrulVnw4YNtWHDBl199dV64IEHlJycrG7duunaa6/V2rVrS1x/9tZbbykxMVHt2rXTQw89pGeffbbUOd7Gjh2rsWPHqnnz5lqzZo0WLlxY5rWNbdu21RNPPKFevXqpTp06evPNNxUTE6N58+bp9ttvV+PGjTVlyhTNnj271FPpp06d0rJly/wy2N144436xz/+oTlz5qhp06YaOXKkXn311RJHQQFUnM1c7gphAPCQMWPG6H//93+1detWX5fitldeeUXjx4/Xf/7zH91yyy2+Lqdc8+bN08svv6zt27f7uhQAlazypnIHUGXl5+dr3759mjRpkl577TVfl1Mho0ePVkpKitavX6/WrVsrKMh/T3hERkZq3Lhxvi4DgA9wxA6A1/Xv31+zZ89Wz549NWvWLC6SBwAvIdgBAABYhP+eSwAAAIBbCHYAAAAWQbADAACwCIIdAACARRDsAAAALIJgBwAAYBEEOwAAAIsg2AEAAFgEwQ4AAMAi/j/MRj9cxNNIywAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import itertools\n", "\n", "duration_hr_estimates = []\n", "n_physical_qubits_estimates = []\n", "for data_block, factory, scheme, phys in itertools.product(data_blocks, factories, schemes, phys_params):\n", " model = PhysicalCostModel(data_block=data_block, factory=factory, qec_scheme=scheme, physical_params=phys)\n", "\n", " duration_hr_estimates.append(model.duration_hr(alg))\n", " n_physical_qubits_estimates.append(model.n_phys_qubits(alg))\n", " \n", "\n", "from matplotlib import pyplot as plt\n", "import numpy as np\n", "plt.scatter(np.array(n_physical_qubits_estimates)/1e6, duration_hr_estimates)\n", "plt.xlabel('# Physical Qubits / million')\n", "plt.ylabel('Duration / hr')\n", "plt.tight_layout()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.8" } }, "nbformat": 4, "nbformat_minor": 5 }