{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Getting Started with `qnexus`\n", "\n", "Here is an example notebook outlining core usage of qnexus, the client Python package for Quantinuum Nexus.\n", "\n", "qnexus can be installed with:\n", "\n", "```bash\n", "pip install qnexus\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from datetime import datetime\n", "from pytket import Circuit\n", "import qnexus as qnx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we'll call `login()` to authenticate the client using your web browser.\n", "\n", "**NB**: this step doesn't need to be done in the Nexus Lab, where authentication is automatic." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "qnx.login()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nexus uses Projects to organise data and jobs. Here we'll get a project in Nexus, or create it if it doesn't exist. We can also use 'properties' to annotate our jobs and data with labels or scientific parameters.\n", "\n", "[Learn more about Projects and properties in qnexus.](projects_properties_context.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_project_ref = qnx.projects.get_or_create(name=\"My Project\")\n", "\n", "my_project_ref.df()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The thing we get back is a `ProjectRef`; `qnexus` uses `Ref`s as 'references' to data in the Quantinuum Nexus database.\n", "\n", "Next we'll create a Pytket circuit and upload it to the Nexus database, getting back a `CircuitRef` for the uploaded circuit. We'll need to also pass the ProjectRef from earlier to upload the circuit as part of the Project." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "circuit = Circuit(2).H(0).CX(0,1).measure_all()\n", "\n", "my_circuit_ref = qnx.circuits.upload(\n", " name=f\"My Circuit from {datetime.now()}\",\n", " circuit = circuit,\n", " project = my_project_ref,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can then get Nexus to compile the circuit (using Quantinuum's TKET compiler), optimizing and rebasing it for a particular device. This will create a Nexus compile Job, wait for it to complete and fetch the compiled circuit.\n", "\n", "[Learn more about Jobs in qnexus.](jobs_results.ipynb)\n", "\n", "We'll get back a list containing a single `CircuitRef` pointing to the compiled circuit stored in Nexus." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "compiled_circuits = qnx.compile(\n", " circuits=[my_circuit_ref],\n", " name=f\"My Compile Job from {datetime.now()}\",\n", " optimisation_level=1,\n", " backend_config=qnx.QuantinuumConfig(device_name=\"H1-1LE\"),\n", " project=my_project_ref,\n", ")\n", "\n", "compiled_circuits.df()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This particular job compiled the circuit for Quantinuum's H1-1LE device, a noiseless simulator for Quantinuum's `H1-1`.\n", "\n", "[Learn more about how to configure jobs to target specific devices in qnexus.](backend_configuration.ipynb)\n", "\n", "[Learn more about checking the devices you have access to in qnexus.](devices_credentials.ipynb)\n", "\n", "Next, we'll submit a request for Nexus to execute this circuit on `H1-1LE`.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "execute_job_ref = qnx.start_execute_job(\n", " circuits=compiled_circuits,\n", " name=f\"My Execute Job from {datetime.now()}\",\n", " n_shots=[100]* len(compiled_circuits),\n", " backend_config=qnx.QuantinuumConfig(device_name=\"H1-1LE\"),\n", " project=my_project_ref,\n", ")\n", "\n", "execute_job_ref.df()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This will return an `ExecuteJobRef` as a reference to the running job in Nexus. If we believe the job will take a long time (hours or days), we can come back to this later either by retrieving the `ExecuteJobRef` using the API or by saving/loading it to the local filesystem.\n", "\n", "\n", "[Learn more about querying your data/jobs in qnexus.](refs_nexus_iterator.ipynb)\n", "\n", "[Learn more about saving and loading Ref objects in qnexus.](saving_refs.ipynb)\n", "\n", "We can check the status or wait for completion before retrieving the results." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(qnx.jobs.status(execute_job_ref))\n", "\n", "# Block until the job is complete\n", "qnx.jobs.wait_for(execute_job_ref)\n", "\n", "# Retrieve a ExecutionResultRef for every Circuit that was executed\n", "execute_job_result_refs = qnx.jobs.results(execute_job_ref)\n", "\n", "# Get a pytket BackendResult for the execution\n", "result = execute_job_result_refs[0].download_result()\n", "\n", "result.get_counts()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we'd like to share our work, we can grant access to team members using collaboration and role-based access control features.\n", "\n", "[Learn more about Access and Collaboration features in qnexus.](teams_roles.ipynb)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To put all of this together in a real-world example, please see our example of a variational quantum eigensolver workflow in qnexus.\n", "\n", "[VQE example in qnexus](vqe_example.ipynb)" ] } ], "metadata": { "kernelspec": { "display_name": "qnexus-Rou6F43i-py3.11", "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": 2 }