"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"from quantum_serverless import Program\n",
"\n",
"program = Program(\n",
- " title=\"First program\",\n",
- " entrypoint=\"program_1.py\",\n",
- " working_dir=\"./source_files/\"\n",
+ " title=\"First program\", entrypoint=\"program.py\", working_dir=\"./source_files/\"\n",
")\n",
"\n",
"job = serverless.run(program)\n",
@@ -118,10 +150,21 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"id": "cc7ccea6-bbae-4184-ba7f-67b6c20a0b0b",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'QUEUED'"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job.status()"
]
@@ -136,10 +179,21 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"id": "1dc78690-f61a-4dfe-bc0e-7007cf561a5b",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'[{\"0\": 0.4999999999999999, \"3\": 0.4999999999999999}]'"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job.result()"
]
@@ -154,13 +208,61 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"id": "eb5ec85f",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k\n",
+ "OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k\n",
+ "Running program 1...\n",
+ "Completed running program 1.\n",
+ "\n"
+ ]
+ }
+ ],
"source": [
"print(job.logs())"
]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9784597b-9377-4d26-8ab9-a8a9b363c924",
+ "metadata": {},
+ "source": [
+ "`QuantumServerless` object has method `.widget` which renders Jupyter widget to see list of executed programs.\n",
+ "\n",
+ "![widget](./images/widget.png)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "f24023e1-6ce4-481e-b43d-3e19bff81d57",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b385710d381c42e8b6f43e7d14539eea",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Tab(children=(GridspecLayout(children=(Output(layout=Layout(grid_area='widget001')), Output(layout=Layout(grid…"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "serverless.widget()"
+ ]
}
],
"metadata": {
@@ -179,7 +281,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.17"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/running/notebooks/03_arguments_and_results.ipynb b/docs/getting_started/basic/02_arguments_and_results.ipynb
similarity index 58%
rename from docs/running/notebooks/03_arguments_and_results.ipynb
rename to docs/getting_started/basic/02_arguments_and_results.ipynb
index e35e61c3c..ccb71862c 100644
--- a/docs/running/notebooks/03_arguments_and_results.ipynb
+++ b/docs/getting_started/basic/02_arguments_and_results.ipynb
@@ -4,18 +4,18 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Programs with arguments\n",
+ "# Passing input arguments to your program\n",
"\n",
"In this document, we will learn how to pass arguments to our program.\n",
"\n",
- "Let's create another file with our program [./source_files/program_3.py](./source_files/program_3.py). \n",
+ "Let's create another file with our program [./source_files/program_with_arguments.py](./source_files/program_with_arguments.py). \n",
"\n",
"Instead of having the circuit defined inside the program (like we did in first example), we will pass it as an argument. We will also save the results, so we can access them later by calling [save_result](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.save_result.html#quantum_serverless.core.save_result).\n",
"\n",
"Here is the program:\n",
"\n",
"```python\n",
- "# source_files/program_3.py\n",
+ "# source_files/program_with_arguments.py\n",
"\n",
"from quantum_serverless import get_arguments, save_result\n",
"\n",
@@ -51,9 +51,35 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " ┌───┐ ░ ┌─┐ \n",
+ " q_0: ┤ H ├──■───░─┤M├───\n",
+ " └───┘┌─┴─┐ ░ └╥┘┌─┐\n",
+ " q_1: ─────┤ X ├─░──╫─┤M├\n",
+ " └───┘ ░ ║ └╥┘\n",
+ "meas: 2/══════════════╩══╩═\n",
+ " 0 1
"
+ ],
+ "text/plain": [
+ " ┌───┐ ░ ┌─┐ \n",
+ " q_0: ┤ H ├──■───░─┤M├───\n",
+ " └───┘┌─┴─┐ ░ └╥┘┌─┐\n",
+ " q_1: ─────┤ X ├─░──╫─┤M├\n",
+ " └───┘ ░ ║ └╥┘\n",
+ "meas: 2/══════════════╩══╩═\n",
+ " 0 1 "
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"from qiskit import QuantumCircuit\n",
"\n",
@@ -73,7 +99,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {
"tags": []
},
@@ -83,34 +109,42 @@
"\n",
"program = Program(\n",
" title=\"Program with arguments\",\n",
- " entrypoint=\"program_3.py\",\n",
- " working_dir=\"./source_files/\"\n",
+ " entrypoint=\"program_with_arguments.py\",\n",
+ " working_dir=\"./source_files/\",\n",
")"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "jupyter": {
- "outputs_hidden": false
- }
- },
- "outputs": [],
+ "cell_type": "markdown",
+ "metadata": {},
"source": [
- "from quantum_serverless import QuantumServerless, Provider\n",
- "import os"
+ "> ⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on [local infrastructure setup](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
+ "from quantum_serverless import QuantumServerless, Provider\n",
+ "import os\n",
+ "\n",
"provider = Provider(\n",
- " username=\"user\",\n",
- " password=\"password123\",\n",
+ " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n",
+ " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n",
+ " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n",
" host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n",
")\n",
"\n",
@@ -127,7 +161,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@@ -143,9 +177,20 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'{\"quasi_dists\": {\"0\": 0.4999999999999999, \"3\": 0.4999999999999999}}'"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job.result()"
]
@@ -167,7 +212,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.16"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/running/notebooks/04_dependencies.ipynb b/docs/getting_started/basic/03_dependencies.ipynb
similarity index 67%
rename from docs/running/notebooks/04_dependencies.ipynb
rename to docs/getting_started/basic/03_dependencies.ipynb
index b315151b4..c3b5fb3b5 100644
--- a/docs/running/notebooks/04_dependencies.ipynb
+++ b/docs/getting_started/basic/03_dependencies.ipynb
@@ -6,18 +6,18 @@
"tags": []
},
"source": [
- "# Dependency management for programs\n",
+ "# Using python packages with your programs\n",
"\n",
"In this document, we will learn how to install custom dependencies to your program.\n",
"\n",
- "Let's create another file with our new program [./source_files/program_4.py](./source_files/program_4.py). \n",
+ "Let's create another file with our new program [./source_files/program_with_dependencies.py](./source_files/program_with_dependencies.py). \n",
"\n",
"For the sake of this example, let's use the `qiskit-experiments` package as our custom dependency. We will use randomized benchmarking (RB) circuits from `qiskit-experiments`, composed with the circuit from the input arguments for measurement.\n",
"\n",
"Here's what the file would look like:\n",
"\n",
"```python\n",
- "# source_files/program_4.py\n",
+ "# source_files/program_with_dependencies.py\n",
"\n",
"from quantum_serverless import get_arguments, save_result\n",
"\n",
@@ -64,7 +64,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {
"tags": []
},
@@ -74,31 +74,43 @@
"\n",
"program = Program(\n",
" title=\"Program with dependencies\",\n",
- " entrypoint=\"program_4.py\",\n",
+ " entrypoint=\"program_with_dependencies.py\",\n",
" working_dir=\"./source_files/\",\n",
- " dependencies=[\"qiskit-experiments==0.5.2\"]\n",
+ " dependencies=[\"qiskit-experiments==0.5.2\"],\n",
")"
]
},
{
- "cell_type": "code",
- "execution_count": null,
+ "cell_type": "markdown",
"metadata": {},
- "outputs": [],
"source": [
- "from quantum_serverless import QuantumServerless, Provider\n",
- "import os"
+ "> ⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on [local infrastructure setup](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
+ "from quantum_serverless import QuantumServerless, Provider\n",
+ "import os\n",
+ "\n",
"provider = Provider(\n",
- " username=\"user\",\n",
- " password=\"password123\",\n",
+ " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n",
+ " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n",
+ " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n",
" host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n",
")\n",
"\n",
@@ -108,17 +120,18 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from qiskit.circuit.random import random_circuit\n",
+ "\n",
"circuit = random_circuit(2, 2)"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@@ -127,20 +140,42 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'QUEUED'"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job.status()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'{\"quasi_dists\": {\"0\": 0.6107159035567002, \"1\": 0.3892840964432998}}'"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
- "print(job.logs())"
+ "job.result()"
]
}
],
@@ -160,7 +195,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.16"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/running/notebooks/02_distributed_workloads.ipynb b/docs/getting_started/basic/04_distributed_workloads.ipynb
similarity index 67%
rename from docs/running/notebooks/02_distributed_workloads.ipynb
rename to docs/getting_started/basic/04_distributed_workloads.ipynb
index fc6798d98..395eca7a0 100644
--- a/docs/running/notebooks/02_distributed_workloads.ipynb
+++ b/docs/getting_started/basic/04_distributed_workloads.ipynb
@@ -8,10 +8,10 @@
"\n",
"In this document, we will learn how to run distributed workflows inside a program. In this case, we will compute the quasi-probability distribution in parallel for a list of quantum circuits.\n",
"\n",
- "Let's take a look at the program file [./source_files/program_2.py](./source_files/program_2.py). \n",
+ "Let's take a look at the program file [./source_files/program_with_parallel_workflow.py](./source_files/program_with_parallel_workflow.py). \n",
"\n",
"```python\n",
- "# source_files/program_2.py\n",
+ "# source_files/program_with_parallel_workflow.py\n",
"\n",
"from quantum_serverless import get_arguments, save_result, distribute_task, get\n",
"\n",
@@ -64,28 +64,36 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "jupyter": {
- "outputs_hidden": false
- }
- },
- "outputs": [],
+ "cell_type": "markdown",
+ "metadata": {},
"source": [
- "from quantum_serverless import QuantumServerless, Provider\n",
- "import os"
+ "> ⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on [local infrastructure setup](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
+ "from quantum_serverless import QuantumServerless, Provider\n",
+ "import os\n",
+ "\n",
"provider = Provider(\n",
- " username=\"user\",\n",
- " password=\"password123\",\n",
+ " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n",
+ " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n",
+ " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n",
" host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n",
")\n",
"\n",
@@ -97,14 +105,27 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Let's create list of random circuit which we will be using as arguments"
+ "Let's create a list of random circuits which we will be passed as arguments to the program."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[,\n",
+ " ,\n",
+ " ]"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"from qiskit.circuit.random import random_circuit\n",
"\n",
@@ -117,21 +138,32 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Run program as usual"
+ "Run program as usual, but pass the circuits in as a keyword argument, `circuits`."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"from quantum_serverless import Program\n",
"\n",
"program = Program(\n",
- " title=\"Program with distributed workflow\",\n",
- " entrypoint=\"program_2.py\",\n",
- " working_dir=\"./source_files/\"\n",
+ " title=\"Program with parallel workflow\",\n",
+ " entrypoint=\"program_with_parallel_workflow.py\",\n",
+ " working_dir=\"./source_files/\",\n",
")\n",
"\n",
"job = serverless.run(program, arguments={\"circuits\": circuits})\n",
@@ -140,18 +172,40 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'QUEUED'"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job.status()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'{\"results\": [{\"2\": 0.4999999999999999, \"3\": 0.4999999999999999}, {\"0\": 0.410199670072165, \"1\": 0.410199670072165, \"2\": 0.0898003299278348, \"3\": 0.0898003299278349}, {\"0\": 0.4999999999999999, \"2\": 0.4999999999999999}]}'"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job.result()"
]
@@ -173,7 +227,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.16"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/running/notebooks/05_retrieving_past_results.ipynb b/docs/getting_started/basic/05_retrieving_past_results.ipynb
similarity index 63%
rename from docs/running/notebooks/05_retrieving_past_results.ipynb
rename to docs/getting_started/basic/05_retrieving_past_results.ipynb
index 4dff7d800..be2704a76 100644
--- a/docs/running/notebooks/05_retrieving_past_results.ipynb
+++ b/docs/getting_started/basic/05_retrieving_past_results.ipynb
@@ -10,35 +10,30 @@
"In this tutorial, we will run two programs and then retrieve the results of each program using the job IDs and the serverless client."
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "81dd7807-7180-4b87-bbf9-832b7cf29d69",
- "metadata": {},
- "outputs": [],
- "source": [
- "from quantum_serverless import QuantumServerless, Provider\n",
- "import os"
- ]
- },
{
"cell_type": "markdown",
"id": "37322958-a029-46bb-bc46-82b7ded329b5",
"metadata": {},
"source": [
- "First, create [Provider](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.Provider.html#quantum_serverless.core.Provider) and [QuantumServerless](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.QuantumServerless.html#quantum_serverless.QuantumServerless) instances."
+ "First, create [Provider](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.Provider.html#quantum_serverless.core.Provider) and [QuantumServerless](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.QuantumServerless.html#quantum_serverless.QuantumServerless) instances.\n",
+ "\n",
+ "> ⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on [local infrastructure setup](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "acdec789-4967-48ee-8f6c-8d2b0ff57e91",
"metadata": {},
"outputs": [],
"source": [
+ "from quantum_serverless import QuantumServerless, Provider\n",
+ "import os\n",
+ "\n",
"provider = Provider(\n",
- " username=\"user\",\n",
- " password=\"password123\",\n",
+ " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n",
+ " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n",
+ " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n",
" host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n",
")\n",
"\n",
@@ -55,7 +50,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "d51df836-3f22-467c-b637-5803145d5d8a",
"metadata": {},
"outputs": [],
@@ -63,14 +58,10 @@
"from quantum_serverless import Program\n",
"\n",
"program1 = Program(\n",
- " title=\"Program 1\",\n",
- " entrypoint=\"program_1.py\",\n",
- " working_dir=\"./source_files/\"\n",
+ " title=\"Program 1\", entrypoint=\"program.py\", working_dir=\"./source_files/\"\n",
")\n",
"program2 = Program(\n",
- " title=\"Program 2\",\n",
- " entrypoint=\"program_2.py\",\n",
- " working_dir=\"./source_files/\"\n",
+ " title=\"Program 2\", entrypoint=\"program.py\", working_dir=\"./source_files/\"\n",
")\n",
"\n",
"job1 = serverless.run(program1)\n",
@@ -87,7 +78,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"id": "f621f786-6ba7-4ef1-8121-741f21f70233",
"metadata": {},
"outputs": [],
@@ -106,10 +97,21 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"id": "cc7ccea6-bbae-4184-ba7f-67b6c20a0b0b",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'[{\"0\": 0.4999999999999999, \"3\": 0.4999999999999999}]'"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"job1.result()\n",
"job2.result()"
@@ -125,7 +127,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"id": "1dc78690-f61a-4dfe-bc0e-7007cf561a5b",
"metadata": {},
"outputs": [],
@@ -144,10 +146,19 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"id": "ca1cbfee-df32-4306-988f-ef0fa31605ee",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Job 1 results: [{\"0\": 0.4999999999999999, \"3\": 0.4999999999999999}]\n",
+ "Job 2 results: [{\"0\": 0.4999999999999999, \"3\": 0.4999999999999999}]\n"
+ ]
+ }
+ ],
"source": [
"print(f\"Job 1 results: {retrieved_job1.result()}\")\n",
"print(f\"Job 2 results: {retrieved_job2.result()}\")"
@@ -163,13 +174,54 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 7,
"id": "5e39caf1-1506-44de-9fbc-248e106be6b5",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Job 1 logs: Running program 1...\n",
+ "Completed running program 1.\n",
+ "\n"
+ ]
+ }
+ ],
"source": [
"print(f\"Job 1 logs: {retrieved_job1.logs()}\")"
]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "15983446-497e-487b-b92d-5c5096f911d7",
+ "metadata": {},
+ "source": [
+ "To get a list of all previously executed programs, use the `.get_jobs()` method of the `QuantumServerless` object. \n",
+ "The `get_jobs` method accepts 2 optional parameters, `limit` and `offset`, which control the size of returned results."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "53f63569-3b80-4ebe-a181-1aa5b3537a7f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[,\n",
+ " ]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "serverless.get_jobs(limit=2, offset=1)"
+ ]
}
],
"metadata": {
@@ -188,7 +240,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.16"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/getting_started/basic/images/widget.png b/docs/getting_started/basic/images/widget.png
new file mode 100644
index 000000000..cf7d9bacd
Binary files /dev/null and b/docs/getting_started/basic/images/widget.png differ
diff --git a/docs/development/examples/index.rst b/docs/getting_started/basic/index.rst
similarity index 100%
rename from docs/development/examples/index.rst
rename to docs/getting_started/basic/index.rst
diff --git a/docs/running/notebooks/source_files/circuit_utils.py b/docs/getting_started/basic/source_files/circuit_utils.py
similarity index 100%
rename from docs/running/notebooks/source_files/circuit_utils.py
rename to docs/getting_started/basic/source_files/circuit_utils.py
diff --git a/docs/running/notebooks/source_files/program_1.py b/docs/getting_started/basic/source_files/program.py
similarity index 54%
rename from docs/running/notebooks/source_files/program_1.py
rename to docs/getting_started/basic/source_files/program.py
index fa630dea8..ed50a2499 100644
--- a/docs/running/notebooks/source_files/program_1.py
+++ b/docs/getting_started/basic/source_files/program.py
@@ -3,16 +3,20 @@
from quantum_serverless import save_result
-print("Running program 1...")
+# all print statement will be available in job logs
+print("Running program...")
+
+# creating circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
-circuit.draw()
+# running Sampler primitive
sampler = Sampler()
-
quasi_dists = sampler.run(circuit).result().quasi_dists
+# saves results of program execution,
+# which will be accessible by calling `.result()`
save_result(quasi_dists)
-print("Completed running program 1.")
\ No newline at end of file
+print("Completed running program.")
diff --git a/docs/running/notebooks/source_files/program_3.py b/docs/getting_started/basic/source_files/program_with_arguments.py
similarity index 89%
rename from docs/running/notebooks/source_files/program_3.py
rename to docs/getting_started/basic/source_files/program_with_arguments.py
index 7bd033970..9f5d73c65 100644
--- a/docs/running/notebooks/source_files/program_3.py
+++ b/docs/getting_started/basic/source_files/program_with_arguments.py
@@ -17,6 +17,4 @@
print(f"Quasi distribution: {quasi_dists[0]}")
# saving results of a program
-save_result({
- "quasi_dists": quasi_dists[0]
-})
+save_result({"quasi_dists": quasi_dists[0]})
diff --git a/docs/running/notebooks/source_files/program_4.py b/docs/getting_started/basic/source_files/program_with_dependencies.py
similarity index 75%
rename from docs/running/notebooks/source_files/program_4.py
rename to docs/getting_started/basic/source_files/program_with_dependencies.py
index 95c318f5e..6f4c73169 100644
--- a/docs/running/notebooks/source_files/program_4.py
+++ b/docs/getting_started/basic/source_files/program_with_dependencies.py
@@ -10,11 +10,7 @@
circuit = arguments.get("circuit")
-rb = StandardRB(
- physical_qubits=(1,),
- lengths=list(range(1, 300, 30)),
- seed=42
-)
+rb = StandardRB(physical_qubits=(1,), lengths=list(range(1, 300, 30)), seed=42)
composed = circuit.compose(rb.circuits()[0])
sampler = Sampler()
@@ -24,6 +20,4 @@
print(f"Quasi distribution: {quasi_dists[0]}")
# saving results of a program
-save_result({
- "quasi_dists": quasi_dists[0]
-})
+save_result({"quasi_dists": quasi_dists[0]})
diff --git a/docs/running/notebooks/source_files/program_2.py b/docs/getting_started/basic/source_files/program_with_parallel_workflow.py
similarity index 69%
rename from docs/running/notebooks/source_files/program_2.py
rename to docs/getting_started/basic/source_files/program_with_parallel_workflow.py
index 142d3f956..d6c776a9b 100644
--- a/docs/running/notebooks/source_files/program_2.py
+++ b/docs/getting_started/basic/source_files/program_with_parallel_workflow.py
@@ -1,4 +1,4 @@
-# source_files/program_2.py
+# source_files/program_with_parallel_workflow.py
from quantum_serverless import get_arguments, save_result, distribute_task, get
@@ -6,26 +6,21 @@
from qiskit.primitives import Sampler
from qiskit.circuit.random import random_circuit
+
@distribute_task()
def distributed_sample(circuit: QuantumCircuit):
"""Distributed task that returns quasi distribution for given circuit."""
return Sampler().run(circuit).result().quasi_dists[0]
-circuits = [random_circuit(2, 2) for _ in range(3)]
-[circuit.measure_all() for circuit in circuits]
-
+arguments = get_arguments()
+circuits = arguments.get("circuits")
# run distributed tasks as async function
# we get task references as a return type
-sample_task_references = [
- distributed_sample(circuit)
- for circuit in circuits
-]
+sample_task_references = [distributed_sample(circuit) for circuit in circuits]
# now we need to collect results from task references
results = get(sample_task_references)
-save_result({
- "results": results
-})
+save_result({"results": results})
diff --git a/docs/development/guides/08_file_download.ipynb b/docs/getting_started/experimental/experimental_file_download.ipynb
similarity index 91%
rename from docs/development/guides/08_file_download.ipynb
rename to docs/getting_started/experimental/experimental_file_download.ipynb
index f1661fb36..c4b55b71f 100644
--- a/docs/development/guides/08_file_download.ipynb
+++ b/docs/getting_started/experimental/experimental_file_download.ipynb
@@ -16,7 +16,9 @@
"> Limitations:\n",
"> - only `tar` files are supported\n",
"> - `tar` file should be saved in `/data` directory during your program execution to be visible by `.files()` method call\n",
- "> - only `/data` directory is supported, `/data/other_folder` will not be visible"
+ "> - only `/data` directory is supported, `/data/other_folder` will not be visible\n",
+ "\n",
+ "> ⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on [local infrastructure setup](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)."
]
},
{
@@ -84,9 +86,7 @@
],
"source": [
"program = Program(\n",
- " title=\"File producer\",\n",
- " entrypoint=\"produce_files.py\",\n",
- " working_dir=\"./src/\"\n",
+ " title=\"File producer\", entrypoint=\"produce_files.py\", working_dir=\"./source_files/\"\n",
")\n",
"\n",
"job = serverless.run(program)\n",
@@ -188,7 +188,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.16"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/running/notebooks/06_running_programs_using_decorators.ipynb b/docs/getting_started/experimental/experimental_running_programs_using_decorators.ipynb
similarity index 94%
rename from docs/running/notebooks/06_running_programs_using_decorators.ipynb
rename to docs/getting_started/experimental/experimental_running_programs_using_decorators.ipynb
index c7c0b8ec2..0ab73b97e 100644
--- a/docs/running/notebooks/06_running_programs_using_decorators.ipynb
+++ b/docs/getting_started/experimental/experimental_running_programs_using_decorators.ipynb
@@ -5,7 +5,7 @@
"id": "f6fb114d-af27-4a89-83b4-b3806dfa8c1a",
"metadata": {},
"source": [
- "# Running program using decorators [Experimental] \n",
+ "# Running program using decorators (Experimental)\n",
"\n",
"In this tutorial we will describe alternative way (interface) of running your programs.\n",
"\n",
@@ -18,7 +18,8 @@
"> 1. functions decorated with distribute_program, can only accept named arguments for now. E.g do not use `my_program(argument1)`, instead specify name of the argument `my_program(argument1=argument1)`\n",
"> 2. function return will run `quantum_serverless.save_result` function under the hood, which means return values must be json serializable values in form of dictionary (with values as all Python native types, like strings, lists, dicts, `numpy` arrays, `QuantumCircuit`, `Operator`, etc.)\n",
"> 3. when using local folder/modules user must specify `working_dir` as `./` (current folder), which will be archiving and sending content of entire folder for remote execution. Make sure that folder does not have large files. \n",
- "\n"
+ "\n",
+ "> ⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on [local infrastructure setup](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)."
]
},
{
@@ -97,7 +98,8 @@
" quasi_dists = sampler.run(circuit).result().quasi_dists\n",
"\n",
" return quasi_dists\n",
- " \n",
+ "\n",
+ "\n",
"job = hello_qiskit()\n",
"job"
]
@@ -165,13 +167,11 @@
"\n",
"@distribute_program(provider)\n",
"def program_with_distributed_tasks(circuits):\n",
- " sample_task_references = [\n",
- " distributed_sample(circuit)\n",
- " for circuit in circuits\n",
- " ]\n",
+ " sample_task_references = [distributed_sample(circuit) for circuit in circuits]\n",
" results = get(sample_task_references)\n",
" print(results)\n",
"\n",
+ "\n",
"circuits = []\n",
"for _ in range(3):\n",
" circuit = random_circuit(2, 2)\n",
@@ -245,12 +245,12 @@
"\n",
"from source_files.circuit_utils import create_hello_world_circuit\n",
"\n",
+ "\n",
"@distribute_program(provider, working_dir=\"./\")\n",
"def my_program_with_modules():\n",
" quasi_dists = Sampler().run(create_hello_world_circuit()).result().quasi_dists\n",
- " return {\n",
- " \"quasi_dists\": quasi_dists\n",
- " } \n",
+ " return {\"quasi_dists\": quasi_dists}\n",
+ "\n",
"\n",
"job = my_program_with_modules()\n",
"job"
@@ -294,7 +294,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.16"
+ "version": "3.10.13"
}
},
"nbformat": 4,
diff --git a/docs/development/guides/index.rst b/docs/getting_started/experimental/index.rst
similarity index 100%
rename from docs/development/guides/index.rst
rename to docs/getting_started/experimental/index.rst
diff --git a/docs/getting_started/experimental/source_files/circuit_utils.py b/docs/getting_started/experimental/source_files/circuit_utils.py
new file mode 100644
index 000000000..0408d2df7
--- /dev/null
+++ b/docs/getting_started/experimental/source_files/circuit_utils.py
@@ -0,0 +1,9 @@
+from qiskit import QuantumCircuit
+
+
+def create_hello_world_circuit() -> QuantumCircuit:
+ circuit = QuantumCircuit(2)
+ circuit.h(0)
+ circuit.cx(0, 1)
+ circuit.measure_all()
+ return circuit
diff --git a/docs/development/guides/src/produce_files.py b/docs/getting_started/experimental/source_files/produce_files.py
similarity index 100%
rename from docs/development/guides/src/produce_files.py
rename to docs/getting_started/experimental/source_files/produce_files.py
diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst
new file mode 100644
index 000000000..2c422a86a
--- /dev/null
+++ b/docs/getting_started/index.rst
@@ -0,0 +1,19 @@
+===============
+Getting started
+===============
+
+This section includes guides for using the basic features of Quantum Serverless to run a program remotely.
+
+**Basic Usage**
+
+.. toctree::
+ :maxdepth: 2
+
+ Basic Usage
+
+**Experimental Features**
+
+.. toctree::
+ :maxdepth: 2
+
+ Experimental
diff --git a/docs/index.rst b/docs/index.rst
index a5f4bb278..40700c112 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -25,9 +25,10 @@ system and receive the results when they are ready.
:maxdepth: 2
About Quantum Serverless
- Quickstart
- Running
- Development
+ Installation
+ Getting started
+ Examples
+ Migration guides
Deployment
.. toctree::
diff --git a/docs/installation/index.rst b/docs/installation/index.rst
new file mode 100644
index 000000000..9a3c6063c
--- /dev/null
+++ b/docs/installation/index.rst
@@ -0,0 +1,39 @@
+============
+Installation
+============
+
+Step 0 [Optional]: Pre-Installation
+
+.. code-block::
+ :caption: Create a minimal environment with only Python installed in it. We recommend using `Python virtual environments `_.
+
+ python3 -m venv /path/to/virtual/environment
+
+.. code-block::
+ :caption: Activate your new environment.
+
+ source /path/to/virtual/environment/bin/activate
+
+.. code-block::
+ :caption: Note: If you are using Windows, use the following commands in PowerShell.
+
+ python3 -m venv c:\path\to\virtual\environment
+ c:\path\to\virtual\environment\Scripts\Activate.ps1
+
+.. code-block::
+ :caption: Clone the Quantum Serverless repository.
+
+ cd /path/to/workspace/
+ git clone git@github.com:Qiskit-Extensions/quantum-serverless.git
+
+Step 1: Install the quantum serverless package.
+
+.. code-block::
+ :caption: Install quantum_serverless via pip.
+
+ pip install --upgrade pip
+ pip install quantum_serverless
+
+
+Note: if you want to deploy your own infrastructure locally or in cloud environment, refer to this document :doc:`/deployment/local`.
+
diff --git a/docs/running/notebooks/index.rst b/docs/migration/index.rst
similarity index 50%
rename from docs/running/notebooks/index.rst
rename to docs/migration/index.rst
index b7aba0a31..9fe5ef7f4 100644
--- a/docs/running/notebooks/index.rst
+++ b/docs/migration/index.rst
@@ -1,3 +1,7 @@
+=========
+Migration
+=========
+
.. nbgallery::
:glob:
diff --git a/docs/migration/migration_from_qiskit_runtime_programs.ipynb b/docs/migration/migration_from_qiskit_runtime_programs.ipynb
new file mode 100644
index 000000000..710cb5f0a
--- /dev/null
+++ b/docs/migration/migration_from_qiskit_runtime_programs.ipynb
@@ -0,0 +1,234 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "7d054012-24ae-4249-8263-ba857939e9ca",
+ "metadata": {},
+ "source": [
+ "# Converting from Qiskit Runtime Programs\n",
+ "\n",
+ "This tutorial will be a demonstation of converting your custom Qiskit Runtime Program into a Quantum Serverless `Program`.\n",
+ "\n",
+ "If you were using Qiskit Runtime Programs before, your code probably looks similar to the following example:\n",
+ "\n",
+ "```python\n",
+ "\"\"\"A sample runtime program that submits random circuits for user-specified iterations.\"\"\"\n",
+ "\n",
+ "import random\n",
+ "\n",
+ "from qiskit import transpile\n",
+ "from qiskit.circuit.random import random_circuit\n",
+ "\n",
+ "\n",
+ "def prepare_circuits(backend):\n",
+ " circuit = random_circuit(\n",
+ " num_qubits=5, depth=4, measure=True, seed=random.randint(0, 1000)\n",
+ " )\n",
+ " return transpile(circuit, backend)\n",
+ "\n",
+ "\n",
+ "def main(backend, user_messenger, **kwargs):\n",
+ " \"\"\"Main entry point of the program.\n",
+ "\n",
+ " Args:\n",
+ " backend: Backend to submit the circuits to.\n",
+ " user_messenger: Used to communicate with the program consumer.\n",
+ " kwargs: User inputs.\n",
+ " \"\"\"\n",
+ " iterations = kwargs.pop(\"iterations\", 5)\n",
+ " for it in range(iterations):\n",
+ " qc = prepare_circuits(backend)\n",
+ " result = backend.run(qc).result()\n",
+ " user_messenger.publish({\"iteration\": it, \"counts\": result.get_counts()})\n",
+ "\n",
+ " return \"Hello, World!\"\n",
+ "```\n",
+ "\n",
+ "\n",
+ "All Qiskit Runtime Programs have a `main` method which accepts `backend`, `user_messenger` and `**kwargs`. This method is not required for Quantum Serverless programs.\n",
+ "\n",
+ "Quantum Serverless handles backends, logging, and input arguments a bit differently than Qiskit Runtime:\n",
+ "- `backend`. For Quantum Serverless programs you are not limited to single backend for a program. You can call any number of backends from single program. Since `Backend.run` is deprecated, we will be using Qiskit Primitives to do our calculation.\n",
+ "- `user_messenger` were used in Qiskit Runtime Programs to facilitate retrieving logs from the program. Quantum Serverless does not require passing such an object. Instead, all contents of `stdout` (e.g. print statements, logging messages) will be provided to the user via the Quantum Serverless job handler.\n",
+ "- `**kwargs` was a variable used to capture program inputs from the user. Users should now input their arguments to the `Program` constructor, and the arguments should be retrieved within the program using the `get_arguments` function from Quantum Serverless.\n",
+ "- To save the results of a program, the `save_result` function should be used. It accepts a python dictionary and can be accessed via the job handler.\n",
+ "\n",
+ "Let's use the guidelines above to transform the above Qiskit Runtime Program into a Quantum Serverless Program.\n",
+ "\n",
+ "```python\n",
+ "# migrated_program.py\n",
+ "\"\"\"A sample runtime program that submits random circuits for user-specified iterations.\"\"\"\n",
+ "\n",
+ "import random\n",
+ "\n",
+ "from qiskit import transpile\n",
+ "from qiskit.circuit.random import random_circuit\n",
+ "from qiskit.primitives import Sampler\n",
+ "\n",
+ "from quantum_serverless import get_arguments, save_result\n",
+ "\n",
+ "\n",
+ "def prepare_circuits():\n",
+ " circuit = random_circuit(\n",
+ " num_qubits=5, depth=4, measure=True, seed=random.randint(0, 1000)\n",
+ " )\n",
+ " return transpile(circuit)\n",
+ "\n",
+ "\n",
+ "arguments = get_arguments()\n",
+ "iterations = arguments.get(\"iterations\", 5)\n",
+ "\n",
+ "for it in range(iterations):\n",
+ " qc = prepare_circuits()\n",
+ " result = Sampler.run(qc).result()\n",
+ " print({\"iteration\": it, \"dists\": result.quasi_dists})\n",
+ "\n",
+ "save_result({\"result\": \"Hello, World!\"})\n",
+ "```\n",
+ "\n",
+ "Let's save this code as `./src/migrated_program.py` and execute it using the `Program` class from the `quantum_serverless` package."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "50fb2a64-751d-40fb-bac8-db49dc92fbca",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from quantum_serverless import Program\n",
+ "\n",
+ "program = Program(\n",
+ " title=\"Migrated program\", entrypoint=\"migrated_program.py\", working_dir=\"./src/\"\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "162c482e-8f86-4224-a9b9-f6567b34acf4",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from quantum_serverless import QuantumServerless, Provider\n",
+ "import os\n",
+ "\n",
+ "provider = Provider(\n",
+ " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n",
+ " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n",
+ " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n",
+ " host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n",
+ ")\n",
+ "\n",
+ "serverless = QuantumServerless(provider)\n",
+ "serverless"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "31e22bdd-2625-494a-a697-b1e26fcd066a",
+ "metadata": {},
+ "source": [
+ "While Qiskit Runtime programs required users to upload their program and call it in two separate steps, the ``Program`` class allows users to send a job for remote execution in a single step."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "9f6eddae-a889-4958-8f0a-7e9f8ec29800",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "job = serverless.run(program, arguments={\"iterations\": 3})\n",
+ "job"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "2223b57b-1dbc-45c7-8fd6-8e2ebfb843aa",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'{\"result\": \"Hello, World!\"}'"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "job.result()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "314e7716-8495-41e0-92dc-b2404ec860d4",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k\n",
+ "OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k\n",
+ "{'iteration': 0, 'dists': [{8: 0.0044464220610969, 9: 0.0714788704988803, 10: 0.0025387094251744, 11: 0.0408112589724704, 12: 0.0044464220610969, 13: 0.0714788704988803, 14: 0.0025387094251744, 15: 0.0408112589724704, 24: 0.0323482396235251, 25: 0.2100040886340835, 26: 0.018469407467762, 27: 0.1199030033170077, 28: 0.0323482396235251, 29: 0.2100040886340835, 30: 0.018469407467762, 31: 0.1199030033170077}]}\n",
+ "{'iteration': 1, 'dists': [{0: 0.0029658828912998, 1: 0.0237036789902499, 4: 0.0150644475889747, 5: 0.1203968069211296, 8: 0.0061806907129902, 9: 0.0493967948055204, 10: 0.0035529476369869, 11: 0.0283955683157122, 12: 0.0313932460322799, 13: 0.2508984520575557, 14: 0.0144443775915554, 15: 0.1154411358076723, 16: 2.64895095504e-05, 17: 0.0002117072231119, 20: 6.5157421817e-06, 21: 5.20745648832e-05, 24: 5.52022691625e-05, 25: 0.0004411829177743, 26: 0.0074040922276745, 27: 0.0591743611636965, 28: 1.35783470443e-05, 29: 0.0001085197195414, 30: 0.0301010639013888, 31: 0.2405711830620639}]}\n",
+ "{'iteration': 2, 'dists': [{0: 0.0039688421058765, 1: 0.1105278404952374, 2: 0.0010364406823262, 3: 0.0288637207938572, 8: 0.2163089101542446, 9: 0.0656597293669953, 10: 0.0564878492146483, 11: 0.0171466671868148, 16: 0.0053863259939914, 17: 0.1091103566071225, 18: 0.0014066085874713, 19: 0.0284935528887121, 24: 0.2177263940423595, 25: 0.0642422454788804, 26: 0.0568580171197935, 27: 0.0167764992816696}]}\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(job.logs())"
+ ]
+ }
+ ],
+ "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.10.13"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/migration/src/migrated_program.py b/docs/migration/src/migrated_program.py
new file mode 100644
index 000000000..a184534bf
--- /dev/null
+++ b/docs/migration/src/migrated_program.py
@@ -0,0 +1,27 @@
+"""A sample runtime program that submits random circuits for user-specified iterations."""
+
+import random
+
+from qiskit import transpile
+from qiskit.circuit.random import random_circuit
+from qiskit.primitives import Sampler
+
+from quantum_serverless import get_arguments, save_result
+
+
+def prepare_circuits():
+ circuit = random_circuit(
+ num_qubits=5, depth=4, measure=True, seed=random.randint(0, 1000)
+ )
+ return transpile(circuit)
+
+
+arguments = get_arguments()
+iterations = arguments.get("iterations", 5)
+
+for it in range(iterations):
+ qc = prepare_circuits()
+ result = Sampler().run([qc]).result()
+ print({"iteration": it, "dists": result.quasi_dists})
+
+save_result({"result": "Hello, World!"})
diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst
deleted file mode 100644
index 24c974a85..000000000
--- a/docs/quickstart/index.rst
+++ /dev/null
@@ -1,159 +0,0 @@
-==========
-Quickstart
-==========
-
-.. note::
-
- These instructions describe a fully local workflow. To run on remote
- resources, users may either `configure their resources themselves `_ or ask
- their provider or dev ops team.
-
-Step 0 [Optional]: Pre-Installation
-
-.. code-block::
- :caption: Create a minimal environment with only Python installed in it. We recommend using `Python virtual environments `_.
-
- python3 -m venv /path/to/virtual/environment
-
-.. code-block::
- :caption: Activate your new environment.
-
- source /path/to/virtual/environment/bin/activate
-
-.. code-block::
- :caption: Note: If you are using Windows, use the following commands in PowerShell.
-
- python3 -m venv c:\path\to\virtual\environment
- c:\path\to\virtual\environment\Scripts\Activate.ps1
-
-.. code-block::
- :caption: Clone the Quantum Serverless repository.
-
- cd /path/to/workspace/
- git clone git@github.com:Qiskit-Extensions/quantum-serverless.git
-
-Step 1: Install Docker.
-
- If Docker is not installed on your system, following the directions
- on the `Docker website `_ to install Docker on your system.
-
-Step 2: Stop any running jupyter notebook servers.
-
-Step 3: Install the quantum serverless package.
-
-.. code-block::
- :caption: Install quantum_serverless via pip.
-
- pip install --upgrade pip
- pip install quantum_serverless
-
-
-Step 4: Run infrastructure.
-
-.. code-block::
- :caption: Run docker compose from the root of the quantum serverless project.
-
- cd quantum-serverless/
- docker compose --profile jupyter up
-
-Step 5: Open the jupyter lab environment by going to ``localhost:8888``. The default token is ``123``.
-
-Step 6: Write your program in containerized environment.
-
-.. code-block::
- :caption: Create a Python file using a text editor. Here we use vim.
-
- vim program.py
-
-.. code-block:: python
- :caption: program.py
-
- from quantum_serverless import distribute_task, get, get_arguments, save_result
-
- from qiskit import QuantumCircuit
- from qiskit.circuit.random import random_circuit
- from qiskit.primitives import Sampler
- from qiskit.quantum_info import SparsePauliOp
-
- # 1. Define a distributed function using the `distribute_task` decorator
- @distribute_task()
- def distributed_sample(circuit: QuantumCircuit):
- """Calculates quasi dists as a distributed function."""
- return Sampler().run(circuit).result().quasi_dists[0]
-
-
- # 2. Get the program arguments using `get_arguments`
- arguments = get_arguments()
- circuits = arguments.get("circuits", [])
-
- # 3. Run the distributed function for each circuit in parallel and get execution references
- function_references = [
- distributed_sample(circuit)
- for circuit in circuits
- ]
-
- # 4. Collect all results using `get`
- collected_results = get(function_references)
-
- # 5. Save the results using `save_result`
- save_result({
- "quasi_dists": collected_results
- })
-
-Step 5: Run the program.
-
-.. code-block:: python
- :caption: in jupyter notebook
-
- from quantum_serverless import QuantumServerless, Provider, Program
- from qiskit.circuit.random import random_circuit
-
- serverless = QuantumServerless(Provider(
- username="user", # this username has already been defined in local docker setup and does not need to be changed
- password="password123", # this password has already been defined in local docker setup and does not need to be changed
- host="http://gateway:8000", # address of provider
- ))
-
- # create program
- program = Program(
- title="Quickstart",
- entrypoint="program.py",
- working_dir="./" # or where your program file is located
- )
-
- # create inputs to our program
- circuits = []
- for _ in range(3):
- circuit = random_circuit(3, 2)
- circuit.measure_all()
- circuits.append(circuit)
-
- # run program
- job = serverless.run(
- program=program,
- arguments={
- "circuits": circuits
- }
- )
-
-Step 6: Monitor the job status.
-
-.. code-block:: python
- :caption: in jupyter notebook
-
- job.status()
- #
-
- job.logs()
-
-Step 7: Get the results.
-
-.. code-block:: python
- :caption: in jupyter notebook
-
- job.result()
- # {"quasi_dists": [
- # {"0": 0.25, "1": 0.25, "2": 0.2499999999999999, "3": 0.2499999999999999},
- # {"0": 0.1512273969460124, "1": 0.0400459556274728, "6": 0.1693190975212014, "7": 0.6394075499053132},
- # {"0": 0.25, "1": 0.25, "4": 0.2499999999999999, "5": 0.2499999999999999}
- # ]}
diff --git a/docs/running/index.rst b/docs/running/index.rst
deleted file mode 100644
index 5cf5890e1..000000000
--- a/docs/running/index.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-=======
-Running
-=======
-
-This section contains a series of short examples that demonstrate how to run serverless programs and showcase the main features of this package.
-
-.. toctree::
- :maxdepth: 2
-
- Running
\ No newline at end of file
diff --git a/docs/running/notebooks/source_files/__init__.py b/docs/running/notebooks/source_files/__init__.py
deleted file mode 100644
index e69de29bb..000000000