diff --git a/docs/guides/function-template-hamiltonian-simulation.ipynb b/docs/guides/function-template-hamiltonian-simulation.ipynb index 6f21c49e205..4de5ae61038 100644 --- a/docs/guides/function-template-hamiltonian-simulation.ipynb +++ b/docs/guides/function-template-hamiltonian-simulation.ipynb @@ -60,23 +60,6 @@ "Throughout, the code is saved to `./source_files/template_hamiltonian_simulation.py`. This file is the function template you can upload to and run remotely with Qiskit Serverless." ] }, - { - "cell_type": "code", - "execution_count": 1, - "id": "35f5800c-163d-47a6-9fcf-13377be57282", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# This cell is hidden from users, it just creates a new folder\n", - "from pathlib import Path\n", - "\n", - "Path(\"./source_files\").mkdir(exist_ok=True)" - ] - }, { "cell_type": "markdown", "id": "115c14aa-5028-46f9-ab19-b49d47519636", @@ -102,8 +85,14 @@ } ], "source": [ - "%%writefile ./source_files/template_hamiltonian_simulation.py\n", + "# This cell is hidden from users, it just creates a new folder\n", + "from pathlib import Path\n", + "\n", + "Path(\"./source_files\").mkdir(exist_ok=True)\n", + "\n", + "PROGRAM_FILE = \"./source_files/template_hamiltonian_simulation.py\"\n", "\n", + "source = \"\"\"\n", "from qiskit import QuantumCircuit\n", "from qiskit_serverless import get_arguments, save_result\n", "\n", @@ -131,7 +120,11 @@ "\n", "hamiltonian = arguments[\"hamiltonian\"]\n", "observable = arguments[\"observable\"]\n", - "initial_state = arguments.get(\"initial_state\", QuantumCircuit(hamiltonian.num_qubits))" + "initial_state = arguments.get(\"initial_state\", QuantumCircuit(hamiltonian.num_qubits))\n", + "\"\"\"\n", + "\n", + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, { @@ -149,8 +142,7 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", - "\n", + "source = \"\"\"\n", "import numpy as np\n", "import json\n", "from mergedeep import merge\n", @@ -185,7 +177,12 @@ "# Merge with user-provided options\n", "estimator_options = merge(\n", " arguments.get(\"estimator_options\", {}), estimator_default_options\n", - ")" + ")\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -211,9 +208,13 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", + "source = \"\"\"\n", + "print(\"estimator_options =\", json.dumps(estimator_options, indent=4))\n", + "\"\"\"\n", "\n", - "print(\"estimator_options =\", json.dumps(estimator_options, indent=4))" + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -241,14 +242,18 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", - "\n", + "source = \"\"\"\n", "# Perform parameter validation\n", "\n", "if not 0.0 < aqc_stopping_fidelity <= 1.0:\n", " raise ValueError(\n", " f\"Invalid stopping fidelity: {aqc_stopping_fidelity}. It must be a positive float no greater than 1.\"\n", - " )" + " )\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -276,9 +281,13 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", + "source = \"\"\"\n", + "output = {}\n", + "\"\"\"\n", "\n", - "output = {}" + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -308,8 +317,7 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", - "\n", + "source = \"\"\"\n", "import os\n", "os.environ[\"NUMBA_CACHE_DIR\"] = \"/data\"\n", "\n", @@ -420,7 +428,12 @@ " synthesis=SuzukiTrotter(reps=remainder_num_trotter_steps),\n", " time=remainder_evolution_time,\n", " )\n", - " final_circuit.compose(remainder_circuit, inplace=True)" + " final_circuit.compose(remainder_circuit, inplace=True)\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -448,8 +461,7 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", - "\n", + "source = \"\"\"\n", "from qiskit_ibm_runtime import QiskitRuntimeService\n", "from qiskit.transpiler import generate_preset_pass_manager\n", "\n", @@ -463,7 +475,12 @@ "\n", "isa_2qubit_depth = isa_circuit.depth(lambda x: x.operation.num_qubits == 2)\n", "print(\"ISA circuit two-qubit depth:\", isa_2qubit_depth)\n", - "output[\"twoqubit_depth\"] = isa_2qubit_depth" + "output[\"twoqubit_depth\"] = isa_2qubit_depth\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -491,15 +508,19 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", - "\n", + "source = \"\"\"\n", "# Exit now if dry run; don't execute on hardware\n", "if dry_run:\n", " import sys\n", "\n", " print(\"Exiting before hardware execution since `dry_run` is True.\")\n", " save_result(output)\n", - " sys.exit(0)" + " sys.exit(0)\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -525,8 +546,7 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", - "\n", + "source = \"\"\"\n", "# ## Step 3: Execute quantum experiments on backend\n", "from qiskit_ibm_runtime import EstimatorV2 as Estimator\n", "\n", @@ -551,7 +571,12 @@ "\n", "# Save expectation values to Qiskit Serverless\n", "print(\"Hardware expectation values\", hw_expvals)\n", - "output[\"hw_expvals\"] = hw_expvals[0]" + "output[\"hw_expvals\"] = hw_expvals[0]\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -579,9 +604,13 @@ } ], "source": [ - "%%writefile --append ./source_files/template_hamiltonian_simulation.py\n", + "source = \"\"\"\n", + "save_result(output)\n", + "\"\"\"\n", "\n", - "save_result(output)" + "# \"a\" appends to the file rather than overwriting it\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -1119,6 +1148,22 @@ "" ] }, + { + "cell_type": "markdown", + "id": "dfcb6598-d78c-4204-b0cc-3ef74e70d73b", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "Here is the entire source of `./source_files/template_hamiltonian_simulation.py` as one code block.\n", + "\n", + "\n", + "\n", + " \n", + "" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1138,8 +1183,7 @@ } ], "source": [ - "%%writefile ./source_files/template_hamiltonian_simulation_full.py\n", - "\n", + "source = \"\"\"\n", "from qiskit import QuantumCircuit\n", "from qiskit_serverless import get_arguments, save_result\n", "\n", @@ -1376,23 +1420,11 @@ "# Save expectation values to Qiskit Serverless\n", "output[\"hw_expvals\"] = hw_expvals[0]\n", "\n", - "save_result(output)" - ] - }, - { - "cell_type": "markdown", - "id": "d7f1776a-a8f6-43a3-85b7-33975c4eeec0", - "metadata": {}, - "source": [ - "\n", - "\n", - "\n", - "Here is the entire source of `./source_files/template_hamiltonian_simulation.py` as one code block.\n", + "save_result(output)\n", + "\"\"\"\n", "\n", - "\n", - "\n", - " \n", - "" + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, { diff --git a/docs/guides/serverless-first-program.ipynb b/docs/guides/serverless-first-program.ipynb index 00c6005e845..e30c191988a 100644 --- a/docs/guides/serverless-first-program.ipynb +++ b/docs/guides/serverless-first-program.ipynb @@ -68,27 +68,6 @@ "1. Run the program" ] }, - { - "cell_type": "code", - "execution_count": 2, - "id": "b186515d-7686-43c3-94a6-187eba0808b9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# This cell is hidden from users, it just creates a new folder\n", - "from pathlib import Path\n", - "\n", - "Path(\"./source_files\").mkdir(exist_ok=True)" - ] - }, { "cell_type": "markdown", "id": "cad16f43-8548-4849-a4b8-09059a8b747c", @@ -117,7 +96,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "64722041-22ed-42bd-8d83-d8e9f5e5b55b", "metadata": { "editable": true, @@ -126,18 +105,16 @@ }, "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Writing ./source_files/transpile_remote.py\n" - ] - } - ], + "outputs": [], "source": [ - "%%writefile ./source_files/transpile_remote.py\n", + "from pathlib import Path\n", + "\n", + "PROGRAM_FILE = \"./source_files/transpile_remote.py\"\n", + "\n", + "# Make the folder if it doesn't already exist\n", + "Path(\"./source_files\").mkdir(exist_ok=True)\n", "\n", + "source = '''\n", "from qiskit.transpiler import generate_preset_pass_manager\n", "\n", "def transpile_remote(circuit, optimization_level, backend):\n", @@ -147,7 +124,11 @@ "\t\tbackend=backend\n", " )\n", " isa_circuit = pass_manager.run(circuit)\n", - " return isa_circuit" + " return isa_circuit\n", + "'''\n", + "\n", + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, { @@ -164,28 +145,24 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "6819379b-d7b2-4fda-9e6b-459eec748a79", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Appending to ./source_files/transpile_remote.py\n" - ] - } - ], + "outputs": [], "source": [ - "%%writefile --append ./source_files/transpile_remote.py\n", - "\n", + "source = \"\"\"\n", "from qiskit_serverless import get_arguments, save_result, distribute_task, get\n", "\n", "# Get program arguments\n", "arguments = get_arguments()\n", "circuits = arguments.get(\"circuits\")\n", "backend_name = arguments.get(\"backend_name\")\n", - "optimization_level = arguments.get(\"optimization_level\")" + "optimization_level = arguments.get(\"optimization_level\")\n", + "\"\"\"\n", + "\n", + "# \"a\" argument appends to file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -200,25 +177,21 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "4b0c7d24-9b87-4e00-bb1d-f82aa967cb1d", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Appending to ./source_files/transpile_remote.py\n" - ] - } - ], + "outputs": [], "source": [ - "%%writefile --append ./source_files/transpile_remote.py\n", - "\n", + "source = \"\"\"\n", "from qiskit_ibm_runtime import QiskitRuntimeService\n", "\n", "service = QiskitRuntimeService()\n", - "backend = service.backend(backend_name)" + "backend = service.backend(backend_name)\n", + "\"\"\"\n", + "\n", + "# \"a\" argument appends to file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -231,22 +204,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "041e7f85-e9e8-424d-8694-d54316225cc4", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Appending to ./source_files/transpile_remote.py\n" - ] - } - ], + "outputs": [], "source": [ + "source = \"\"\"\n", "# Each circuit is being transpiled and will populate the array\n", - "%%writefile --append ./source_files/transpile_remote.py\n", - "\n", "results = [\n", " transpile_remote(circuit, 1, backend)\n", " for circuit in circuits\n", @@ -254,7 +218,12 @@ "\n", "save_result({\n", " \"transpiled_circuits\": results\n", - "})" + "})\n", + "\"\"\"\n", + "\n", + "# \"a\" argument appends to file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { diff --git a/docs/guides/serverless-manage-resources.ipynb b/docs/guides/serverless-manage-resources.ipynb index b07a6941e63..54d6422cbf5 100644 --- a/docs/guides/serverless-manage-resources.ipynb +++ b/docs/guides/serverless-manage-resources.ipynb @@ -68,23 +68,6 @@ "You can also set custom statuses that further describe the specific workflow stage, as follows." ] }, - { - "cell_type": "code", - "execution_count": 1, - "id": "9e41cd2f-bce6-4c8a-8e44-537c18b3023c", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# This cell is hidden from users, it just creates a new folder\n", - "from pathlib import Path\n", - "\n", - "Path(\"./source_files\").mkdir(exist_ok=True)" - ] - }, { "cell_type": "code", "execution_count": 2, @@ -100,8 +83,12 @@ } ], "source": [ - "%%writefile ./source_files/status_example.py\n", + "from pathlib import Path\n", + "\n", + "PROGRAM_FILE = \"./source_files/status_example.py\"\n", "\n", + "# The following string is our serverless program\n", + "source = \"\"\"\n", "from qiskit_serverless import update_status, Job\n", "\n", "## If your function has a mapping stage, particularly application functions, you can set the status to \"RUNNING: MAPPING\" as follows:\n", @@ -117,7 +104,13 @@ "update_status(Job.EXECUTING_QPU)\n", "\n", "## Once QPU is completed and post-processing has begun, set the status \"RUNNING: POST_PROCESSING\":\n", - "update_status(Job.POST_PROCESSING)" + "update_status(Job.POST_PROCESSING)\n", + "\"\"\"\n", + "\n", + "# Ensure the folder exists and write the program to file\n", + "Path(\"./source_files\").mkdir(exist_ok=True)\n", + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, { @@ -155,8 +148,9 @@ } ], "source": [ - "%%writefile ./source_files/transpile_remote.py\n", + "PROGRAM_FILE = \"./source_files/transpile_remote.py\"\n", "\n", + "source = '''\n", "from qiskit.transpiler import generate_preset_pass_manager\n", "from qiskit_ibm_runtime import QiskitRuntimeService\n", "from qiskit_serverless import distribute_task\n", @@ -171,7 +165,11 @@ " backend=service.backend(backend)\n", " )\n", " isa_circuit = pass_manager.run(circuit)\n", - " return isa_circuit" + " return isa_circuit\n", + "'''\n", + "\n", + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, { @@ -197,8 +195,7 @@ } ], "source": [ - "%%writefile --append ./source_files/transpile_remote.py\n", - "\n", + "source = \"\"\"\n", "from time import time\n", "from qiskit_serverless import get, get_arguments, save_result, update_status, Job\n", "\n", @@ -206,7 +203,12 @@ "arguments = get_arguments()\n", "circuit = arguments.get(\"circuit\")\n", "optimization_level = arguments.get(\"optimization_level\")\n", - "backend = arguments.get(\"backend\")" + "backend = arguments.get(\"backend\")\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -224,7 +226,7 @@ } ], "source": [ - "%%writefile --append ./source_files/transpile_remote.py\n", + "source = \"\"\"\n", "# Start distributed transpilation\n", "\n", "update_status(Job.OPTIMIZING_HARDWARE)\n", @@ -236,7 +238,12 @@ "]\n", "\n", "transpiled_circuits = get(transpile_worker_references)\n", - "end_time = time()" + "end_time = time()\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -254,7 +261,7 @@ } ], "source": [ - "%%writefile --append ./source_files/transpile_remote.py\n", + "source = \"\"\"\n", "# Save result, with metadata\n", "\n", "result = {\n", @@ -269,7 +276,12 @@ " },\n", "}\n", "\n", - "save_result(result)" + "save_result(result)\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -413,14 +425,18 @@ } ], "source": [ - "%%writefile --append ./source_files/transpile_remote.py\n", - "\n", + "source = \"\"\"\n", "@distribute_task(target={\n", " \"cpu\": 16,\n", " \"mem\": 2 * 1024 * 1024 * 1024\n", "})\n", "def transpile_remote(circuit, optimization_level, backend):\n", - " return None" + " return None\n", + "\"\"\"\n", + "\n", + "# \"a\" appends to the file rather than overwriting\n", + "with open(PROGRAM_FILE, \"a\") as file:\n", + " file.write(source)" ] }, { @@ -617,8 +633,9 @@ "metadata": {}, "outputs": [], "source": [ - "%%writefile ./source_files/extract_tarfile.py\n", + "PROGRAM_FILE = \"./source_files/extract_tarfile.py\"\n", "\n", + "source = \"\"\"\n", "import tarfile\n", "from qiskit_serverless import IBMServerlessClient\n", "\n", @@ -629,7 +646,11 @@ "\n", "\n", "with tarfile.open(downloaded_tar, 'r') as tar:\n", - " tar.extractall()" + " tar.extractall()\n", + "\"\"\"\n", + "\n", + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, { diff --git a/docs/tutorials/transpilation-optimizations-with-sabre.ipynb b/docs/tutorials/transpilation-optimizations-with-sabre.ipynb index 8dcc3c665cd..758cf6d3b11 100644 --- a/docs/tutorials/transpilation-optimizations-with-sabre.ipynb +++ b/docs/tutorials/transpilation-optimizations-with-sabre.ipynb @@ -740,24 +740,7 @@ "id": "0d6b162b-8a78-4b7b-a497-def00672a816", "metadata": {}, "source": [ - "Qiskit Serverless requires setting up your workload’s `.py` files into a dedicated directory. The following code cell is a Python file in the `source_files` directory named `transpile_remote.py`. This file contains the function that runs the transpilation process." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "0ba37113-8e9b-4797-8e13-915310933100", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# This cell is hidden from users, it makes sure the `source_files` directory exists\n", - "from pathlib import Path\n", - "\n", - "Path(\"source_files\").mkdir(exist_ok=True)" + "Qiskit Serverless requires setting up your workload’s `.py` files into a dedicated directory. The following code cell creates a Python file in the `source_files` directory named `transpile_remote.py`. This file contains the function that runs the transpilation process." ] }, { @@ -775,7 +758,14 @@ } ], "source": [ - "%%writefile source_files/transpile_remote.py\n", + "from pathlib import Path\n", + "\n", + "PROGRAM_FILE = \"./source_files/transpile_remote.py\"\n", + "\n", + "# Ensure the folder exists\n", + "Path(\"source_files\").mkdir(exist_ok=True)\n", + "\n", + "source = '''\n", "import time\n", "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n", "from qiskit.transpiler.passes import SabreLayout, SabreSwap\n", @@ -837,7 +827,11 @@ "transpile_times = [result[1] for result in results_with_times]\n", "\n", "# Save both results and transpile times\n", - "save_result({\"transpiled_circuits\": transpiled_circuits, \"transpile_times\": transpile_times})" + "save_result({\"transpiled_circuits\": transpiled_circuits, \"transpile_times\": transpile_times})\n", + "'''\n", + "\n", + "with open(PROGRAM_FILE, \"w\") as file:\n", + " file.write(source)" ] }, {