diff --git a/docs/api/functions/qunova-chemistry.mdx b/docs/api/functions/qunova-chemistry.mdx
index cf2cc742652e..a843cfd4c229 100644
--- a/docs/api/functions/qunova-chemistry.mdx
+++ b/docs/api/functions/qunova-chemistry.mdx
@@ -16,13 +16,26 @@ description: API reference for HI-VQE Chemistry, a Qiskit Function by Qunova Com
## Inputs
+Arguments are checked when you call `run()`, before a job is created: one with
+the wrong name, type or range raises an exception describing what failed, and
+nothing is billed. `function.validate_arguments({...})` runs the same check without
+running anything, and `function.arguments_schema` lists every argument with its
+type, range and default.
+
### `geometry`
This can be either a string or structured lists containing atom and coordinate pairs. If this is given as a string, it must be a molecule geometry in Cartesian Coordinate Format. If this is given as a list, it should be given as a list of lists that each contain an atom string and coordinate tuple.
-- Required: Yes
+- Required: Yes, unless `fcidump_file_name` is given
- Example: `[['O', (0, 0, 0)], ['H', (0, 1, 0)], ['H', (0, 0, 1)]]` or `"O 0 0 0; H 0 1 0; H 0 0 1"`
+### `fcidump_file_name`
+
+The name of an FCIDUMP file you uploaded to the function with `file_upload`, without a directory part, to use in place of `geometry`. The integrals of the file are used as they are, and `geometry` and `molecule_options` are ignored. The file can be plain text or gzip-compressed, and must describe a closed-shell singlet. See [Run from an FCIDUMP file](/docs/guides/qunova-chemistry#run-from-an-fcidump-file).
+- Required: Yes, unless `geometry` is given
+- Example: `"nh3.FCIDUMP"`
+
+
### `backend_name`
Name of the backend to make the query.
@@ -34,6 +47,7 @@ Name of the backend to make the query.
The maximum subspace dimension for the diagonalization. Fewer states will be used if the number is not a perfect square.
- Required: Yes
+- Valid range: Between 1 and 400 000 000
- Example: `100`
@@ -41,6 +55,7 @@ The maximum subspace dimension for the diagonalization. Fewer states will be use
The maximum number of classically-generated CI states to be included in each iteration.
- Required: Yes
+- Valid range: At least 1
- Example: `10`
@@ -63,19 +78,19 @@ A string specifying the basis type; these are passed to pyscf. For example: `"st
#### `active_orbitals`
-A list of active orbital indices in the interval [0, n) where n is the number of qubits used in the problem. If this is specified, then the frozen_orbitals argument must also be specified.
-- Valid range: The spatial orbital indices valid for the problem
+A list of active orbital indices in the interval [0, n) where n is the number of orbitals in the basis. If this is specified, then the frozen_orbitals argument must also be specified.
+- Valid range: The spatial orbital indices valid for the problem, each at most once
#### `frozen_orbitals`
A list of frozen orbital indices in the same range as active_orbitals. If specified, then active_orbitals must also be specified. Note that only occupied orbitals should be frozen as the number of active electrons is reduced by 2 for every occupied orbital that is frozen.
-- Valid range: The spatial orbital indices valid for the problem, excluding active orbitals
+- Valid range: The spatial orbital indices valid for the problem, excluding active orbitals, each at most once
#### `orbital_coeffs`
-
-The coefficients for the spatial orbitals used in the calculation of the electronic repulsion integrals for the system. Some valid examples are Hartree-Fock molecular orbitals, natural orbitals, and AVAS orbitals.
+
+The coefficients for the spatial orbitals used in the calculation of the electronic repulsion integrals for the system. Some valid examples are Hartree-Fock molecular orbitals, natural orbitals, and AVAS orbitals. Give a matrix as a list of equal-length rows or as a 2-D NumPy array, such as PySCF's `mo_coeff`.
- Valid range: Various
@@ -116,7 +131,7 @@ Specifies whether to use cartesian GTOs as the angular momentum basis functions
#### `magmom`
-
+
Sets the colinear spin magnetic moment of each atom. By default, this is None and each atom is initialized with a spin of zero.
- Valid range: See [pyscf documentation](https://pyscf.org/pyscf_api_docs/pyscf.gto.html#pyscf.gto.mole.MoleBase.build)
@@ -124,13 +139,12 @@ Sets the colinear spin magnetic moment of each atom. By default, this is None an
#### `avas_aolabels`
This defines Atomic Orbital to be included in AVAS scheme. See [AVAS documentation](https://arxiv.org/abs/1701.07862).
-- Valid range: i.e., ["H 1s", "O 2p"] for H$_2$O
+- Valid range: i.e., ["H 1s", "O 2p"] for H$_2$O, each label at most once
#### `avas_threshold`
This specifies the cutoff value used to determine which Atomic Orbitals (AOs) are retained in the active space.
-- Valid range: Between 0.0 and 2.0
#### `noons_level`
@@ -224,16 +238,47 @@ The tolerance for predicting which states should be screened out of the subspace
- Example: `{"shots": 10_000, "max_iter": 10 }`
-
-
+### `use_session`
+
+Runs the function's quantum jobs in one Qiskit Runtime session, so that jobs
+after the first do not wait in the queue again.
+- Required: No
+- Example: `True`
+
+
+### `function_size`
+
+Which resources the job runs on, and what the run is billed. It is passed to
+`run()` like the arguments above, though it belongs to the platform rather than
+to this function.
+
+| `function_size` | Qubits | Compute profile | Per-execution fee |
+|-----|-----|-----|-----|
+| `"s"` | Up to 10 | 8 CPUs, 32 GB | 0.4 RU |
+| `"m"` | Up to 20 | 16 CPUs, 128 GB | 1.0 RU |
+| `"l"` | More than 20 | 48 CPUs, 768 GB | 4.0 RU |
+
+A size smaller than the problem needs is rejected before any QPU time is
+spent, with error code 1221 naming the size to use; the rejected run is still
+billed at the size it was submitted at. A size larger than it needs runs, and
+is billed at that larger size. To check the size before submitting, see
+[Qubits your problem needs](/docs/guides/qunova-chemistry#qubits-your-problem-needs). With a license token,
+the size is checked the same way and sets the compute, and so the classical
+compute cost, but no per-execution fee is charged; the token also sets its own
+qubit limit.
+- Required: No
+- Example: `"l"`
+
## Outputs
-The function returns a dictionary with four keys and values. The keys and values are documented in the following table:
+The function returns a dictionary with the following keys and values:
| Key | Value Type| Explanation |
|-----|---------------|---------------------------------------------------------------------------------------------------------------------------|
| `"energy"` | `float` | The approximate ground state energy of the molecule. |
| `"results_file_name"` | `string` | The name of the hdf5 results file that can be downloaded using Qiskit Serverless. The file contains `"states"`, `"eigenvector"`, `"energy_history"`, `"final_energy"`, and `"final_energy_variance"`. |
| `"energy_variance"` | `float` | The energy variance of the ground state of the subspace composed of the `"states"` saved in the results file, giving an indication of the quality of the solution. This value is non-negative and a lower value means that the ground state of the subspace more closely approximates an eigenstate of the system's Hamiltonian. |
-| `"energy_history"` | `List[float]` | The energies computed each iteration during the hybrid optimization process, in the same order that they were computed. Two energies are computed per iteration as part of the SPSA optimization process. |
\ No newline at end of file
+| `"energy_history"` | `List[float]` | The energies computed each iteration during the hybrid optimization process, in the same order that they were computed. Two energies are computed per iteration as part of the SPSA optimization process. |
+| `"function_version"` | `string` | The version of the function that ran the job. Quote it in a support request. |
+| `"metadata"` | `dict` | Contains `"resource_usage"`, giving the time spent in each stage of the job, including QPU time. |
diff --git a/docs/guides/qunova-chemistry.ipynb b/docs/guides/qunova-chemistry.ipynb
index 11f3dc2dcda4..a95bf559d801 100644
--- a/docs/guides/qunova-chemistry.ipynb
+++ b/docs/guides/qunova-chemistry.ipynb
@@ -135,8 +135,26 @@
"source": [
"## Get started\n",
"\n",
- "First, [request access to the function](https://forms.office.com/r/zN3hvMTqJ1).\n",
- "Then, authenticate using your [IBM Quantum® API key](http://quantum.cloud.ibm.com/) and, assuming you've already [saved your account](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) to your local environment, select the Qiskit Function as follows:"
+ "### Ways to use HI-VQE\n",
+ "\n",
+ "You can use HI-VQE in one of two ways. Either way, the instance you\n",
+ "authenticate with needs [Qiskit Functions access\n",
+ "enabled](/docs/guides/access-instances-platform-apis#configure-qiskit-functions-access-on-an-instance),\n",
+ "or the function will not appear in the catalog.\n",
+ "\n",
+ "| | Usage-based | Licensed |\n",
+ "| --- | --- | --- |\n",
+ "| **How to start** | Run the function; there is nothing to sign up for | [Request a license](https://forms.office.com/r/zN3hvMTqJ1) from Qunova |\n",
+ "| **Qubits** | No limit | Set by your license |\n",
+ "| **What you pay** | A per-execution fee for the [function size](#function-sizes-and-billing) you choose, plus the QPU and classical compute time the run uses | Your license fee to Qunova, plus the QPU and classical compute time the run uses |\n",
+ "| **License token** | Not needed | Needed; see [Licensed use](#licensed-use) |\n",
+ "\n",
+ "The examples on this page are usage-based runs. With a license, only the way\n",
+ "you load the function changes.\n",
+ "\n",
+ "### Load the function\n",
+ "\n",
+ "Save your [IBM Quantum® API key](http://quantum.cloud.ibm.com/) [to your local environment](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) if you have not already, then select the Qiskit Function as follows:"
]
},
{
@@ -201,7 +219,7 @@
"id": "b03aa968",
"metadata": {},
"source": [
- "#### Define the molecular geometry and options\n",
+ "### Define the molecule\n",
"\n",
"The molecular geometry of NH3 is provided with Cartesian coordinates separated with \";\" for each atom."
]
@@ -227,7 +245,10 @@
"id": "64429e13",
"metadata": {},
"source": [
- "Additional options can be defined and provided for molecular system in the following dictionary format."
+ "Additional options can be defined and provided for molecular system in the following dictionary format.\n",
+ "For every option you can set, with its type, default and valid range, see\n",
+ "[`molecule_options`](/docs/api/functions/qunova-chemistry#molecule_options) and\n",
+ "[`hivqe_options`](/docs/api/functions/qunova-chemistry#hivqe_options) in the API reference."
]
},
{
@@ -242,12 +263,53 @@
"hivqe_options = {\"shots\": 100, \"max_iter\": 20}"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "3c7a91e2",
+ "metadata": {},
+ "source": [
+ "### Check the arguments\n",
+ "\n",
+ "Before running, you can check the arguments with `validate_arguments()`. It\n",
+ "checks their names, types and ranges against the function's argument schema\n",
+ "without creating a job, so it is free. It returns `{\"valid\": True}`, or raises\n",
+ "an exception describing what failed. `function.arguments_schema` shows every\n",
+ "argument the function accepts, with its type, range and default.\n",
+ "\n",
+ "This check does not cover the function size; see [Qubits your problem\n",
+ "needs](#qubits-your-problem-needs)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5d0b84f6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "function.validate_arguments(\n",
+ " {\n",
+ " \"geometry\": geometry,\n",
+ " \"backend_name\": backend_name,\n",
+ " \"max_states\": 2000,\n",
+ " \"max_expansion_states\": 10,\n",
+ " \"molecule_options\": molecule_options,\n",
+ " \"hivqe_options\": hivqe_options,\n",
+ " }\n",
+ ")"
+ ]
+ },
{
"cell_type": "markdown",
"id": "bf180336",
"metadata": {},
"source": [
- "Execute the function with geometry and option inputs."
+ "### Run the function\n",
+ "\n",
+ "Run the function with the geometry and options. NH3 has 8 orbitals in the\n",
+ "STO-3G basis, so the problem uses 16 qubits and fits the default function\n",
+ "size, `\"m\"`. A run is billed once it starts; see [Function sizes and\n",
+ "billing](#function-sizes-and-billing)."
]
},
{
@@ -260,9 +322,12 @@
"# Run HI-VQE\n",
"job = function.run(\n",
" geometry=geometry,\n",
- " # `backend_name` is the name of a backend with at least 16 qubits,\n",
+ " # `backend_name` is a backend you have access to,\n",
" # for example, \"ibm_marrakesh\".\n",
" backend_name=backend_name,\n",
+ " # `function_size` sets the resources the job runs on and what it\n",
+ " # costs. See \"Function sizes and billing\" below.\n",
+ " function_size=\"m\",\n",
" max_states=2000,\n",
" max_expansion_states=10,\n",
" molecule_options=molecule_options,\n",
@@ -296,19 +361,13 @@
"print(\"Job ID:\", job.job_id)"
]
},
- {
- "cell_type": "markdown",
- "id": "608cf736",
- "metadata": {},
- "source": [
- "This example then utilizes 16 qubits with 8 orbitals of sto3g basis for an NH3 molecule."
- ]
- },
{
"cell_type": "markdown",
"id": "ad1c9bcb",
"metadata": {},
"source": [
+ "### Get the results\n",
+ "\n",
"Check your Qiskit Function workload's [status](/docs/guides/functions-get-started#check-job-status) or return [results](/docs/guides/functions-get-started#retrieve-results) as follows:"
]
},
@@ -365,9 +424,21 @@
"id": "2b6fb05c",
"metadata": {},
"source": [
- "To access the ground state energy, use the `\"energy\"` key. The `\"results_file_name\"` key provides the name of the h5 results file that can be downloaded using `QiskitServerless`.\n",
+ "To access the ground state energy, use the `\"energy\"` key. The\n",
+ "`\"results_file_name\"` key provides the name of the h5 results file that can\n",
+ "be downloaded using `QiskitServerless`.\n",
"\n",
- "This file contains :\n",
+ "The response also carries:\n",
+ "- `\"energy_variance\"`: the energy variance of the final trial state, as a\n",
+ " single number,\n",
+ "- `\"energy_history\"`: the energies computed along the way, two per\n",
+ " iteration,\n",
+ "- `\"function_version\"`: the version of the function that ran the job, which\n",
+ " is worth quoting in a support request, and\n",
+ "- `\"metadata\"`: a `\"resource_usage\"` dictionary giving the time spent in\n",
+ " each stage of the job, including QPU time.\n",
+ "\n",
+ "The results file contains:\n",
"- `\"final_energy\"`: the energy of the final trial state,\n",
"- `\"final_energy_variance\"`: the energy variance of the final trial state,\n",
"- `\"energy_history\"`: the energy history over HI-VQE's training,\n",
@@ -403,6 +474,8 @@
"id": "03b51be7",
"metadata": {},
"source": [
+ "### Download the results file\n",
+ "\n",
"To download the results file for the calculation, you will need to create a `QiskitServerless` instance using the same credentials as `QiskitFunctionCatalog`."
]
},
@@ -454,22 +527,401 @@
" final_energy_variance = f[\"final_energy_variance\"][0]"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "32946cb4",
+ "metadata": {},
+ "source": [
+ "### Run from an FCIDUMP file\n",
+ "\n",
+ "Instead of a geometry, you can give the problem as an FCIDUMP file of its\n",
+ "integrals, for example one written by PySCF or by another quantum chemistry\n",
+ "program. Upload the file to the function, then pass its name as\n",
+ "`fcidump_file_name`:\n",
+ "\n",
+ "- The integrals are used as they are. No mean-field calculation is run, and\n",
+ " `geometry` and `molecule_options` are ignored if you pass them as well.\n",
+ "- Every orbital in the file is active, so the problem uses 2 × `NORB` qubits.\n",
+ "- The file can be plain text or gzip-compressed. Only closed-shell singlets\n",
+ " are supported: `MS2=0` and an even `NELEC`.\n",
+ "- The first `NELEC`/2 orbitals are taken as the occupied orbitals of the\n",
+ " reference state. If the orbitals of the file are not in order of energy,\n",
+ " the job log says so, as the run can converge slowly from that state.\n",
+ "\n",
+ "This writes the NH3 problem of the example to a file with PySCF, which you\n",
+ "can install with `pip install pyscf`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5d629f4a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from pyscf import gto, scf\n",
+ "from pyscf.tools import fcidump\n",
+ "\n",
+ "mol = gto.M(atom=geometry, basis=\"sto3g\")\n",
+ "fcidump.from_scf(scf.RHF(mol).run(), \"nh3.FCIDUMP\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b4173b97",
+ "metadata": {},
+ "source": [
+ "Upload the file and run. Pass the file name alone, without a directory. The\n",
+ "file stays uploaded until you remove it with `serverless.file_delete()`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4e574ac1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "serverless.file_upload(\"nh3.FCIDUMP\", function)\n",
+ "\n",
+ "job = function.run(\n",
+ " fcidump_file_name=\"nh3.FCIDUMP\",\n",
+ " backend_name=backend_name,\n",
+ " function_size=\"m\",\n",
+ " max_states=2000,\n",
+ " max_expansion_states=10,\n",
+ " hivqe_options=hivqe_options,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "30399da1",
+ "metadata": {},
+ "source": [
+ "## Function sizes and billing\n",
+ "\n",
+ "Every run is submitted at a function size, which sets the resources it runs\n",
+ "on and, for a usage-based run, its per-execution fee. The size is checked against\n",
+ "the problem with or without a license token."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "df5164aa-c7ca-438e-a414-f7f5a6795aa5",
+ "metadata": {},
+ "source": [
+ "### Sizes and fees\n",
+ "\n",
+ "Pass `function_size` to `run()` alongside the function's own arguments. If\n",
+ "you leave it out, the run uses `\"m\"`.\n",
+ "\n",
+ "| `function_size` | Qubits | Compute | Per-execution fee |\n",
+ "| --- | --- | --- | --- |\n",
+ "| `\"s\"` | Up to 10 | 8 CPUs, 32 GB | 0.4 RU |\n",
+ "| `\"m\"` | Up to 20 | 16 CPUs, 128 GB | 1.0 RU |\n",
+ "| `\"l\"` | More than 20 | 48 CPUs, 768 GB | 4.0 RU |\n",
+ "\n",
+ "A usage-based run costs its per-execution fee plus the QPU and classical compute\n",
+ "time it uses. Fees are given in resource units (RU); see [IBM Quantum\n",
+ "plans](/docs/guides/plans-overview) for what a resource unit costs on your\n",
+ "plan. With a license, you pay your license fee to Qunova in place of the\n",
+ "per-execution fee. The function size still sets the compute the run uses, and\n",
+ "so its classical compute cost."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6cf9a7ea",
+ "metadata": {},
+ "source": [
+ "### What is billed\n",
+ "\n",
+ "For a usage-based run:\n",
+ "\n",
+ "| What happens | Billed |\n",
+ "| --- | --- |\n",
+ "| You call `validate_arguments()` | No |\n",
+ "| You call `run()` with a wrong argument name, type or range | No. The call is refused before a job is created |\n",
+ "| The run completes | Yes |\n",
+ "| The run fails after it starts, for example on an invalid geometry | Yes |\n",
+ "| `function_size` is too small for the problem | Yes, at the size you chose. The run is rejected with error code 1221, naming the size to use, before any QPU time is spent |\n",
+ "| `function_size` is larger than needed | Yes, at the larger size. The run goes ahead, with a warning naming the size that would have been enough |\n",
+ "\n",
+ "A run with a license token at too small a size is rejected in the same way.\n",
+ "To get the size right the first time, work it out before you submit, as the\n",
+ "next two sections show."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5569c36e-04c2-453f-a7fd-89b36b9d0d7b",
+ "metadata": {},
+ "source": [
+ "### Qubits your problem needs\n",
+ "\n",
+ "HI-VQE represents each orbital of the active space with two qubits, one for\n",
+ "each electron spin:\n",
+ "\n",
+ "$$\n",
+ "\\text{qubits} = 2 \\times \\text{active orbitals}\n",
+ "$$\n",
+ "\n",
+ "By default, every orbital in the basis is active. You can choose a smaller\n",
+ "active space with\n",
+ "[`molecule_options`](/docs/api/functions/qunova-chemistry#molecule_options).\n",
+ "\n",
+ "For example, NH3 has 8 orbitals in the STO-3G basis, so the\n",
+ "[Example](#example) uses 2 × 8 = 16 qubits and fits `\"m\"`.\n",
+ "\n",
+ "To find the size for your own problem, use the [size estimator](#size-estimator)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9e2f4a17",
+ "metadata": {},
+ "source": [
+ "### Size estimator\n",
+ "\n",
+ "This is the same code the function uses to check a run's size, so the size it\n",
+ "gives is the one your run is checked at. It needs only PySCF\n",
+ "(`pip install pyscf`), submits nothing, and costs nothing. Open the code\n",
+ "below, then run it in a cell or save it as `hivqe_chemistry_size_estimator.py`.\n",
+ "You only need to call `estimate_size`; the rest of the code is how the size is\n",
+ "worked out.\n",
+ "\n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7a88635c-b4c0-4b8c-b1dd-faf369836b5c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\"\"\"Size estimator for Qunova HI-VQE Chemistry. Requires PySCF only.\n",
+ "\n",
+ "estimate_size(geometry, molecule_options=...) returns \"s\", \"m\" or \"l\" from the\n",
+ "number of qubits the problem needs: two per active orbital. The active space is\n",
+ "the orbitals AVAS selects if avas_aolabels is set, else active_orbitals if set,\n",
+ "else every orbital in the basis. With fcidump_file_name, the path of an FCIDUMP\n",
+ "file, it is every orbital of the file, and geometry and molecule_options are\n",
+ "ignored, as the function ignores them. Other inputs are accepted and ignored.\n",
+ "\"\"\"\n",
+ "from __future__ import annotations\n",
+ "\n",
+ "import gzip\n",
+ "import re\n",
+ "from typing import Any, Literal\n",
+ "\n",
+ "from pyscf import gto, scf\n",
+ "from pyscf.mcscf import avas\n",
+ "\n",
+ "Size = Literal[\"s\", \"m\", \"l\"]\n",
+ "_ORDER = {\"s\": 0, \"m\": 1, \"l\": 2}\n",
+ "\n",
+ "# Upper bounds (inclusive) on the number of qubits for each size.\n",
+ "_SMALL = 10\n",
+ "_MEDIUM = 20\n",
+ "\n",
+ "# The function's defaults for the molecule_options that decide the active space.\n",
+ "_DEFAULTS = {\n",
+ " \"active_orbitals\": None,\n",
+ " \"avas_aolabels\": None,\n",
+ " \"avas_threshold\": 0.2,\n",
+ " \"basis\": \"sto-3g\",\n",
+ " \"charge\": 0,\n",
+ " \"symmetry\": False,\n",
+ " \"symmetry_subgroup\": None,\n",
+ " \"unit\": \"angstrom\",\n",
+ " \"nucmod\": None,\n",
+ " \"pseudo\": None,\n",
+ " \"cart\": False,\n",
+ " \"magmom\": None,\n",
+ "}\n",
+ "\n",
+ "# AVAS weights below this are numerical noise; counting them would make the size vary\n",
+ "# from one call to the next.\n",
+ "_AVAS_WEIGHT_TOLERANCE = 1e-10\n",
+ "\n",
+ "\n",
+ "def estimate_size(problem: Any, **kwargs: Any) -> Size:\n",
+ " \"\"\"Return the size (\"s\", \"m\" or \"l\") required to run the function.\"\"\"\n",
+ " metrics = _measure(problem, **kwargs)\n",
+ " if _is_small(metrics):\n",
+ " return \"s\"\n",
+ " if _is_medium(metrics):\n",
+ " return \"m\"\n",
+ " return \"l\"\n",
+ "\n",
+ "\n",
+ "def _measure(problem: Any, **kwargs: Any) -> dict:\n",
+ " \"\"\"Return the number of qubits the run uses for this geometry and these options.\"\"\"\n",
+ " if kwargs.get(\"fcidump_file_name\"):\n",
+ " return {\n",
+ " \"num_qubits\": 2\n",
+ " * _fcidump_num_orbitals(kwargs[\"fcidump_file_name\"])\n",
+ " }\n",
+ " options = {**_DEFAULTS, **(kwargs.get(\"molecule_options\") or {})}\n",
+ " mol = gto.M(\n",
+ " atom=problem,\n",
+ " basis=options[\"basis\"],\n",
+ " spin=0, # the function runs singlets only\n",
+ " charge=options[\"charge\"],\n",
+ " symmetry=options[\"symmetry\"],\n",
+ " symmetry_subgroup=options[\"symmetry_subgroup\"],\n",
+ " unit=options[\"unit\"],\n",
+ " nucmod=options[\"nucmod\"],\n",
+ " pseudo=options[\"pseudo\"],\n",
+ " cart=options[\"cart\"],\n",
+ " magmom=options[\"magmom\"],\n",
+ " verbose=0,\n",
+ " )\n",
+ "\n",
+ " if options[\"avas_aolabels\"] is None:\n",
+ " # The active space is the orbitals given, or the whole basis; building the molecule\n",
+ " # is enough to know it.\n",
+ " if options[\"active_orbitals\"]:\n",
+ " return {\"num_qubits\": 2 * len(options[\"active_orbitals\"])}\n",
+ " return {\"num_qubits\": 2 * mol.nao_nr()}\n",
+ "\n",
+ " # AVAS picks the active space from an RHF, so it has to run one.\n",
+ " rhf = scf.RHF(mol)\n",
+ " rhf.verbose = 0\n",
+ " rhf.kernel()\n",
+ " selection = avas.AVAS(\n",
+ " mf=rhf,\n",
+ " aolabels=options[\"avas_aolabels\"],\n",
+ " threshold=max(options[\"avas_threshold\"], _AVAS_WEIGHT_TOLERANCE),\n",
+ " )\n",
+ " selection.verbose = 0\n",
+ " selection.kernel()\n",
+ " return {\"num_qubits\": 2 * selection.ncas}\n",
+ "\n",
+ "\n",
+ "# An FCIDUMP header is read up to its end (&END or /). It is a few lines; its\n",
+ "# only part that grows with the problem is ORBSYM, a few characters per orbital.\n",
+ "_FCIDUMP_MAX_HEADER_LINES = 1000\n",
+ "\n",
+ "\n",
+ "def _fcidump_num_orbitals(path: str) -> int:\n",
+ " \"\"\"NORB from the header of an FCIDUMP file, plain or gzip-compressed,\n",
+ " without reading the integrals.\"\"\"\n",
+ " with open(path, \"rb\") as raw:\n",
+ " gzipped = raw.read(2) == b\"\\x1f\\x8b\"\n",
+ " opener = gzip.open if gzipped else open\n",
+ " header = []\n",
+ " try:\n",
+ " with opener(path, \"rt\") as in_file:\n",
+ " for line_number, line in enumerate(in_file):\n",
+ " header.append(line.upper())\n",
+ " if \"&END\" in header[-1] or \"/\" in line:\n",
+ " break\n",
+ " if line_number >= _FCIDUMP_MAX_HEADER_LINES:\n",
+ " raise ValueError(\n",
+ " \"No end of header (&END or /) was found in the FCIDUMP file.\"\n",
+ " )\n",
+ " else:\n",
+ " raise ValueError(\n",
+ " \"No end of header (&END or /) was found in the FCIDUMP file.\"\n",
+ " )\n",
+ " except (UnicodeDecodeError, OSError, EOFError) as error:\n",
+ " raise ValueError(\n",
+ " \"The FCIDUMP file could not be read as text or as gzip-compressed text.\"\n",
+ " ) from error\n",
+ " match = re.search(r\"NORB\\s*=\\s*(\\d+)\", \"\".join(header))\n",
+ " if match is None or int(match.group(1)) < 1:\n",
+ " raise ValueError(\n",
+ " \"No valid NORB entry was found in the FCIDUMP file header.\"\n",
+ " )\n",
+ " return int(match.group(1))\n",
+ "\n",
+ "\n",
+ "def _is_small(metrics: dict) -> bool:\n",
+ " \"\"\"Determine if the metrics fit T-size 's'.\"\"\"\n",
+ " return metrics[\"num_qubits\"] <= _SMALL\n",
+ "\n",
+ "\n",
+ "def _is_medium(metrics: dict) -> bool:\n",
+ " \"\"\"Determine if the metrics fit T-size 'm'.\"\"\"\n",
+ " return metrics[\"num_qubits\"] <= _MEDIUM\n",
+ "\n",
+ "\n",
+ "def validate_size(provided_size: Size, problem: Any, **kwargs: Any) -> None:\n",
+ " \"\"\"Call at the start of the function. Raise if ``provided_size`` is smaller than\n",
+ " the estimated size; the estimated size or a larger one is accepted.\"\"\"\n",
+ " expected = estimate_size(problem, **kwargs)\n",
+ " if _ORDER[provided_size] < _ORDER[expected]:\n",
+ " raise ValueError(\n",
+ " f\"Size '{provided_size}' is too small for this problem; expected '{expected}' or larger.\"\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b71c3d58",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "\n",
+ "For the NH3 molecule in the [Example](#example):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "216827a3-35e1-4499-b924-6ec5b6b7af92",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# NH3 in STO-3G has 8 orbitals, so 16 qubits: \"m\"\n",
+ "print(estimate_size(geometry, molecule_options=molecule_options))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "80af2a86",
+ "metadata": {},
+ "source": [
+ "For an FCIDUMP file, pass its path as `fcidump_file_name`, as you will pass its\n",
+ "name to `run()`:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e20b4b85",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# nh3.FCIDUMP, written in \"Run from an FCIDUMP file\", has 8 orbitals: \"m\"\n",
+ "print(estimate_size(None, fcidump_file_name=\"nh3.FCIDUMP\"))"
+ ]
+ },
{
"cell_type": "markdown",
"id": "5f252348-720f-47c0-9e7f-ae5e5512b8d1",
"metadata": {},
"source": [
- "## Licensing\n",
+ "## Licensed use\n",
"\n",
- "Note that use of this Qiskit Function is limited to problems requiring at most 20 qubits, unless a license is obtained granting a higher limit.\n",
+ "### Get a license\n",
"\n",
- "Email [qiskit.support@qunovacomputing.com](mailto:qiskit.support@qunovacomputing.com) with license inquiries.\n",
+ "To request a license, fill in [this form](https://forms.office.com/r/zN3hvMTqJ1), or email\n",
+ "[qiskit.support@qunovacomputing.com](mailto:qiskit.support@qunovacomputing.com) with your inquiry.\n",
+ "Your license sets your qubit limit, and comes with a license token.\n",
"\n",
- "### Example of licensed function use\n",
+ "### Run with a license token\n",
"\n",
- "Licensed users are issued a license token, and then must use a wrapper library to submit their license token to the function.\n",
- "The wrapper library can be installed [from PyPI](https://pypi.org/project/hivqe-qiskit-function-utils/) with `pip install hivqe-qiskit-function-utils`.\n",
- "The below example shows how this library should be used to submit your license token when calling the function."
+ "Pass your license token to the function through the wrapper library, which you\n",
+ "can install [from PyPI](https://pypi.org/project/hivqe-qiskit-function-utils/)\n",
+ "with `pip install hivqe-qiskit-function-utils`. Everything else is as in the\n",
+ "[Example](#example), including `function_size`: see [Function sizes and\n",
+ "billing](#function-sizes-and-billing)."
]
},
{
@@ -495,9 +947,12 @@
" token=\"your_hivqe_license_token\",\n",
" function=catalog.load(\"qunova/hivqe-chemistry\"),\n",
")\n",
+ "\n",
"job = hivqe.run(\n",
" geometry=molecule_geometry,\n",
- " backend_name=backend_name, # can use any device with at least 14 qubits\n",
+ " backend_name=backend_name, # a backend you have access to\n",
+ " # 14 qubits fit the default \"m\"; a problem over 20 qubits needs \"l\"\n",
+ " function_size=\"m\",\n",
" max_states=10000,\n",
" max_expansion_states=1000,\n",
" hivqe_options={\"ansatz\": \"epa\", \"max_iter\": 10},\n",
@@ -505,6 +960,112 @@
"result = job.result()"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "04236c83",
+ "metadata": {},
+ "source": [
+ "## Fetch error messages\n",
+ "\n",
+ "If your workload fails, the status will be `ERROR` and calling\n",
+ "`job.result()` will raise an exception. This run fails after it starts, so it\n",
+ "is [billed](#what-is-billed) like any other:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "90c6de7c",
+ "metadata": {
+ "editable": true,
+ "slideshow": {
+ "slide_type": ""
+ },
+ "tags": [
+ "raises-exception"
+ ]
+ },
+ "outputs": [
+ {
+ "ename": "QiskitServerlessException",
+ "evalue": "[\"runner.UnknownRuntimeError: 'An unexpected error occurred during job execution. Please make sure that your inputs are valid. If you are still experiencing problems, you can contact the Qunova Computing support service at qiskit.support@qunovacomputing.com and provide the Function job ID of this job for more assistance. -- https://docs.quantum.ibm.com/errors#1500'\\n\"]",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mQiskitServerlessException\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[12], line 10\u001b[0m\n\u001b[1;32m 1\u001b[0m job \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mrun(\n\u001b[1;32m 2\u001b[0m geometry\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minvalid-geometry\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;66;03m# This will cause an error\u001b[39;00m\n\u001b[1;32m 3\u001b[0m backend_name\u001b[38;5;241m=\u001b[39mbackend_name,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 7\u001b[0m hivqe_options\u001b[38;5;241m=\u001b[39mhivqe_options,\n\u001b[1;32m 8\u001b[0m )\n\u001b[0;32m---> 10\u001b[0m \u001b[43mjob\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
+ "File \u001b[0;32m~/work/documentation/documentation/.tox/py311/lib/python3.11/site-packages/qiskit_serverless/core/job.py:253\u001b[0m, in \u001b[0;36mJob.result\u001b[0;34m(self, wait, cadence, verbose, maxwait)\u001b[0m\n\u001b[1;32m 251\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstatus() \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 252\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m results:\n\u001b[0;32m--> 253\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m QiskitServerlessException(results)\n\u001b[1;32m 255\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m QiskitServerlessException(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfiltered_logs(include\u001b[38;5;241m=\u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m(?i)error|exception\u001b[39m\u001b[38;5;124m\"\u001b[39m))\n\u001b[1;32m 257\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(results, \u001b[38;5;28mstr\u001b[39m):\n",
+ "\u001b[0;31mQiskitServerlessException\u001b[0m: [\"runner.UnknownRuntimeError: 'An unexpected error occurred during job execution. Please make sure that your inputs are valid. If you are still experiencing problems, you can contact the Qunova Computing support service at qiskit.support@qunovacomputing.com and provide the Function job ID of this job for more assistance. -- https://docs.quantum.ibm.com/errors#1500'\\n\"]"
+ ]
+ }
+ ],
+ "source": [
+ "job = function.run(\n",
+ " geometry=\"invalid-geometry\", # This will cause an error\n",
+ " backend_name=backend_name,\n",
+ " max_states=2000,\n",
+ " max_expansion_states=15,\n",
+ " molecule_options=molecule_options,\n",
+ " hivqe_options=hivqe_options,\n",
+ ")\n",
+ "\n",
+ "job.result()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "0b8de82f-3c5a-4024-8e3a-ef8efa83cfb9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ERROR'"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "job.status()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e86cab2f-11ab-4647-b785-9091c014034c",
+ "metadata": {},
+ "source": [
+ "Every failure reports an error code, a message describing what went wrong,\n",
+ "and a solution saying what to do about it. The codes follow [IBM's error\n",
+ "code registry](/docs/errors), and the ones this function returns are:\n",
+ "\n",
+ "| Code | What happened |\n",
+ "| --- | --- |\n",
+ "| 1007 | The `backend_name` you gave does not exist, or is not available to you |\n",
+ "| 1201 | A license token was supplied but no matching license was found |\n",
+ "| 1221 | An argument did not validate, or `function_size` was too small for the problem. The message names the size to use |\n",
+ "| 1500 | Something unexpected went wrong. Quote the job ID when you report it |\n",
+ "| 2409 | The license has expired, has been revoked, or was used from an instance it was not issued for |\n",
+ "| 4500 | The problem needs more qubits than your license or trial access allows |\n",
+ "| 4630 | Your license could not be read. Nothing is wrong with what you submitted; contact us with the job ID |\n",
+ "| 4631 | A Qiskit Runtime job made by the run failed or was cancelled, and Runtime gave no error code of its own. Submit the job again |\n",
+ "\n",
+ "When a Qiskit Runtime job made by the run fails with an error code of its\n",
+ "own, such as 1305, that code is reported instead; look it up in the\n",
+ "registry.\n",
+ "\n",
+ "Several codes cover more than one cause, so read the message as well as the\n",
+ "code. If you need help with a failure, send the Function job ID to\n",
+ "[qiskit.support@qunovacomputing.com](mailto:qiskit.support@qunovacomputing.com).\n",
+ "\n",
+ "A call with a wrong argument name, type or range does not get this far:\n",
+ "`run()` refuses it before a job is created; see [Check the\n",
+ "arguments](#check-the-arguments)."
+ ]
+ },
{
"cell_type": "markdown",
"id": "4af252f6",
@@ -520,13 +1081,16 @@
"id": "54d8f446",
"metadata": {},
"source": [
- "#### Dissociation potential energy surface curve for an Li2S molecule with 24 qubits\n",
+ "### Dissociation potential energy surface curve for an Li2S molecule with 24 qubits\n",
"\n",
"The PES curve is shown with the FCI reference and initial guess from RHF, together with the energy error from the FCI reference.\n",
"\n",
".\n",
"\n",
- "The calculations have been conducted with the following geometries and options."
+ "The calculations have been conducted with the following geometries and options.\n",
+ "The cell below runs them in the full STO-3G basis, which takes 38 qubits, so it\n",
+ "submits three runs at `\"l\"`: 12 RU in per-execution fees, plus QPU and classical\n",
+ "compute time."
]
},
{
@@ -572,7 +1136,8 @@
" # Run HI-VQE\n",
" job = function.run(\n",
" geometry=Li2S_geoms[geom],\n",
- " backend_name=backend_name, # can use any device with at least 38 qubits\n",
+ " backend_name=backend_name, # a backend you have access to\n",
+ " function_size=\"l\", # 38 qubits, more than \"m\" allows\n",
" max_states=2000,\n",
" max_expansion_states=10,\n",
" molecule_options=molecule_options,\n",
@@ -594,7 +1159,7 @@
"id": "4d8d6cad",
"metadata": {},
"source": [
- "#### Dissociation PES curve for an N2 molecule with 40 qubits\n",
+ "### Dissociation PES curve for an N2 molecule with 40 qubits\n",
"\n",
"The nitrogen molecule has been identified as a multireference system with large correlation energy contributions beyond the Hartree-Fock state. We conducted a benchmark calculation for the N2 molecule with cc-pvdz basis, (20o,14e) using the homo-lumo active orbital selection. The complete active space (CAS) number to represent this problem is 6,009,350,400. It is not possible to obtain the eigenvalue problem solution (for energy and electronic structure) with this number of states using a powerful desktop (16cpu/64GB). With HI-VQE, users can efficiently search the subspace of CAS states to find chemically accurate results while saving computation resources significantly. The following plots show the PES curve of 40 qubits HI-VQE calculation of the N2 molecule dissociation.\n",
"\n",
@@ -606,7 +1171,7 @@
"id": "e84bc625",
"metadata": {},
"source": [
- "#### Dissociation PES curve for five-coordinated iron(II)-porphyrin with an NO system with 44 qubits\n",
+ "### Dissociation PES curve for five-coordinated iron(II)-porphyrin with an NO system with 44 qubits\n",
"\n",
"Another interesting chemical system is an iron(II)-porphyrin (FeP) complex with a coordinated nitric oxide (NO) ligand, which represents a biologically relevant metalloporphyrin system that plays crucial roles in various physiological processes. In this example, HI-VQE has been utilized to estimate the accurate potential energy surface curve of the intermolecular interaction between FeP and NO (ground state energy for differently separated geometries). The combined system has 450 orbitals and 202 electrons (450o,202e) with 6-31g(d) basis in total. The homo-lumo active orbital selection was utilized to calculate the smaller case from the real case with (22o,22e). From the following benchmark results, we were able to achieve the chemical accuracy (> 1.6 mHa) with a state-of-the-art classical computer chemistry calculation of CASCI(DMRG) (22o,22e) reference.\n",
"\n",
@@ -618,7 +1183,7 @@
"id": "b34fe075",
"metadata": {},
"source": [
- "## Benchmarks\n",
+ "### Benchmarks\n",
"\n",
"- Exact matrix size is the number of determinants for exact solution, such as FCI and CASCI.\n",
"- HI-VQE calculation samples and calculates the subspace of it (as in, HI-VQE matrix size).\n",
@@ -627,83 +1192,12 @@
"\n",
"| Chemical system | Number of qubits | Exact matrix size | HI-VQE matrix size | E(diff) from exact (mHa) | Number of iteration | Total time | QPU runtime usage |\n",
"| ------------------ | ---------------- | ----------------- | ------------------- | ------------------------ | ------------------- | ------------- | ----------------- |\n",
- "| $NH_3$ (8o,10e) | 16 | 3136 | 1936 | 0.08 | 6 | 37 s | 34 s |\n",
- "| $Li_2S$ (10o,10e) | 20 | 63504 | 3969 | 0.60 | 5 | 250 s | 50 s |\n",
- "| $NH_3$ (15o,10e) | 30 | 9018009 | 49729 | 0.90 | 5 | 354 s | 54 s |\n",
- "| $N_2$ (16o,14e) | 32 | 130873600 | 1798281 | 1.10 | 9 | 6531 s | 121 s |\n",
- "| $3H_2O$ (18o,24e) | 36 | 344622096 | 399424 | 0.90 | 24 | 5174 s | 130 s |\n",
- "| $N_2$ (20o,14e) | 40 | 6009350400 | 9012004 | 1.20 | 21 | 46547 s | 258 s |"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "04236c83",
- "metadata": {},
- "source": [
- "## Fetch error messages\n",
- "\n",
- "If your workload fails, the status will be `ERROR` and calling `job.result()` will raise an exception:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "90c6de7c",
- "metadata": {
- "editable": true,
- "slideshow": {
- "slide_type": ""
- },
- "tags": [
- "raises-exception"
- ]
- },
- "outputs": [
- {
- "ename": "QiskitServerlessException",
- "evalue": "[\"runner.UnknownRuntimeError: 'An unexpected error occurred during job execution. Please make sure that your inputs are valid. If you are still experiencing problems, you can contact the Qunova Computing support service at qiskit.support@qunovacomputing.com and provide the Function job ID of this job for more assistance. -- https://docs.quantum.ibm.com/errors#1500'\\n\"]",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mQiskitServerlessException\u001b[0m Traceback (most recent call last)",
- "Cell \u001b[0;32mIn[12], line 10\u001b[0m\n\u001b[1;32m 1\u001b[0m job \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mrun(\n\u001b[1;32m 2\u001b[0m geometry\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124minvalid-geometry\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;66;03m# This will cause an error\u001b[39;00m\n\u001b[1;32m 3\u001b[0m backend_name\u001b[38;5;241m=\u001b[39mbackend_name,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 7\u001b[0m hivqe_options\u001b[38;5;241m=\u001b[39mhivqe_options,\n\u001b[1;32m 8\u001b[0m )\n\u001b[0;32m---> 10\u001b[0m \u001b[43mjob\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
- "File \u001b[0;32m~/work/documentation/documentation/.tox/py311/lib/python3.11/site-packages/qiskit_serverless/core/job.py:253\u001b[0m, in \u001b[0;36mJob.result\u001b[0;34m(self, wait, cadence, verbose, maxwait)\u001b[0m\n\u001b[1;32m 251\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstatus() \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 252\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m results:\n\u001b[0;32m--> 253\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m QiskitServerlessException(results)\n\u001b[1;32m 255\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m QiskitServerlessException(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfiltered_logs(include\u001b[38;5;241m=\u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m(?i)error|exception\u001b[39m\u001b[38;5;124m\"\u001b[39m))\n\u001b[1;32m 257\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(results, \u001b[38;5;28mstr\u001b[39m):\n",
- "\u001b[0;31mQiskitServerlessException\u001b[0m: [\"runner.UnknownRuntimeError: 'An unexpected error occurred during job execution. Please make sure that your inputs are valid. If you are still experiencing problems, you can contact the Qunova Computing support service at qiskit.support@qunovacomputing.com and provide the Function job ID of this job for more assistance. -- https://docs.quantum.ibm.com/errors#1500'\\n\"]"
- ]
- }
- ],
- "source": [
- "job = function.run(\n",
- " geometry=\"invalid-geometry\", # This will cause an error\n",
- " backend_name=backend_name,\n",
- " max_states=2000,\n",
- " max_expansion_states=15,\n",
- " molecule_options=molecule_options,\n",
- " hivqe_options=hivqe_options,\n",
- ")\n",
- "\n",
- "job.result()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "0b8de82f-3c5a-4024-8e3a-ef8efa83cfb9",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'ERROR'"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "job.status()"
+ "| $NH_3$ (8o,10e) | 16 | 3136 | 1936 | 0.08 | 6 | 37 s | 34 s |\n",
+ "| $Li_2S$ (10o,10e) | 20 | 63504 | 3969 | 0.60 | 5 | 250 s | 50 s |\n",
+ "| $NH_3$ (15o,10e) | 30 | 9018009 | 49729 | 0.90 | 5 | 354 s | 54 s |\n",
+ "| $N_2$ (16o,14e) | 32 | 130873600 | 1798281 | 1.10 | 9 | 6531 s | 121 s |\n",
+ "| $3H_2O$ (18o,24e) | 36 | 344622096 | 399424 | 0.90 | 24 | 5174 s | 130 s |\n",
+ "| $N_2$ (20o,14e) | 40 | 6009350400 | 9012004 | 1.20 | 21 | 46547 s | 258 s |"
]
},
{
@@ -713,6 +1207,16 @@
"source": [
"## Changelog\n",
"\n",
+ "### 5.0.4\n",
+ "\n",
+ "- Runs execute on dedicated compute, sized by the function size you choose.\n",
+ "- Runs without a license token are no longer limited to 20 qubits. Each run is billed per execution at the function size you choose with the new `function_size` argument: `\"s\"`, `\"m\"` (the default) or `\"l\"`. Runs with a license token are checked against the function size too. See [Function sizes and billing](#function-sizes-and-billing).\n",
+ "- Runs can take the problem from an FCIDUMP file you upload, in place of a geometry. See [Run from an FCIDUMP file](#run-from-an-fcidump-file).\n",
+ "- Added a size estimator that gives the function size a problem needs, on your own machine and at no charge. See [Size estimator](#size-estimator).\n",
+ "- Arguments are checked against the function's argument schema when you call `run()`, and a malformed call is refused before a job is created, at no charge. Check them in advance with `validate_arguments()`. See [Check the arguments](#check-the-arguments).\n",
+ "- Every error carries an error code, a message saying what went wrong, and what to do about it. See [Fetch error messages](#fetch-error-messages).\n",
+ "- The result includes `\"function_version\"` and `\"metadata\"`, whose `\"resource_usage\"` gives the time spent in each stage of the job, including QPU time. The job status also shows `RUNNING: MAPPING` while the problem is being set up.\n",
+ "\n",
"### 4.0.0\n",
"\n",
"- The result no longer includes `\"states\"` or `\"eigenvector\"`. They are now saved in an HDF5 results file, together with `\"final_energy\"`, `\"final_energy_variance\"`, and `\"energy_history\"`.\n",
@@ -739,9 +1243,8 @@
"## Next steps\n",
"\n",
"\n",
- "- Request access to the function by filling in [this form](https://forms.office.com/r/zN3hvMTqJ1).\n",
+ "- Request access and a license, if you need one, by filling in [this form](https://forms.office.com/r/zN3hvMTqJ1).\n",
"- Visit the [API reference](/docs/api/functions/qunova-chemistry) for this Qiskit Function.\n",
- "- Try the [Compute dissociation PES curve for FeP-NO with HI-VQE](/docs/tutorials/qunova-hivqe) tutorial.\n",
"- Review [Pellow-Jarman, A., et al. (2025). HIVQE: Handover Iterative Variational Quantum Eigensolver for Efficient Quantum Chemistry Calculations. arXiv preprint arXiv:2503.06292](https://arxiv.org/abs/2503.06292).\n",
"- Try the [Dissociation PES curves with Qunova HiVQE](/docs/tutorials/qunova-hivqe) tutorial.\n",
""
diff --git a/docs/tutorials/qunova-hivqe.ipynb b/docs/tutorials/qunova-hivqe.ipynb
index da02a45ce223..f90c011905c2 100644
--- a/docs/tutorials/qunova-hivqe.ipynb
+++ b/docs/tutorials/qunova-hivqe.ipynb
@@ -39,7 +39,7 @@
"source": [
"## Background\n",
"\n",
- "Accurately calculating chemical reaction energies is crucial for scientific advancements in materials science, chemical engineering, drug discovery, and other fields. Among various chemical systems, the Li-S system has garnered significant interest for understanding and developing new battery compositions. This tutorial provides hands-on experience in calculating the Li-S bond dissociation potential energy surface (PES) of a $Li_2S$ system by removing one lithium atom using HiVQE calculations. The results can be compared with reference calculations (CASCI) as well as classical methods like Hartree-Fock (HF) for a 20-qubit problem.\n",
+ "Accurately calculating chemical reaction energies is crucial for scientific advancements in materials science, chemical engineering, drug discovery, and other fields. Among various chemical systems, the Li-S system has garnered significant interest for understanding and developing new battery compositions. This tutorial provides hands-on experience in calculating the Li-S bond dissociation potential energy surface (PES) of a $Li_2S$ system by removing one lithium atom using HI-VQE calculations. The results can be compared with reference calculations (CASCI) as well as classical methods like Hartree-Fock (HF) for a 20-qubit problem.\n",
"\n",
"The lithium–sulfur example connects this workflow to research on next-generation batteries for energy storage. Calculating how energy changes as a Li–S bond breaks provides molecular-level insight relevant to understanding the chemical transformations in these systems. More broadly, potential energy surfaces are tools for studying reaction pathways and catalysts for more resource-efficient chemical processes."
]
@@ -62,7 +62,7 @@
"outputs": [],
"source": [
"!pip install --upgrade pip\n",
- "!pip install -U qiskit-ibm-catalog \"qiskit_ibm_runtime<0.42.0\" pyscf numpy matplotlib typing_extensions h5py"
+ "!pip install -U qiskit-ibm-catalog qiskit-ibm-runtime pyscf numpy matplotlib typing_extensions h5py"
]
},
{
@@ -73,7 +73,9 @@
"source": [
"## Setup\n",
"\n",
- "To run this tutorial, import `qunova/hivqe-chemistry` function via `QiskitFunctionCatalog`. You need an IBM Quantum Premium Plan, Flex Plan, or On-Prem (IBM Quantum Platform API) Plan account with a license from Qunova to run this function."
+ "To run this tutorial, load the `qunova/hivqe-chemistry` function through\n",
+ "`QiskitFunctionsCatalog`. You need an IBM Quantum Premium Plan, Flex Plan, or\n",
+ "On-Prem (IBM Quantum Platform API) Plan account."
]
},
{
@@ -84,6 +86,7 @@
"outputs": [],
"source": [
"from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
+ "from qiskit_ibm_runtime import QiskitRuntimeService\n",
"from pyscf import gto, scf, mcscf\n",
"import matplotlib.pyplot as plt\n",
"import pprint\n",
@@ -96,7 +99,50 @@
" token=\"YOUR_API_KEY\",\n",
")\n",
"\n",
- "hivqe = catalog.load(\"qunova/hivqe-chemistry\")"
+ "hivqe = catalog.load(\"qunova/hivqe-chemistry\")\n",
+ "\n",
+ "# A backend you have access to, with enough qubits for Part 2\n",
+ "service = QiskitRuntimeService(\n",
+ " channel=\"ibm_quantum_platform\",\n",
+ " instance=\"INSTANCE_CRN\",\n",
+ " token=\"YOUR_API_KEY\",\n",
+ ")\n",
+ "backend_name = service.least_busy(operational=True, min_num_qubits=44).name"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "659d5a25-7fd6-41b2-a657-5bfe1d8c713d",
+ "metadata": {},
+ "source": [
+ "### Before you run\n",
+ "\n",
+ "**Without a license.** The cell above is all the setup you need. Every run\n",
+ "below names a `function_size`, which sets the resources it gets and what it is\n",
+ "billed: `\"m\"` for Part 1, and `\"l\"` for Part 2, which needs 44 qubits. Running\n",
+ "the whole tutorial is six runs at `\"m\"` and three at `\"l\"`, or 18.0 resource\n",
+ "units in per-execution fees, plus the QPU and classical compute time the runs\n",
+ "use. See [Function sizes and\n",
+ "billing](/docs/guides/qunova-chemistry#function-sizes-and-billing) in the guide for\n",
+ "what the sizes cost.\n",
+ "\n",
+ "**With a license.** Load the function through the wrapper library instead of\n",
+ "the cell above, then run everything below unchanged:\n",
+ "\n",
+ "```python\n",
+ "# pip install hivqe-qiskit-function-utils\n",
+ "from hivqe_qiskit_function_utils import FunctionWrapper\n",
+ "\n",
+ "hivqe = FunctionWrapper(\n",
+ " token=\"YOUR_HIVQE_LICENSE_TOKEN\",\n",
+ " function=catalog.load(\"qunova/hivqe-chemistry\"),\n",
+ ")\n",
+ "```\n",
+ "\n",
+ "Your license sets the qubit limit, so it has to permit at least 44 qubits for\n",
+ "Part 2. You don't pay the per-execution fee, but `function_size` still sets\n",
+ "the compute each run uses, and so its classical compute cost, and is checked\n",
+ "against the problem as for any run."
]
},
{
@@ -104,7 +150,7 @@
"id": "00c68174",
"metadata": {},
"source": [
- "You will also need to create a `QiskitServerless` instance to download the results file for the calculation. This uses the same credentials as `QiskitFunctionCatalog`."
+ "You will also need to create a `QiskitServerless` instance to download the results file for the calculation. This uses the same credentials as `QiskitFunctionsCatalog`."
]
},
{
@@ -175,7 +221,7 @@
"id": "3cd2cc70",
"metadata": {},
"source": [
- "HiVQE calculations will be performed with the options defined below. Using sto3g basis for $Li_2S$, there are 19 spatial orbitals with 22 electrons. To run (10o,10e) case with HiVQE calculation, you can define 10 active orbitals and six frozen orbitals. At each iteration, 100 shots will be used to sample electron configuration generated by the ExcitationPreserving quantum circuit (`epa`) with `circular` entanglement and two repetitions (`reps`). The maximum number of iteration is set to be 30 to ensure termination of iteration with energy convergence."
+ "HI-VQE calculations will be performed with the options defined below. Using sto3g basis for $Li_2S$, there are 19 spatial orbitals with 22 electrons. To run (10o,12e) case with HI-VQE calculation, you can define 10 active orbitals and freeze the five lowest orbitals, which leaves 12 active electrons. At each iteration, 100 shots will be used to sample electron configuration generated by the ExcitationPreserving quantum circuit (`epa`) with `circular` entanglement and two repetitions (`reps`). The maximum number of iteration is set to be 30 to ensure termination of iteration with energy convergence."
]
},
{
@@ -205,9 +251,9 @@
"id": "3ee5ec4c",
"metadata": {},
"source": [
- "### Step 2 and 3: Optimize problem for quantum hardware execution and execute using the HiVQE Chemistry function\n",
+ "### Step 2 and 3: Optimize problem for quantum hardware execution and execute using the HI-VQE Chemistry function\n",
"\n",
- "Set up the `for` loop to run HiVQE calculations with geometries with options defined below. Jobs are submitted in the `for` loop. In this tutorial, you will submit six geometries and retrieve results when they are all completed. In the main function run, you need to define the `max_states` and `max_expansion_states` to control the maximum size of the subspace matrix and to control how many states can be generated using classical CI expansion methods per iteration. The function job ids will be stored in the dictionary with each geometry label to further track and process the ouptut."
+ "Set up the `for` loop to run HI-VQE calculations with geometries with options defined below. Jobs are submitted in the `for` loop. In this tutorial, you will submit six geometries and retrieve results when they are all completed. In the main function run, you need to define the `max_states` and `max_expansion_states` to control the maximum size of the subspace matrix and to control how many states can be generated using classical CI expansion methods per iteration. The function job ids will be stored in the dictionary with each geometry label to further track and process the output. These geometries need 20 qubits, so the runs are submitted at `function_size=\"m\"`."
]
},
{
@@ -229,7 +275,8 @@
"for dis, geom in str_geometries.items():\n",
" hivqe_run = hivqe.run(\n",
" geometry=geom,\n",
- " backend_name=\"\",\n",
+ " backend_name=backend_name,\n",
+ " function_size=\"m\",\n",
" max_states=40000,\n",
" max_expansion_states=100,\n",
" molecule_options=molecule_options,\n",
@@ -355,7 +402,7 @@
"id": "51a9e47b",
"metadata": {},
"source": [
- "The results file for each of the calculations can be downloaded into the current directory using `QiskitServerless`. These files contain `\"states\"`, `\"eigenvector\"`, `\"energy_history\"`, `\"final_energy\"`, and `\"final_energy_variance\"`."
+ "The results file for each of the calculations can be downloaded into the current directory, under its own name, using `QiskitServerless`. These files contain `\"states\"`, `\"eigenvector\"`, `\"energy_history\"`, `\"final_energy\"`, and `\"final_energy_variance\"`."
]
},
{
@@ -370,7 +417,10 @@
" for i, job in enumerate(completed_jobs.items()):\n",
" dis, cal = job\n",
" print(dis, cal.result()[\"results_file_name\"])\n",
- " serverless.file_download(cal.result()[\"results_file_name\"], hivqe)"
+ " results_file_name = cal.result()[\"results_file_name\"]\n",
+ " serverless.file_download(\n",
+ " results_file_name, hivqe, target_name=results_file_name\n",
+ " )"
]
},
{
@@ -390,7 +440,8 @@
"source": [
"import h5py\n",
"\n",
- "results_file_name = \"PATH_TO_DOWNLOADED_RESULTS_FILE\"\n",
+ "# The results file of the 1.51 calculation\n",
+ "results_file_name = completed_jobs[\"1.51\"].result()[\"results_file_name\"]\n",
"\n",
"# Read data from the results file for a single calculation\n",
"with h5py.File(results_file_name, \"r\") as f:\n",
@@ -416,7 +467,7 @@
"source": [
"### Step 4: Post-process and compare with classical methods\n",
"\n",
- "Classical reference calculation (CASCI) can be conducted for (10o,10e) to validate HiVQE results."
+ "Classical reference calculation (CASCI) can be conducted for (10o,12e) to validate HI-VQE results."
]
},
{
@@ -426,7 +477,7 @@
"metadata": {},
"outputs": [],
"source": [
- "str_geometries = {\n",
+ "ref_geometries = {\n",
" \"1.31\": \"S -1.250686 0.660708 -0.095168; Li -1.482812 0.453464 -1.369406; Li -0.911870 0.962810 1.762020\",\n",
" \"1.41\": \"S -1.244856 0.665971 -0.062773; Li -1.494574 0.442933 -1.434177; Li -0.905937 0.968078 1.794395\",\n",
" \"1.51\": \"S -1.239044 0.671232 -0.030374; Li -1.506327 0.432403 -1.498949; Li -0.899996 0.973348 1.826768\",\n",
@@ -517,7 +568,7 @@
"\n",
"cas_list = molecule_options[\"active_orbitals\"]\n",
"distance_ref = []\n",
- "for dis, geom in str_geometries.items():\n",
+ "for dis, geom in ref_geometries.items():\n",
" distance_ref.append(dis)\n",
" mole = gto.M(atom=geom, basis=molecule_options[\"basis\"])\n",
" mole.verbose = 0\n",
@@ -543,10 +594,8 @@
"id": "e1900a94",
"metadata": {},
"source": [
- "### Plotting the dissociation curve for Li\\_2S\n",
- "\n",
- "Let's plot and compare HiVQE results with HF and CASCI.\n",
- "You can observe that all HiVQE calculations are well-matched with the classical reference result (CASCI)."
+ "Let's plot and compare HI-VQE results with HF and CASCI.\n",
+ "You can observe that all HI-VQE calculations are well-matched with the classical reference result (CASCI)."
]
},
{
@@ -591,11 +640,11 @@
"source": [
"## Part 2: FeP-NO (44Q)\n",
"\n",
- "Note that to run the function on the FeP-NO system with the settings shown in this example, you need a license that permits using the function with at least 44 qubits. Email [qiskit.support@qunovacomputing.com](mailto:qiskit.support@qunovacomputing.com) to inquire about obtaining a license.\n",
+ "The settings shown in this example need 44 qubits, so the runs below are submitted at `function_size=\"l\"`. On a license, it must permit at least 44 qubits; email [qiskit.support@qunovacomputing.com](mailto:qiskit.support@qunovacomputing.com) to inquire about one.\n",
"\n",
"### Step 1: Map classical inputs to a quantum problem\n",
"\n",
- "Define the options for HiVQE calculations"
+ "Define the options for HI-VQE calculations"
]
},
{
@@ -605,14 +654,14 @@
"metadata": {},
"outputs": [],
"source": [
- "molecule_options = {\n",
+ "molecule_options_fepno = {\n",
" \"basis\": \"631g*\",\n",
" \"active_orbitals\": list(range(90, 112, 1)),\n",
" \"frozen_orbitals\": list(range(0, 90, 1)),\n",
" \"charge\": -1,\n",
"}\n",
"\n",
- "hivqe_options = {\n",
+ "hivqe_options_fepno = {\n",
" \"shots\": 2000,\n",
" \"max_iter\": 40,\n",
" \"ansatz\": \"epa\",\n",
@@ -635,170 +684,7 @@
"execution_count": null,
"id": "8c93344d",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'5.0': '\\nFe 9.918629 31.289202 1.717339\\nN 10.542914 31.832173 -0.080685\\nN 11.795572 31.199413 2.341831\\nN 9.294593 30.741247 3.513929\\nN 8.042689 31.359481 1.087282\\nC 9.775254 32.111817 -1.200449\\nC 10.600219 32.479101 -2.319680\\nC 11.891090 32.425876 -1.887580\\nC 11.847694 32.024341 -0.507342\\nC 12.945734 31.464689 1.611366\\nC 14.116395 31.289997 2.423572\\nC 13.685777 30.915122 3.663719\\nC 12.252381 30.861042 3.608186\\nC 10.062170 30.463021 4.634102\\nC 9.236749 30.104333 5.755782\\nC 7.945687 30.161198 5.324720\\nC 7.989641 30.552269 3.941498\\nC 6.892881 31.087489 1.815829\\nC 5.722676 31.253502 1.001149\\nC 6.153153 31.631057 -0.238233\\nC 7.586010 31.695401 -0.179773\\nC 8.390724 32.047572 -1.247553\\nH 7.903308 32.291586 -2.187969\\nC 12.973334 31.849872 0.283741\\nH 13.944682 32.031190 -0.169145\\nC 11.447158 30.518591 4.678739\\nH 11.934423 30.277429 5.619969\\nC 6.864795 30.711643 3.146118\\nH 5.893357 30.532078 3.599511\\nH 12.800139 32.636412 -2.439296\\nH 10.224017 32.743662 -3.301293\\nH 15.131785 31.441247 2.076257\\nH 14.273933 30.694315 4.546802\\nH 9.612512 29.848040 6.739754\\nH 7.036117 29.960530 5.879248\\nH 4.707408 31.099933 1.347803\\nH 5.564992 31.851940 -1.121294\\nN 9.666041 36.091609 3.085945\\nO 9.598728 37.226756 3.411299\\n'}"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "geometry_1_75 = \"\"\"\n",
- "Fe 9.910596 31.534095 1.798088\n",
- "N 10.557481 31.888419 -0.055204\n",
- "N 11.823496 31.255002 2.384659\n",
- "N 9.292831 30.783362 3.568730\n",
- "N 8.036805 31.418327 1.124265\n",
- "C 9.784765 32.177349 -1.158798\n",
- "C 10.612656 32.501029 -2.296868\n",
- "C 11.903375 32.404043 -1.876832\n",
- "C 11.859093 32.028943 -0.483750\n",
- "C 12.965737 31.464698 1.641427\n",
- "C 14.146517 31.236323 2.440231\n",
- "C 13.713061 30.885870 3.681911\n",
- "C 12.268752 30.896411 3.634891\n",
- "C 10.067717 30.486167 4.664747\n",
- "C 9.246224 30.053411 5.772052\n",
- "C 7.957075 30.082846 5.336488\n",
- "C 7.995710 30.538421 3.967046\n",
- "C 6.900258 31.104497 1.836595\n",
- "C 5.722470 31.251707 1.015333\n",
- "C 6.148430 31.668586 -0.207993\n",
- "C 7.587039 31.767438 -0.130483\n",
- "C 8.399453 32.134197 -1.192329\n",
- "H 7.912872 32.388031 -2.131079\n",
- "C 12.984883 31.836053 0.306093\n",
- "H 13.955948 31.977044 -0.162626\n",
- "C 11.453768 30.560663 4.708020\n",
- "H 11.940677 30.298823 5.644352\n",
- "C 6.877071 30.697580 3.164102\n",
- "H 5.907240 30.476797 3.603674\n",
- "H 12.813946 32.569160 -2.441577\n",
- "H 10.236332 32.758110 -3.280309\n",
- "H 15.164312 31.335191 2.080201\n",
- "H 14.299625 30.629109 4.556760\n",
- "H 9.626524 29.758225 6.743433\n",
- "H 7.053076 29.823583 5.875809\n",
- "H 4.709768 31.058315 1.350561\n",
- "H 5.561898 31.886355 -1.093106\n",
- "N 9.832739 33.209042 2.298783\n",
- "O 9.346337 34.075996 1.606023\n",
- "\"\"\"\n",
- "\n",
- "geometry_2_00 = \"\"\"\n",
- "Fe 9.917990 31.445558 1.778346\n",
- "N 10.556809 31.866188 -0.055498\n",
- "N 11.814089 31.227003 2.372666\n",
- "N 9.297875 30.758246 3.550104\n",
- "N 8.043584 31.397768 1.120485\n",
- "C 9.784831 32.164652 -1.160219\n",
- "C 10.611624 32.501801 -2.293514\n",
- "C 11.902858 32.406547 -1.875160\n",
- "C 11.859552 32.017818 -0.486307\n",
- "C 12.960503 31.454432 1.636717\n",
- "C 14.140770 31.242960 2.439615\n",
- "C 13.708543 30.884151 3.678983\n",
- "C 12.266351 30.874173 3.627468\n",
- "C 10.070264 30.465070 4.655102\n",
- "C 9.247247 30.053101 5.766681\n",
- "C 7.958085 30.091201 5.332866\n",
- "C 7.998432 30.529979 3.958727\n",
- "C 6.901428 31.093932 1.833807\n",
- "C 5.723289 31.255057 1.016540\n",
- "C 6.151314 31.670649 -0.206350\n",
- "C 7.589736 31.755538 -0.133074\n",
- "C 8.400230 32.124963 -1.194447\n",
- "H 7.913264 32.386655 -2.130914\n",
- "C 12.983905 31.827747 0.302415\n",
- "H 13.955696 31.979687 -0.161365\n",
- "C 11.454251 30.533644 4.698234\n",
- "H 11.941002 30.276716 5.636156\n",
- "C 6.877444 30.689985 3.159940\n",
- "H 5.907605 30.480118 3.604825\n",
- "H 12.813105 32.581608 -2.437367\n",
- "H 10.233725 32.768337 -3.273979\n",
- "H 15.157796 31.357524 2.082132\n",
- "H 14.295001 30.638320 4.557047\n",
- "H 9.626721 29.768762 6.741623\n",
- "H 7.051752 29.847502 5.875478\n",
- "H 4.709710 31.071712 1.354640\n",
- "H 5.565103 31.898376 -1.089333\n",
- "N 9.840508 33.353531 2.373019\n",
- "O 9.344561 34.158205 1.637232\n",
- "\"\"\"\n",
- "\n",
- "geometry_5_00 = \"\"\"\n",
- "Fe 9.918629 31.289202 1.717339\n",
- "N 10.542914 31.832173 -0.080685\n",
- "N 11.795572 31.199413 2.341831\n",
- "N 9.294593 30.741247 3.513929\n",
- "N 8.042689 31.359481 1.087282\n",
- "C 9.775254 32.111817 -1.200449\n",
- "C 10.600219 32.479101 -2.319680\n",
- "C 11.891090 32.425876 -1.887580\n",
- "C 11.847694 32.024341 -0.507342\n",
- "C 12.945734 31.464689 1.611366\n",
- "C 14.116395 31.289997 2.423572\n",
- "C 13.685777 30.915122 3.663719\n",
- "C 12.252381 30.861042 3.608186\n",
- "C 10.062170 30.463021 4.634102\n",
- "C 9.236749 30.104333 5.755782\n",
- "C 7.945687 30.161198 5.324720\n",
- "C 7.989641 30.552269 3.941498\n",
- "C 6.892881 31.087489 1.815829\n",
- "C 5.722676 31.253502 1.001149\n",
- "C 6.153153 31.631057 -0.238233\n",
- "C 7.586010 31.695401 -0.179773\n",
- "C 8.390724 32.047572 -1.247553\n",
- "H 7.903308 32.291586 -2.187969\n",
- "C 12.973334 31.849872 0.283741\n",
- "H 13.944682 32.031190 -0.169145\n",
- "C 11.447158 30.518591 4.678739\n",
- "H 11.934423 30.277429 5.619969\n",
- "C 6.864795 30.711643 3.146118\n",
- "H 5.893357 30.532078 3.599511\n",
- "H 12.800139 32.636412 -2.439296\n",
- "H 10.224017 32.743662 -3.301293\n",
- "H 15.131785 31.441247 2.076257\n",
- "H 14.273933 30.694315 4.546802\n",
- "H 9.612512 29.848040 6.739754\n",
- "H 7.036117 29.960530 5.879248\n",
- "H 4.707408 31.099933 1.347803\n",
- "H 5.564992 31.851940 -1.121294\n",
- "N 9.666041 36.091609 3.085945\n",
- "O 9.598728 37.226756 3.411299\n",
- "\"\"\"\n",
- "\n",
- "str_geometries = {\n",
- " \"1.75\": geometry_1_75,\n",
- " \"2.00\": geometry_2_00,\n",
- " \"5.00\": geometry_5_00,\n",
- "}\n",
- "\n",
- "\n",
- "hivqe_result = {}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "52b55a07",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'5.0': '\\nFe 9.918629 31.289202 1.717339\\nN 10.542914 31.832173 -0.080685\\nN 11.795572 31.199413 2.341831\\nN 9.294593 30.741247 3.513929\\nN 8.042689 31.359481 1.087282\\nC 9.775254 32.111817 -1.200449\\nC 10.600219 32.479101 -2.319680\\nC 11.891090 32.425876 -1.887580\\nC 11.847694 32.024341 -0.507342\\nC 12.945734 31.464689 1.611366\\nC 14.116395 31.289997 2.423572\\nC 13.685777 30.915122 3.663719\\nC 12.252381 30.861042 3.608186\\nC 10.062170 30.463021 4.634102\\nC 9.236749 30.104333 5.755782\\nC 7.945687 30.161198 5.324720\\nC 7.989641 30.552269 3.941498\\nC 6.892881 31.087489 1.815829\\nC 5.722676 31.253502 1.001149\\nC 6.153153 31.631057 -0.238233\\nC 7.586010 31.695401 -0.179773\\nC 8.390724 32.047572 -1.247553\\nH 7.903308 32.291586 -2.187969\\nC 12.973334 31.849872 0.283741\\nH 13.944682 32.031190 -0.169145\\nC 11.447158 30.518591 4.678739\\nH 11.934423 30.277429 5.619969\\nC 6.864795 30.711643 3.146118\\nH 5.893357 30.532078 3.599511\\nH 12.800139 32.636412 -2.439296\\nH 10.224017 32.743662 -3.301293\\nH 15.131785 31.441247 2.076257\\nH 14.273933 30.694315 4.546802\\nH 9.612512 29.848040 6.739754\\nH 7.036117 29.960530 5.879248\\nH 4.707408 31.099933 1.347803\\nH 5.564992 31.851940 -1.121294\\nN 9.666041 36.091609 3.085945\\nO 9.598728 37.226756 3.411299\\n'}"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
"geometry_1_75 = \"\"\"\n",
"Fe 9.910596 31.534095 1.798088\n",
@@ -926,14 +812,14 @@
"O 9.598728 37.226756 3.411299\n",
"\"\"\"\n",
"\n",
- "str_geometries = {\n",
+ "fepno_geometries = {\n",
" \"1.75\": geometry_1_75,\n",
" \"2.00\": geometry_2_00,\n",
" \"5.00\": geometry_5_00,\n",
"}\n",
"\n",
"\n",
- "hivqe_result = {}"
+ "hivqe_result_fepno = {}"
]
},
{
@@ -941,9 +827,9 @@
"id": "5ed92d44",
"metadata": {},
"source": [
- "### Step 2 and 3: Optimize problem for quantum hardware execution and execute using the HiVQE Chemistry function\n",
+ "### Step 2 and 3: Optimize problem for quantum hardware execution and execute using the HI-VQE Chemistry function\n",
"\n",
- "Based on the setup of HiVQE and geometries, obtain results sequentially."
+ "Based on the setup of HI-VQE and geometries, obtain results sequentially."
]
},
{
@@ -962,12 +848,13 @@
"outputs": [],
"source": [
"hivqe_run_1_75 = hivqe.run(\n",
- " geometry=str_geometries[\"1.75\"],\n",
- " backend_name=\"\",\n",
+ " geometry=fepno_geometries[\"1.75\"],\n",
+ " backend_name=backend_name,\n",
+ " function_size=\"l\",\n",
" max_states=400000000,\n",
" max_expansion_states=100,\n",
- " molecule_options=molecule_options,\n",
- " hivqe_options=hivqe_options,\n",
+ " molecule_options=molecule_options_fepno,\n",
+ " hivqe_options=hivqe_options_fepno,\n",
")\n",
"info_jobid_1_75 = hivqe_run_1_75.job_id"
]
@@ -992,8 +879,8 @@
"print(submitted_job_1_75.job_id, stat)\n",
"if stat == \"DONE\":\n",
" hivqe_run_1_75_energy = submitted_job_1_75.result()[\"energy\"]\n",
- " print(f\"Completed HiVQE calculation, Energy {hivqe_run_1_75_energy}\")\n",
- " hivqe_result[\"1.75\"] = hivqe_run_1_75_energy"
+ " print(f\"Completed HI-VQE calculation, Energy {hivqe_run_1_75_energy}\")\n",
+ " hivqe_result_fepno[\"1.75\"] = hivqe_run_1_75_energy"
]
},
{
@@ -1012,12 +899,13 @@
"outputs": [],
"source": [
"hivqe_run_2_00 = hivqe.run(\n",
- " geometry=str_geometries[\"2.00\"],\n",
- " backend_name=\"\",\n",
+ " geometry=fepno_geometries[\"2.00\"],\n",
+ " backend_name=backend_name,\n",
+ " function_size=\"l\",\n",
" max_states=400000000,\n",
" max_expansion_states=100,\n",
- " molecule_options=molecule_options,\n",
- " hivqe_options=hivqe_options,\n",
+ " molecule_options=molecule_options_fepno,\n",
+ " hivqe_options=hivqe_options_fepno,\n",
")\n",
"info_jobid_2_00 = hivqe_run_2_00.job_id"
]
@@ -1042,8 +930,8 @@
"print(submitted_job_2_00.job_id, stat)\n",
"if stat == \"DONE\":\n",
" hivqe_run_2_00_energy = submitted_job_2_00.result()[\"energy\"]\n",
- " print(f\"Completed HiVQE calculation, Energy {hivqe_run_2_00_energy}\")\n",
- " hivqe_result[\"2.00\"] = hivqe_run_2_00_energy"
+ " print(f\"Completed HI-VQE calculation, Energy {hivqe_run_2_00_energy}\")\n",
+ " hivqe_result_fepno[\"2.00\"] = hivqe_run_2_00_energy"
]
},
{
@@ -1062,12 +950,13 @@
"outputs": [],
"source": [
"hivqe_run_5_00 = hivqe.run(\n",
- " geometry=str_geometries[\"5.00\"],\n",
- " backend_name=\"\",\n",
+ " geometry=fepno_geometries[\"5.00\"],\n",
+ " backend_name=backend_name,\n",
+ " function_size=\"l\",\n",
" max_states=400000000,\n",
" max_expansion_states=100,\n",
- " molecule_options=molecule_options,\n",
- " hivqe_options=hivqe_options,\n",
+ " molecule_options=molecule_options_fepno,\n",
+ " hivqe_options=hivqe_options_fepno,\n",
")\n",
"info_jobid_5_00 = hivqe_run_5_00.job_id"
]
@@ -1092,8 +981,17 @@
"print(submitted_job_5_00.job_id, stat)\n",
"if stat == \"DONE\":\n",
" hivqe_run_5_00_energy = submitted_job_5_00.result()[\"energy\"]\n",
- " print(f\"Completed HiVQE calculation, Energy {hivqe_run_5_00_energy}\")\n",
- " hivqe_result[\"5.00\"] = hivqe_run_5_00_energy"
+ " print(f\"Completed HI-VQE calculation, Energy {hivqe_run_5_00_energy}\")\n",
+ " hivqe_result_fepno[\"5.00\"] = hivqe_run_5_00_energy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1c0606d4-088a-4999-bf16-cb6b87637652",
+ "metadata": {},
+ "source": [
+ "These are the energies from the three runs, so that the comparison below works\n",
+ "without waiting for your own jobs. Skip this cell to use your own."
]
},
{
@@ -1103,7 +1001,7 @@
"metadata": {},
"outputs": [],
"source": [
- "hivqe_result = {\n",
+ "hivqe_result_fepno = {\n",
" \"1.75\": -2373.681781,\n",
" \"2.00\": -2373.694128,\n",
" \"5.00\": -2373.637807,\n",
@@ -1117,7 +1015,7 @@
"source": [
"### Step 4: Post-process and compare with classical methods\n",
"\n",
- "Classical reference calculation (CASCI-DMRG, maxM=800) results are provided for (22o,22e) to validate HiVQE results."
+ "Classical reference calculation (CASCI-DMRG, maxM=800) results are provided for (22o,22e) to validate HI-VQE results."
]
},
{
@@ -1127,12 +1025,16 @@
"metadata": {},
"outputs": [],
"source": [
- "rhf_result = {\n",
+ "rhf_result_fepno = {\n",
" \"1.75\": -2373.59331683504,\n",
" \"2.00\": -2373.60640773065,\n",
" \"5.00\": -2373.50214278007,\n",
"}\n",
- "casci_result = {\"1.75\": -2373.6827, \"2.00\": -2373.6948, \"5.00\": -2373.6393}"
+ "casci_result_fepno = {\n",
+ " \"1.75\": -2373.6827,\n",
+ " \"2.00\": -2373.6948,\n",
+ " \"5.00\": -2373.6393,\n",
+ "}"
]
},
{
@@ -1158,11 +1060,11 @@
],
"source": [
"fig, ax = plt.subplots(1, 1)\n",
- "hf_energy = [v for key, v in rhf_result.items()]\n",
- "casci_energy = [v for key, v in casci_result.items()]\n",
- "hivqe_energy = [v for key, v in hivqe_result.items()]\n",
- "distance_ref = [float(key) for key, v in rhf_result.items()]\n",
- "distance = [float(key) for key, v in hivqe_result.items()]\n",
+ "hf_energy = [v for key, v in rhf_result_fepno.items()]\n",
+ "casci_energy = [v for key, v in casci_result_fepno.items()]\n",
+ "hivqe_energy = [v for key, v in hivqe_result_fepno.items()]\n",
+ "distance_ref = [float(key) for key, v in rhf_result_fepno.items()]\n",
+ "distance = [float(key) for key, v in hivqe_result_fepno.items()]\n",
"\n",
"ax.plot(distance_ref, hf_energy, \"-o\", label=\"RHF\", c=\"blue\")\n",
"ax.plot(distance_ref, casci_energy, \"-o\", label=\"CASCI\", c=\"green\")\n",
@@ -1189,6 +1091,7 @@
}
],
"metadata": {
+ "hours": 1.5,
"kernelspec": {
"display_name": "Python 3",
"language": "python",
@@ -1206,7 +1109,6 @@
"pygments_lexer": "ipython3",
"version": "3"
},
- "hours": 1.5,
"qpuSeconds": 300
},
"nbformat": 4,