343 lines
10 KiB
Plaintext
343 lines
10 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Example: VQE as QiskitPattern\n",
|
|
"\n",
|
|
"This tutorial will be demonstation of creating VQE as QiskitPattern as well as migration guide on how you can replicate IBM Quantum VQE custom runtime program.\n",
|
|
"\n",
|
|
"Let's first get information on what is VQE runtime program and what inputs and outputs it has.\n",
|
|
"\n",
|
|
"**Description** of runtime program is: Variational Quantum Eigensolver (VQE) to find the minimal eigenvalue of a Hamiltonian.\n",
|
|
"\n",
|
|
"**Inputs**:\n",
|
|
"\n",
|
|
"| name | type | description |\n",
|
|
"| ---- | ---- | ----------- |\n",
|
|
"| ansatz | object | A parameterized quantum circuit preparing the ansatz wavefunction for the VQE. It is assumed that all qubits are initially in the 0 state. | \n",
|
|
"| initial_parameters|[array,string]|Initial parameters of the ansatz. Can be an array or the string ``'random'`` to choose random initial parameters.|\n",
|
|
"|operator|object|The Hamiltonian whose smallest eigenvalue we're trying to find. Should be PauliSumOp|\n",
|
|
"|method|str|The classical optimizer used in to update the parameters in each iteration. |\n",
|
|
"\n",
|
|
"\n",
|
|
"**Return values**\n",
|
|
"\n",
|
|
"| name | type | description |\n",
|
|
"| ---- | ---- | ----------- |\n",
|
|
"|cost_function_evals|integer|The number of cost function (energy) evaluations.|\n",
|
|
"|optimal_parameters|null|Not supported at the moment, therefore ``None``.|\n",
|
|
"|optimal_point|array|The optimal parameter values found during the optimization. This is a numpy array.|\n",
|
|
"|optimal_value|number|The smallest value found during the optimization. Equal to the ``eigenvalue`` attribute. This is a float.|\n",
|
|
"|optimizer_evals|integer|The number of steps of the optimizer.|\n",
|
|
"|optimizer_history|object|A dictionary containing information about the function evaluations (not necessarily the actual parameter value!): the current evaluation count, the parameters, the energy and the standard deviation.|\n",
|
|
"|optimizer_time|number|The total time taken by the optimizer. This is a float.|\n",
|
|
"\n",
|
|
"We will also add optional `QiskitRuntimeService` as an argument to use that to access real devices.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"With that information we can start drafting our pattern implementation in `vqe.py` file.\n",
|
|
"\n",
|
|
"What our pattern should do:\n",
|
|
"\n",
|
|
"1. parse input arguments\n",
|
|
"2. create run_vqe function that accepts estimator instance, creates VQE and runs calculation\n",
|
|
"3. decide which estimator to use and run vqe\n",
|
|
" - if runtime service was passed then create a session and run `run_vqe` function\n",
|
|
" - if runtime service was not passed then use stantard qiskit estimator\n",
|
|
"4. save results from vqe\n",
|
|
"\n",
|
|
"Roughly our VQE pattern will look like this. Full code can be found in [vqe.py](./source_files/vqe/vqe.py) file.\n",
|
|
"\n",
|
|
"```python\n",
|
|
"# vqe.py\n",
|
|
"\n",
|
|
"import ...\n",
|
|
"\n",
|
|
"def run_vqe(\n",
|
|
" initial_parameters,\n",
|
|
" ansatz,\n",
|
|
" operator,\n",
|
|
" estimator,\n",
|
|
" method\n",
|
|
"):\n",
|
|
" ...\n",
|
|
"\n",
|
|
"arguments = get_arguments()\n",
|
|
"\n",
|
|
"service = arguments.get(\"service\")\n",
|
|
"ansatz = arguments.get(\"ansatz\")\n",
|
|
"operator = arguments.get(\"operator\")\n",
|
|
"initial_parameters = arguments.get(\"initial_parameters\") \n",
|
|
"optimizer = ...\n",
|
|
"\n",
|
|
"...\n",
|
|
"\n",
|
|
"if service is not None:\n",
|
|
" # if we have service we need to open a session and create estimator\n",
|
|
" backend = arguments.get(\"backend\", \"ibmq_qasm_simulator\")\n",
|
|
" with Session(service=service, backend=backend) as session:\n",
|
|
" estimator = Estimator(session=session, options=options) # qiskit_ibm_runtime.Estimator\n",
|
|
" vqe_result = run_vqe( estimator=estimator, ...)\n",
|
|
"else:\n",
|
|
" # if we do not have a service let's use standart local estimator\n",
|
|
" estimator = QiskitEstimator() # qiskit.primitives.Estimator\n",
|
|
"\n",
|
|
"vqe_result, callback_dict = run_vqe(\n",
|
|
" initial_parameters=initial_parameters,\n",
|
|
" ansatz=ansatz,\n",
|
|
" operator=operator,\n",
|
|
" estimator=estimator,\n",
|
|
" method=method\n",
|
|
")\n",
|
|
"\n",
|
|
"save_result({\n",
|
|
" \"optimal_point\": vqe_result.x.tolist(),\n",
|
|
" \"optimal_value\": vqe_result.fun,\n",
|
|
" \"optimizer_evals\": vqe_result.nfev,\n",
|
|
" \"optimizer_history\": callback_dict.get(\"cost_history\", []),\n",
|
|
" \"optimizer_time\": callback_dict.get(\"_total_time\", 0)\n",
|
|
"})\n",
|
|
"\n",
|
|
"\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"At this point we have our pattern implemented. Now we need to actually run it. But before let's prepare input arguments from our VQE pattern."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{'ansatz': <qiskit.circuit.library.n_local.efficient_su2.EfficientSU2 at 0x7f8ee8de92b0>,\n",
|
|
" 'operator': SparsePauliOp(['YZ', 'ZI', 'ZZ', 'XX'],\n",
|
|
" coeffs=[ 0.398 +0.j, -0.398 +0.j, -0.0113+0.j, 0.181 +0.j]),\n",
|
|
" 'method': 'COBYLA',\n",
|
|
" 'service': None}"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"\n",
|
|
"from qiskit.circuit.library import EfficientSU2\n",
|
|
"from qiskit.quantum_info import SparsePauliOp\n",
|
|
"\n",
|
|
"from qiskit_ibm_runtime import QiskitRuntimeService, Estimator, Session, Options\n",
|
|
"\n",
|
|
"USE_RUNTIME_SERVICE = False\n",
|
|
"\n",
|
|
"service = None\n",
|
|
"if USE_RUNTIME_SERVICE:\n",
|
|
" service = QiskitRuntimeService(\n",
|
|
" channel='ibm_quantum',\n",
|
|
" instance='ibm-q/open/main',\n",
|
|
" token='<Your Token>',\n",
|
|
" verify=False\n",
|
|
" )\n",
|
|
"\n",
|
|
"operator = SparsePauliOp.from_list(\n",
|
|
" [(\"YZ\", 0.3980), (\"ZI\", -0.3980), (\"ZZ\", -0.0113), (\"XX\", 0.1810)]\n",
|
|
")\n",
|
|
"ansatz = EfficientSU2(operator.num_qubits)\n",
|
|
"\n",
|
|
"input_arguments = {\n",
|
|
" \"ansatz\": ansatz,\n",
|
|
" \"operator\": operator,\n",
|
|
" \"method\": \"COBYLA\",\n",
|
|
" \"service\": service,\n",
|
|
"}\n",
|
|
"\n",
|
|
"input_arguments"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"With arguments prepared we can create our qiskit serverless client, setup provider and run our pattern"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from qiskit_serverless import ServerlessClient\n",
|
|
"import os"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<ServerlessProvider: gateway-provider>"
|
|
]
|
|
},
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"serverless = ServerlessClient(\n",
|
|
" token=os.environ.get(\"GATEWAY_TOKEN\", \"awesome_token\"),\n",
|
|
" host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n",
|
|
")\n",
|
|
"serverless"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'vqe'"
|
|
]
|
|
},
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from qiskit_serverless import QiskitFunction\n",
|
|
"\n",
|
|
"if USE_RUNTIME_SERVICE:\n",
|
|
" function = QiskitFunction(title=\"vqe\", entrypoint=\"vqe.py\", working_dir=\"./source_files/vqe/\")\n",
|
|
"else:\n",
|
|
" function = QiskitFunction(title=\"vqe\", entrypoint=\"vqe.py\", working_dir=\"./source_files/vqe/\", dependencies=[\"qiskit_aer\"])\n",
|
|
"\n",
|
|
"serverless.upload(function)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<Job | 94ae450e-bb6f-46c3-a0b0-1ad12b91115f>"
|
|
]
|
|
},
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"job = serverless.run(\"vqe\", arguments=input_arguments)\n",
|
|
"job"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'QUEUED'"
|
|
]
|
|
},
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"job.status()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"{'result': {'0': 0.4223, '1': 0.3604, '2': 0.1073, '3': 0.11},\n",
|
|
" 'optimal_point': [2.51762813907937,\n",
|
|
" 1.532634671366952,\n",
|
|
" 6.968201754881848,\n",
|
|
" 1.8258529400009142,\n",
|
|
" 1.5453234923701027,\n",
|
|
" 3.905921764150066,\n",
|
|
" 1.6694898480396192,\n",
|
|
" 1.075020301957671,\n",
|
|
" 0.8048376424004327,\n",
|
|
" 2.823196594205023,\n",
|
|
" 2.9665234835014846,\n",
|
|
" 4.143832547893007,\n",
|
|
" 4.382722375425133,\n",
|
|
" 4.582108812661252,\n",
|
|
" 6.596830693043498,\n",
|
|
" 4.716678649450963],\n",
|
|
" 'optimal_value': -0.7029303910686284,\n",
|
|
" 'optimizer_time': 3.4171429999987595}"
|
|
]
|
|
},
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"job.result()"
|
|
]
|
|
}
|
|
],
|
|
"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.9.16"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|