{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# VQE with gradients, active spaces, and gate fusion\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial will explore the Variational Quantum Eigensolver, a hybrid quantum classical algorithm for determining the ground state energy of molecules. The first part of this tutorial will walk through the key aspects of the VQE algorithm and how to implement it with CUDA-Q. The following sections explore advanced topics: parallel gradients, active spaces, and gate fusion" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Basics of VQE" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The VQE algorithm is hybrid quantum-classical algorithm, meaning some subroutines run on a quantum computer or quantum simulator and others run on a traditional (super)computer. \n", "\n", "The goal is to take a parameterized quantum circuit and a qubit form of the molecular Hamiltonian, measure an expectation value that corresponds to the ground state energy of the molecule, and then repeat the process to variationally minimize the energy with respect to the parameters in the quantum circuit. The optimization is performed on a classical device while the expectation values are determined on a quantum device. See the figure below.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![VQE.png](./images/VQE.png)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next few cells will elaborate on each part of the VQE procedure and show you how to build a VQE simulation to compute the ground state energy of the water molecule." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Installing/Loading Relevant Packages" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Install the relevant packages.\n", "!pip install pyscf==2.6.2 openfermionpyscf==0.5 matplotlib==3.8.4 openfermion==1.6.1 -q" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import openfermion\n", "import openfermionpyscf\n", "from openfermion.transforms import jordan_wigner, get_fermion_operator\n", "\n", "import os\n", "import timeit\n", "\n", "import cudaq\n", "import matplotlib.pyplot as plt\n", "from scipy.optimize import minimize\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementing VQE in CUDA-Q" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like most quantum chemistry programs, the first step is to specify a molecular geometry, basis set, charge, and multiplicity. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "geometry = [('O', (0.1173, 0.0, 0.0)), ('H', (-0.4691, 0.7570, 0.0)),\n", " ('H', (-0.4691, -0.7570, 0.0))]\n", "basis = 'sto3g'\n", "multiplicity = 1\n", "charge = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The VQE procedure requires some classical preprocessing. The code below uses the PySCF package and OpenFermion to compute the Hartree Fock reference state and compute the integrals required for the Hamiltonian." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "molecule = openfermionpyscf.run_pyscf(\n", " openfermion.MolecularData(geometry, basis, multiplicity, charge))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, the Hamiltonian is built using `get_molecular_hamiltonian`. The Hamiltonian must then be converted to a qubit Hamiltonian consisting of qubit operators. The standard Jordan-Wigner transformation is used to perform this mapping. \n", "\n", "Finally, the Jordan-Wigner qubit Hamiltonian is converted into a CUDA-Q spin operator which can be used to evaluate an expectation value given a quantum circuit." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "molecular_hamiltonian = molecule.get_molecular_hamiltonian()\n", "\n", "fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)\n", "\n", "qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)\n", "\n", "spin_ham = cudaq.SpinOperator(qubit_hamiltonian)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, the quantum circuit needs to be defined, which models the wavefunction. This is done in CUDA-Q by specifying a CUDA-Q kernel. The kernel takes as an input the number of qubits, the number of electrons, and the parameters of the circuit ansatz (form of the wavefunction) yet to be defined. \n", "\n", "The number of qubits corresponds to the potential positions of electrons and is therefore twice the number of spatial orbitals constructed with the chosen basis set, as each can be occupied by two electrons. \n", "\n", "The Hartree-Fock reference is constructed by applying $X$ bitflip operations to each of the first $N$ qubits where $N$ is the number of electrons. Next, a parameterized ansatz is chosen. Theoretically, any set of operations can work as an ansatz, however, it is good practice to use an ansatz that captures the underlying physics of the problem. The most common choice for chemistry is the Unitary Coupled Cluster Ansatz with Single and Double excitations (UCCSD). This UCCSD hate operations are automatically added to the kernel with the `cudaq.kernels.uccsd(qubits, thetas, electron_num, qubit_num)` function. \n", "\n", "The STO-3G water molecuule UCCSD ansatz requires optimization of 140 parameters." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "140\n" ] } ], "source": [ "electron_count = 10\n", "qubit_count = 2 * 7\n", "\n", "\n", "@cudaq.kernel\n", "def kernel(qubit_num: int, electron_num: int, thetas: list[float]):\n", " qubits = cudaq.qvector(qubit_num)\n", "\n", " for i in range(electron_num):\n", " x(qubits[i])\n", "\n", " cudaq.kernels.uccsd(qubits, thetas, electron_num, qubit_num)\n", "\n", "\n", "parameter_count = cudaq.kernels.uccsd_num_parameters(electron_count,\n", " qubit_count)\n", "\n", "print(parameter_count)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The classical optimizer requires a custom cost function which is defined below. The `cudaq.observe()` function computes an expectation given the Hamiltonian and the kernel defined above." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def cost(theta):\n", "\n", " exp_val = cudaq.observe(kernel, spin_ham, qubit_count, electron_count,\n", " theta).expectation()\n", "\n", " return exp_val\n", "\n", "\n", "exp_vals = []\n", "\n", "\n", "def callback(xk):\n", " exp_vals.append(cost(xk))\n", "\n", "\n", "# Initial variational parameters.\n", "np.random.seed(42)\n", "x0 = np.random.normal(0, 1, parameter_count)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The final step is to run the optimization using the scipy minimize function and a selected optimizer, in this case COBYLA. " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UCCSD-VQE energy = -70.21455023422772\n", "Total number of qubits = 14\n", "Total number of parameters = 140\n", "Total number of terms in the spin hamiltonian = 1086\n", "Total elapsed time (s) = 3.9171073289999185\n" ] }, { "data": { "image/png": "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0SWJiIicoVbB5z//+Q+vvvoqt9xyi+3YDTfcQOfOnXnrrbdYunQpsbGxvPjiiwo+bsJkMjH6smhmL0rmi01pCj4iIuKUatXVtXr1arp3737G8e7du7NmzRoA+vXrR0qKVvN1JyO6VY7zWbM/k7Tsoot674aDWUz/cjt5xdr6QkRE6k6tgk9MTAxz58494/jcuXOJian8l35mZiYhISGXVp24lOgQP/rEVy6M+NXmmq/knJFXwn3vbeDDtSl8vUV7vomISN2pVfB55ZVXeP311+natSv33Xcf9913H926deONN97g1VdfBWD9+vXceuutdi32u+++IyEhAV9fX0JCQs65MnRmZibR0dGYTCays7PtWoOcX9Ug5y82HcYwjBq957lvdpB9apPTQ5kFdVabiIhIrYLPjTfeSHJyMtdeey1ZWVlkZWUxfPhwkpKSuP766wGYNGkSr732mt0K/fzzzxk7dix33303W7duZdWqVdxxxx1nvfbee++lS5cudvtsqbnhnSKweJrZl1HAtsM5F7z+h+1H+W77UdvPKVna301EROrORQ9uLisr45prruFf//oXM2fOrIuazlBeXs4jjzzC7Nmzuffee23HO3Q4c3uEOXPmkJ2dzbPPPssPP/xQL/XJ/wT4eDGsYwTfbD3Cl5vT6BoTfM5rTxaU8szXiQB0jw1mc0o2hzIVfEREpO5cdIuPl5cX27Ztq4tazmnTpk2kpaVhNpvp3r07kZGRDB8+nMTExGrX7dy5kxdeeIH33nsPs7lmX62kpOSMhRjl0oy6rBkA32w9Qmn5uddyemHBTk7kl9ImvBEvjuwMQGpWYY27yERERC5Wrbq67rzzzrMObq4r+/fvB+C5557j6aefZsGCBYSEhDBw4ECysrKAygBz++23M3v2bGJjY2t875kzZxIUFGR7VQ3Oltrr16oJTRpZyCooZcXujLNes3TXMb7cnIbZBC/f1JX4MH9MJigorSCrQKt/i4hI3aj1lhVz5syhZ8+ePPDAAzz22GPVXjU1depUTCbTeV9JSUm2FaCnT5/O6NGj6dGjB/PmzcNkMvHpp58CMG3aNNq3b8+dd955Ud9l2rRp5OTk2F6pqakX9X45k6eHmZGnprZ/ufnMLSxyisp46svtANzfP55uMcH4eHkQEegDaJyPiIjUnVotYJiYmMhll10GwO7du6udM5lMNb7PlClTGD9+/HmviY+P5+jRysGvvx3TY7FYiI+Pt60VtGzZMrZv385nn30GYOsuadKkCdOnT+f5558/6/0tFgsWi6XGNUvNjLosmn//coAfdx4np7CMID8v27mXvtvFsdwSWjTx59Gr2tiOx4T6cTSnmJSsQrrHaikEERGxv1oFn+XLl9vlw8PCwggLu/BO3j169MBisZCcnEy/fv2AykHWBw8eJC4uDqic9VVU9L9F89avX88999zDypUradmypV3qlZrrEBVIu4gAktLzWLD9CGMSKv93Wrkng/9uSMVkgpdv6oKPl4ftPbGhfqw7kEWKBjiLiEgdqVXwqbJ371727dvHlVdeia+vL4ZhXFSLT00FBgYyceJEZsyYQUxMDHFxccyePRuAm2++GeCMcHPixAkA2rdvT3BwsN1rkgsbdVkzXvo+iS83pTEmIY78knKmfl7ZxTWub3N6NQ+tdn1cqB+gri4REak7tQo+mZmZ3HLLLSxfvhyTycSePXuIj4/n3nvvJSQkxLaIoT3Nnj0bT09Pxo4dS1FREQkJCSxbtkyrQzuxEd2aMeuHJDYcOsmhzAL+vfIAadlFxIT68uQ1bc+4Praxgo+IiNStWg1ufvTRR/Hy8iIlJQU/Pz/b8VtvvZWFCxfarbjf8vLy4pVXXuHYsWPk5uayZMkSOnbseM7rBw4ciGEYau1xoPBAH65o1QSAZ7/ewfu/HgJg1qgu+Hmfmblj1OIjIiJ1rFYtPosXL2bRokVER0dXO966dWsOHTpkl8KkYRh9WTQr95ywTWu/vXesLQydLvZU8EnPLaa4rKLa+B8RERF7qFWLT0FBQbWWnipZWVmaISXVXN0xHD/vygATGeTDU9e2O+e1jf298ff2wDC46N3dRUREaqJWwad///689957tp9NJhNWq5WXX36ZQYMG2a04cX1+3p6M7RuHxdPMyzd1IcDH65zXmkym/3V3aWaXiIjUgVp1db388ssMGTKEDRs2UFpaypNPPsmOHTvIyspi1apV9q5RXNy04e2ZclVbvD0vnLNjQ/1ISs/TOB8REakTtWrx6dSpE7t376Zfv36MGDGCgoICRo0axebNm7VmjpxVTUIPQJxmdomISB2q9To+QUFBTJ8+3Z61iNgGOCv4iIhIXah18MnOzmbdunUcP37ctpdWlbvuuuuSCxP3pDE+IiJSl2oVfL799lvGjBlDfn4+gYGB1VZrNplMCj5Sa79t8amrlcBFRMR91WqMz5QpU7jnnnvIz88nOzubkydP2l5ZWVn2rlHcSHSIHyYTFJVVcCK/1NHliIhIA1Or4JOWlsbDDz981rV8RC6Ft6eZqCBfQON8RETE/moVfIYNG8aGDRvsXYsIADGhVcGnwMGViIhIQ1OrMT7XXXcdTzzxBDt37qRz5854eVVflO7GG2+0S3HinmJD/fh1fxYpmVq9WURE7KtWwef+++8H4IUXXjjjnMlkoqKi4tKqErcW19gfUFeXiIjYX62Cz+nT10Xs6X+7tKurS0RE7Ouixvhce+215OTk2H6eNWsW2dnZtp8zMzPp0KGD3YoT96RFDEVEpK5cVPBZtGgRJSUltp9feumlatPXy8vLSU5Otl914paqgs+x3BKKy9RtKiIi9nNRwccwjPP+LGIPIX5eBFgqe2EPn1Srj4iI2E+tprOL1CWTyWQb53NIW1eIiIgdXVTwMZlMZ2whoC0FpC5onI+IiNSFi5rVZRgG48ePx2KxAFBcXMzEiRPx96+cfvzb8T8ilyK2sYKPiIjY30UFn3HjxlX7+c477zzjGm1QKvYQq13aRUSkDlxU8Jk3b15d1SFSjbq6RESkLmhwszil3wYfzR4UERF7UfARp9QsxBezCUrKrWTkaeyYiIjYh4KPOCUvDzNRwZW7tB9Sd5eIiNiJgo84LQ1wFhERe1PwEaelAc4iImJvCj7itKrW8klV8BERETtR8BGnVdXiozE+IiJiLwo+4rTU1SUiIvam4CNOqyr4ZOSVUFRa4eBqRESkIVDwEacV7OdNoE/l4uJq9REREXtQ8BGnps1KRUTEnhR8xKk58zifI9lF/POnvWQXljq6FBERqSEFH3FqMaHOO6X91cW7eXlhMr//cBMVVu0nJiLiChR8xKnFhfoDcCizwMGVnGlTykkAVu/L5B/L9zq4GhERqQkFH3FqztrVlV1YyoET/wtjb/y4m7X7Mx1YkYiI1ISCjzi1quCTerIIqxN1J209nANA88Z+jLqsGVYDHpm/hawCjfcREXFmCj7i1KKCffAwmygtt3I8r8TR5dhsSckGoGtMMH8a0Yn4MH/Sc4t5/NOtGIbzBDQREalOwUecmqeHmWbBvoBzjfPZejgbgG4xwfhbPPn77Zfh7WlmWdJx5v5ywLHFiYjIOSn4iNNztnE+hmGwJTUbqGzxAegQFcgz13cA4C8Lk2znayIzv4QlO49RXmG1c6UiInI6BR9xes42pf3wySKyCkrx8jDRITLQdvzOhFiu7RxBWYXBQx9vIre47Lz3KS6rYM5P+xg4+yfuf28D/1i+r65LFxFxewo+4vTiGjvXLu1VrTntIwPx8fKwHTeZTMwc1YXoEF9Ss4qY+vm2s473MQyDr7ekMeTVFfxlYRJ5JeUAfL01TeODRETqmEsFn++++46EhAR8fX0JCQlh5MiRZ1zz7rvv0qVLF3x8fGjatCmTJ0+u/0LFrpytq6sq+HQ71c31W0G+Xvz9jsvwNJv4fns6H65NqXZ+w8EsRv5zNY/M30JadhERgT68+LtOeHuY2Z9RwN7j+fXwDURE3Jenowuoqc8//5z777+fl156icGDB1NeXk5iYmK1a1577TVeffVVZs+eTUJCAgUFBRw8eNAxBYvdxDpZV9fWqvE90cFnPd8tJpg/XtOOF7/fxQsLdtIjLgQ/bw9m/ZDED4npAPh5ezBpQEvu6x+Pr7cHP+48xvLkDH5ITKd1eEA9fRMREffjEsGnvLycRx55hNmzZ3Pvvffajnfo0MH255MnT/L000/z7bffMmTIENvxLl261GutYn9VY3xO5JdSUFKOv8Vxf23LKqxsT6tcw6dbbPA5r7u3XwtW7zvB8uQMxs5dR05RKWUVBmYT3NorhkevakPTAB/b9cM7RbI8OYOFiek8PKR1XX8NERG35RJdXZs2bSItLQ2z2Uz37t2JjIxk+PDh1Vp8lixZgtVqJS0tjfbt2xMdHc0tt9xCamrqee9dUlJCbm5utZc4lyBfL4L9vADHd3clp+dRUm4lwMeTFo39z3md2Wzi1Vu6ER5o4UR+CWUVBle2CeOHR65k5qgu1UIPwNAO4XiYTew8mktKpnO0bImINEQuEXz2798PwHPPPcfTTz/NggULCAkJYeDAgWRlZdmusVqtvPTSS7zxxht89tlnZGVlcdVVV1Faeu7VdGfOnElQUJDtFRMTUy/fSS6Os4zz+e34HrPZdN5rQ/29mTuuF6Mua8Z/7unNe/f0pm3E2buxQv29SWgRCsDCHUftWrOIiPyPQ4PP1KlTMZlM530lJSVhtVaubzJ9+nRGjx5Njx49mDdvHiaTiU8//RQAq9VKWVkZb775JsOGDaNPnz58/PHH7Nmzh+XLl5+zhmnTppGTk2N7XaiFSBzDWaa0X2h8z+k6NQvitVu6MaBN2AWvvaZTBAALT40DEhER+3PoGJ8pU6Ywfvz4814THx/P0aOV/wL+7Zgei8VCfHw8KSmVs2YiIyPPuCYsLIwmTZrYrjkbi8WCxWKp7VeQelLV4nPIwd1A55vRdamGdYzg2a93sCklm/ScYiKCfC78JhERuSgODT5hYWGEhV34X8I9evTAYrGQnJxMv379ACgrK+PgwYPExcUBcMUVVwCQnJxMdHQ0AFlZWZw4ccJ2jbiuOCfo6sorLmNvRuV08651EHzCA324LDaYTSnZLN6Zzl19m9v9M0RE3J1LjPEJDAxk4sSJzJgxg8WLF5OcnMykSZMAuPnmmwFo06YNI0aM4JFHHmH16tUkJiYybtw42rVrx6BBgxxZvtiBM0xp3344B8OAZsG+hAXUTSvh8E6VLZc/bFd3l4hIXXCJ4AMwe/ZsbrvtNsaOHUuvXr04dOgQy5YtIyQkxHbNe++9R0JCAtdddx0DBgzAy8uLhQsX4uXl5cDKxR6qxvgcPllEhfX8qxtbL3C+trb8ZmPSujKsY+U4n7UHMskqOPegfBERqR2XWMcHwMvLi1deeYVXXnnlnNcEBgYyd+5c5s6dW4+VSX2ICvbF02yitMJKem4xzYJ9MQyD1KwiEo/ksONIDjuO5LLjSC45hWW8dmtXru8SZdcatqRkA3UbfGIb+9EhMpCdR3NZsjOdW3vF1tlniYi4I5cJPuLePMwmokN8OZhZyJ8X7CSroJSdR3PJKy4/6/WP/ncLQb5e9G994TFkNbX1VItPXYzv+a3hnSLYeTSXhYkKPiIi9uYyXV0isacWDPwhMZ21B7LIKy7H28NMp2aB3NozhhdGdOTzSX25oWsUZRUGD7y/0Tb9/FIdzSniWG4JHmYTnZoFXvgNl6BqWvuqvZkX3OFdREQujlp8xGX8fmBLvD1MRIf40TEqkI5RQbQOb4SXR/X83rlZMNmFpazcc4K7313PpxP70jKs0SV9dlWAahMegJ933f7fpnV4AC3D/NmXUcDypOOM6NasTj/vdIZhsPNoLm3CA854tiIirk7/VROX0Se+Mf8e14vnbuzIzT1j6BAVeNZfzN6eZubc2YMu0UFkFZRy19x1HMstvqTP3pJ6an+uOu7mquLIxQz//N0urnvzF/62bG+9f7aISF1T8JEGqZHFk3njexHfxJ+07CLumruOnMLadxttST0JQLeYIHuVeF5V09p/Ss6gqLSiXj4TKoPW3F8OAPDl5sMYRt3MkBMRcRQFH2mwGjey8J97ehMeaCH5WB73/md9rUJEhdVg++GqFp+QC1xtHx2jAokO8aWorIIVuzPq5TNTswp54rOtv/m5iKT0vHr5bBGR+qLgIw1aTKgf/7mnN4E+nmw4dJIHP9pEeYX1ou6x93g+BaUV+Ht70KrppY0VqimTycQ1Hau6u+p+09KS8gomf7SJvOJyLosNtu0ttnjHsTr/bBGR+qTgIw1eu4hA5o7vhcXTzNKk40z7YvtFdeFUDWzuHB2ExwV2ZLenqnE+S3cdp7T84sLaxZr5fRLbDucQ7OfF3+64jOs6V3a1Ld6pFaRFpGFR8BG30Kt5KH+/4zI8zCY+3XiYvyxMrvF7N1ftyF5PA5urXBYbQliAhbySclbtO1Fnn7Mw8Sjvrj4IwKs3d6VZsC9D2jfFbIIdR3I5fNKxG8OKiNiTgo+4jas6hDPzd50B+NeKfXyyPrVG76tq8elez8HHbDYxrGM4AIvqaHZXSmYhT3y2DYAHroxnSPvKz2vcyELP5qEALNmp7i4RaTgUfMSt3NIrhseuagPAc9/u4FBmwXmvLyqtIPlY5QDf+m7xAbimY1WX07EL7lF2sX47rqdHXAiPD2tb7fzVHSpDkMb5iEhDouAjbmfyoFYktAilsLSCR/+75byDnROP5FBhNQgPtBAZ5FuPVVZKiA8l2M+LrIJS1h3Isuu9Z36fxPa0U+N6bu9+xppIV3eoHGO07mAWJ7Vhqog0EAo+4nY8zCZevaUrjSyebErJ5q2f95/z2qqNSbtGB9dPcafx8jAz9FT306Id9uvu+mH7/8b1vH5LN6KCzwx1sY39aBcRQIXVYGnScbt9toiIIyn4iFuKDvHj+Rs7AvD6kt0kpuWc9botpzYm7RYbXE+VnWn4b1Zxttqhu+tQZgFPnhrXM3FASwa1a3rOa68+NaV+sR1Dl4iIIyn4iNsadVkzhneKoNxq8If/bqG47MzFDatafLo5qMUH4IpWTfD39iA9t9i2Q3xt2cb1lJTTMy6EKVe3Oe/1VYOrf95TvytIi4jUFQUfcVsmk4mXfteZpgEW9h7PZ9YPSdXOZ+SVkJZdhMlUuYaPo/h4eTD4VHfXl5vTLuleb63YT2JaLiF+Xrx5lnE9p+sQGUizYF+Ky6ys3FM/K0iLiNQlBR9xayH+3rx8UxcA3l19sNov96pp7K3CGhHg4+WI8mxu6xUDwCcbUsnML6nVPQpLy3lnVeU+XM/d2PGs43pOZzKZuPpUq89iTWsXkQZAwUfc3sC2TRnbJw6Axz/dSnZh5Qymqm6l+tqR/Xwub9mYzs2CKC6z8t6aQ7W6x/x1qWQXltG8sR/Xd4mq8fuqZnct3XXsorf7EBFxNgo+IsC0a9sR38SfY7klPPP1DgC2OGjF5rMxmUw8MCAegP+sOUhhaflFvb+swsq/V1bOXptwZcuL2nqjV/MQgv28OFlYxvqDJy/qc0VEnI2Cjwjg5+3Ja7d2w8Ns4tutR/hqc5qtq8sZWnwAhneKJK6xH9mFZfy3hqtOV/lmyxGO5BQTFmBh1GXNLuq9nh5mhrSr6u7S7C4RcW0KPiKndIsJ5uHBrQH44+fbyC0ux+Jppm1EgIMrq+RhNnF//8pWn3+vPEBZDbudrFaDf63YB8C9/Vrg4+Vx0Z9tG+ez49hFbfAqIuJsFHxEfmPyoJZ0jQmm5NRu6J2bBV1w5lN9uqlHNE0aeZOWXcSCbUdq9J6lScfZczyfAIsndyTE1upzr2wdho+XmbTsInYeza3VPUREnIHz/BddxAl4eph5/Zau+J5qFXGG8T2/5ePlwd1XtAAqp6ZfqPXFMAzm/LQXgDv7xhFYy9lpvt4eXNk6DNDeXSLi2hR8RE4TH9aIV27uSseoQG7pGePocs5wZ0Ic/t4eJKXn8VPy+dfWWX/wJJtSsvH2NHP3Fc0v6XOrVnG259YZIiL1TcFH5Cyu6xLJdw/3d5rxPb8V5OfF7b0ru6yqxu6cS1Vrz009omka4HNJnzukXVPMJkhKzyMls/CS7iUi4igKPiIu6N7+LfDyMLH2QBabU84+xXzX0VyWJ2dgNsGEU4OiL0WIvze9W4QCmt0lIq5LwUfEBUUG+TKiW+W09HO1+rx16vi1nSNp3sTfLp9btZihVnEWEVel4CPioiaeWtBw8c5j7MvIr3YuNauQb7cdPXVdS7t9ZtW09g0Hs2q9dYaIiCMp+Ii4qFZNAxjaPhzDgLdX7K927t8r91NhNejfugmdmtlvg9XoED86RgViNSqnyYuIuBoFHxEXNmlgZavPl5vTOJZbDMCJ/BLmn1rZedJA+7X2VLF1d2l2l4i4IAUfERfWIy6UnnEhlFZYeeeXyp3X/7P6ICXlVrpGB9E3vrHdP7Oqu+vnPScoKLm4PcNOV1xWwXfbjpJTWGaP0kRELkjBR8TFVY3h+XBtCuk5xbbd2ycNbInJVPPNSGuqXUQAMaG+lJZbWbnn/OsInU9ZhZWJH2xk8kebGDP3V0rLtfO7iNQ9BR8RFze4XVNaN21Efkk5d85dS05RGfFh/rYuKXszmUwMO3Xvl75P4kh20UXfwzAMpn6+3bYAY2JaLrMXJdm1ThGRs1HwEXFxZrOJB061+uw9Xjm764Er4zGb7d/aU2XClfHEhPqSklXI7f/360WHn5cXJfP5psN4mE3c169yC47/W3mA5ckaMC0idUvBR6QBuLFrFJFBlSszhwdaGNm9WZ1+XtNAH+ZP6EtMqC+HMivDz9GcmoWfeasOMOenyjWGZo7qzNPXd2Bc3zgAHv9kK8fziuusbhERBR+RBsDb08yUq9sCMOWqtlg8Per8M5sF+1YLP7e9feHw8+3WI7ywYCcATwxra9sLbdq17WkXEUBmQSlTPtmK1Xr+zVdFRGpLwUekgbipRzTJf76GW3rV38aqzYJ9+fj+PjUKP6v3nmDKJ1sxDLirbxy//81Uex8vD/5+R3d8vMys3HOCt1fuP+s9REQulYKPSANSHy09p4sO8ePj+/sQHXKq2+ss4ScxLYcJ72+ktMLKtZ0jmHFDxzNmnLVqGsBzN3QE4JVFyWxJza6vryAibkTBR0QuWXSIH/MnVIafg6fCT3pO5Vid1KxCxs9bT35JOX3iQ3ntlm54nGPg9a29YriucyTlVoOHP95MXrHW9xER+1LwERG7OD383Pb2GnYcyeGud9ZxIr+EdhEBvH1XT3y8zt0qZTKZeGlUZ5oFV84Ye/qrRAxD431ExH5Mhv6rUk1ubi5BQUHk5OQQGBjo6HJEXM7hk5VjfQ6f/F93V7NgX774/eWEB/rU6B4bD2Vxy1u/UmE1eOXmrtzUI/qc15ZVWNmams2mlJP4eXvSLNiXyGAfIoN8CfTxrJNFHO3lWG4xIX7eeHvq36Ail6qmv78VfE6j4CNy6VJPre9z+GQRIX5efDbpclqGNbqoe/x92R5eWbwbP28PFjzUj/hT7zcMg/0nCvhlzwlW7jnBr/szyT/H1hmNLJ5EBvkQGexLs2AfooJ8GdI+nA5Rjv//9ntrDjLjmx3Ehvrx8uguJNTB9iIi7kTBp5YUfETsIy27iPfXHGJk9yjaRVz8/5cqrAZ3/nsta/Zn0jEqkAcGtOSXPRn8sucER3Kqr/UT4udFQovGlFsNjuYUcSS7iJPn2f/rilaNua9/PANah9XpQo/n8v6agzzz9Y5qx8Zf3pwnr2mLn7dnvdcj0hAo+NSSgo+I80jPKWb4X38+I8R4e5jp2TyEfq2b0L9VGB2jAs8IMEWlFRzJKeJodjFHsos4klNE0tE8luw6RsWpdYJaNW3Eff1aMLJ7s/OOPbKn34ae+/q1oKC0nI/XpQJUtv7c1IU+l9j6YxgGeSXlnCwoJauglJOFpeQUldG7RWOaBfte8ncQcUYNMvh89913vPDCC2zbtg0fHx8GDBjAV199ZTu/fv16pk6dysaNGzGZTPTu3ZuXX36Zrl271vgzFHxEnMtPycd56KPNNAvxpX/rJvRrHUbv5qH4etcuqBw+Wci7qw4yf32qrYussb83Y/vGMbZPHI0bWexZfjXv/3qIZ75KBCq3FZk6vB0mk4mfd2cw9fNttpascX3jePKadvhbzt/6k55TzMo9GazZl8mRnCJOFpSRVVjKyYJSys+yCGR0iC9LHh1Q62cn4swaXPD5/PPPuf/++3nppZcYPHgw5eXlJCYmcssttwCQn59PXFwcN954I1OnTqW8vJwZM2bwyy+/kJqaipeXV40+R8FHxD3kFZfx3/WpzFt1kLRTe41ZPM2MuqwZV3UIp11EIJFBPnYbHH2u0PPbel76PomP16UAEBPqy8uju9K35f9af4pKK1h3MIufd2ewck8Gu4/ln/cz/bw9CPHzJtTfm9SThWQXljFxQEumDm9nl+8k4kwaVPApLy+nefPmPP/889x7771nvWbDhg306tWLlJQUYmIqV67dvn07Xbp0Yc+ePbRq1apGn6XgI+Jeyius/JCYzr9X7mfr4Zxq5wJ9PGkXEUi7yADaRgTQLiKQthEBNLpAS8zpPvj1EE+fCj0Troxn2mmh57dW7slg6ufbbWFsbJ84YkJ9+Xn3CdYdzKK03Gq71mSCLtHB9G/VhDYRAYT6eRPi70Wovzchft7Vuu+W7DzG/e9twNNs4ruH+9M2IuCivoOIs2tQwWfdunUkJCTwzjvv8Oabb5Kenk63bt2YPXs2nTp1AiAvL48WLVrw4IMP8tRTT1FRUcG0adNYvHgx27Ztw9Pz7P+hKikpoaSkxPZzbm4uMTExCj4ibsYwDDYcOsnH61JITMthX0aBbSzQ6WJD/ejdIpTB7ZrSv3UTAnzO3aL84dpDTP+yZqGnSl5xGTN/SOKjtSlnnIsM8uHK1mH0b9OEK1o2IcTfu8bfccJ7G1i88xg940L45IG+tRrYvfd4Ho39LRf1uSL1oUEFn/nz53P77bcTGxvLa6+9RvPmzXn11VdZvHgxu3fvJjQ0FIDExERGjhzJgQMHAGjdujWLFi0iLi7unPd+7rnneP755884ruAj4t5KyivYd7yApPRcktLzKl9HczmeV1LtOk+zyRaCBrVrSnwTf1uw+W3oub9/C566tv1FdZ39sucEby7bg5+3B1e2DuPKNk1oGdao1t1vR7KLuOq1FRSUVjBrVGdu6x17Ue//eksaj8zfQpvwRnz/cH88PbT+kDgPlwg+U6dO5S9/+ct5r9m1axebNm1izJgxvPXWW0yYMAGobKmJjo7mz3/+Mw888ABFRUUMHDiQdu3a8eCDD1JRUcErr7xCUlIS69evx9f37DMZ1OIjIhcjq6CUxLQcVuzOYHnScfafKKh2Pq6xH4PaNiXI14u/Lt0DVM7emn7dxYWeuvLvlfv583e7CPL1YumUATSp4WDudQeyuPPfaymtqOxqmzmqM7dfZHASqUsuEXwyMjLIzMw87zXx8fGsWrWKwYMHs3LlSvr162c7l5CQwNChQ3nxxReZO3cuTz31FEePHsVsrvxXSGlpKSEhIcydO5fbbrutRjVpjI+IXIyDJwpYlnSc5cnHWbs/yxYMqjhT6IHKMU03/n0VO4/mMqp7M167tdsF37M/I59Rc1aTXVhGs2Bf0rKLCA+08NPjgzRDTJxGTX9/O3SlrLCwMMLCwi54XY8ePbBYLCQnJ9uCT1lZGQcPHrR1YxUWFmI2m6v9x6XqZ6vVetb7iohcquZN/LmnXwvu6deCgpJyftl7guVJx1l7IIvru0Ty2FVtnCb0AHh6mHlpVGd+989VfLE5jZt6RHN5qybnvD4zv4S7311PdmEZXWOCee+e3lz715WkZRfx7uqDTBrYsh6rF7l0LtFBGxgYyMSJE5kxYwaLFy8mOTmZSZMmAXDzzTcDcNVVV3Hy5EkmT57Mrl272LFjB3fffTeenp4MGjTIkeWLiJvwt3gyrGMEs0Z3YfnjA5lydVunCj1VusUEM7ZP5T8an/4qkZLyirNeV1xWwf3vbeBQZiExob78+66eBPl68dhVbQCY89Necs6zQraIM3KJ4AMwe/ZsbrvtNsaOHUuvXr04dOgQy5YtIyQkBIB27drx7bffsm3bNvr27Uv//v05cuQICxcuJDIy0sHVi4g4l8eHtSUswML+EwXM+WnfGeetVoMpn2xlU0o2gT6ezBvfi7CAyvFAI7s3o214ALnF5cxZceZ7RZyZS8zqqk8a4yMi7uLbrUd46OPNeHuYWfiH/raNYAFm/ZDEv1bsw8vDxHv3JFRbSBFg6a5j3PufDVg8zax4YhARQT71Xb5INTX9/e0yLT4iImJf13eJ5Mo2YZRWWHn6q0Sq/h388boU/nWqJecvo7ucEXoABrdrSs+4EErKrbbZayKuQMFHRMRNmUwm/jyiExZPM6v3ZfLVljRW7M6wrTL9h6GtGXVZ9DnfW7X1xScbUtmXcf7tM0SchYKPiIgbi23sx8NDWgPwpwW7mPzhJiqsBqMua8Yjp46fS8/moQxt35QKq8Gri5Pro1yRS6bgIyLi5u7vH0/rpo3IKiglv6ScvvGNmTWqS41mpD0+rC0mE3y/PZ2tqdl1X6zIJVLwERFxc96elWv7eJpNtG7aiH/d2QNvz5r9emgXEcjvujcD4OVFSXVZpohdOHQBQxERcQ69moey4slBhPh54ed9cb8aHh3ahgVbj7JqbyYr92TQv/WFF6a1hwqrwbxVBygsraBTs0A6RQXRNFCzy+T8FHxERASAZsFn39PwQmJC/RjTJ5Z5qw7yl4VJXNGyyXl3fq9a4Tq+iT+twwNq9ZnFZRX8Yf4WFu5Ir3Y8LMBCp6hAOjULomNUEB2jAokO8XXKhSTFMRR8RETkkj04qBWfrE8lMS2X77Yf5YauUdXOF5SUszTpON9tO8JPyRmUlFvx9jDzp5EdubXXxW12ml9SzoT3NrB6XybeHmau6hjOnmN57D2eT0ZeCcuTM1ienGG7PsjXizv7xPK4k66kLfVLwUdERC5Z40YW7r8ynjd+3MOri5O5plMEJeVWlu46xvfbj9rCTpUQPy9OFpbxx8+3s/VwDjNu6IDF88IbnlbtHbbtcA7+3h783109bXuNFZVWsCs9lx1pOSSm5ZJ4JIfdx/LIKSrjH8v30SkqiOGdtZK/u9PKzafRys0iIrWTX1LOgJeXk1lQStfoIJLS86qFneaN/biuSyTXdo6kfUQgc1bs45XFyRhG5f5hc+68jMigc3e3pWUXMXbuWvZnFBDq7827d/eiS3TweWsqKa/gtcW7eevn/YQFWPjx0QEE+XnZ6yuLE6np728Fn9Mo+IiI1N67qw7w3Lc7bT//Nux0iAw8o6vpp+TjPDJ/CzlFZTRp5M3f77iMPvFnrhS993geY+eu42hOMVFBPrx3bwKtmjY647qzKS6r4No3V7I/o4DbesUwa3SXS/uS4pQUfGpJwUdEpPbKKqy8vmQ3ZpOJ4Z0jzhp2TpeSWcgDH2xk19FcPMwmpl/bnruvaG5739bUbMbPW8fJwjJahvnz/r0JRF3kQOx1B7K45a01AHx8f5+zbsMhrk3Bp5YUfERE6l9RaQVTv9jG11uOADCiWxSzRnVhU8pJJry3gYLSCrpGBzHv7t6E+nvX6jOe+nI7H61NoUUTf354pD8+XhceUySuQ8GnlhR8REQcwzAM3l19kD9/t4sKq0F8mD+Hs4oorbByRavGvDW2J40stZ+Tk1tcxtBXV3A8r4TfD2zJk9e0s2P14mjanV1ERFyKyWTi7ita8NF9CTRp5M3+jAJKK6wM7xTBO+N7XVLoAQj08eJPIzsB8NbP+9l5JNceZYuLUfARERGnkhDfmAUP9ee6LpFMHtSSv99xWY2mutfEsI4RXNMxggqrwdQvtlFhVaeHu1HwERERpxMR5MM/7riMJ4a1w+M8q0DXxvMjOhLg48m2wznMW3XArvcW56fgIyIibiU80Ienrm0PwKuLd5OaVejgiqQ+KfiIiIjbubVnDAktQikqq2D6V4lono/7UPARERG3YzabmDmqM96eZn7encFXW9IcXZLUEwUfERFxS/FhjXhkSGsAXvh2J5n5JQ6uSOqDgo+IiLitCVfG0y4igJOFZTzzdaJmebkBBR8REXFbXh5mZo3ugtkE329PZ+IHGykqrXB0WVKHFHxERMStdYsJ5m+3X4a3p5klO49x29tryMirm26vXUdzefG7nbzzi6bRO8qlLYMpIiLSAFzXJZKmgRbuf28DWw/nMGrOKt69uzctw2q2A/z5FJVW8O22I3y8LoXNKdm24+0iAri8VZNLvr9cHO3VdRrt1SUi4r72Z+Qzft56UrIKCfL14v/u6knvFqG1uldSei4fr03hi81p5BWXA+BpNhEb6sf+EwV0iAzk24f62X2BRnelTUprScFHRMS9ZeaXcN97G9icko23h5lXbunKjV2javTeotIKFpxq3dn0m9ad2FA/busdw809YvAwmxgwezl5xeW8fFMXbukZU0ffxL0o+NSSgo+IiBSXVfCH+VtYuCMdgCevacukAS0xmaq3zhSVVrAp5SRr92ey9kAWm1OzKS23ApWtO1d3DOf23rFc0bIJ5t+07Pzfz/t58ftdNA2wsPzxgfhf4gasouBTawo+IiICUGE1eOn7Xcw9NRD59t6x/PGatmxOzWbdgSzW7s9k2+Ecyk+bAh8T6sttvWK5uWc0TQN8znrvkvIKrnrtZ1KyCnl4SGseu6pNnX+fhk7Bp5YUfERE5LfmrTrACwt2cq7flpFBPiS0CKV3i8YkxIcS38T/jJahs/lh+1EmfbgJHy8zyx8fSGSQr50rdy81/f2ttjUREZHzuPuKFjQL9uXh+ZspLrMSG+p3KuiE0ie+MdEhvjUKOqe7plMEvZuHsu5gFrMXJfPaLd3sX7ycQS0+p1GLj4iInE1GXgkVVoOIoLN3X9XGtsPZ3Pj3VQB88+AVdIkOttu93U1Nf39rAUMREZEaCAuw2DX0AHSJDmZU92YA/Pm7Xdolvh4o+IiIiDjQ48Pa4uNlZt2BLBbtOObocho8BR8REREHigr2ZUL/eABm/rCLknLtFVaXFHxEREQc7IEBLQkLsHAos5D31xxydDkNmoKPiIiIg/lbPHni6rYA/HXpHrIKSh1cUcOl4CMiIuIERveIpn1kIHnF5by5dI+jy2mwFHxEREScgIfZxNPXtQfg/V8Psfd4voMrapgUfERERJzEFa2aMLR9UyqsBk9+tpXFO9LJKSpzdFkNihYwPI0WMBQREUfal5HPNW/8TFlF5a9nswk6NQuib3xj+rZsTK/modrU9Cy0V1ctKfiIiIijbUnN5rONqazel8n+jIJq5zzNJrrGBHN5y8YMbteUbjHBtdoyo6FR8KklBR8REXEmx3KLWbMvk9X7TrBqbyZp2UXVzneJDmL85c25rkskFk8PB1XpeA0q+Pz0008MGjTorOfWrVtHr169ANi2bRuTJ09m/fr1hIWF8dBDD/Hkk09e1Gcp+IiIiDNLzSpk9b4TrNxzgsU7j1FabgWgSSMLYxJiGdMnlqYB9t1awxU0qOBTWlpKVlZWtWPPPPMMS5cuZd++fZhMJnJzc2nTpg1Dhw5l2rRpbN++nXvuuYc33niDCRMm1PizFHxERMRVZBWU8vG6FN5fc4j03GIAvDxMXNc5kruvaEHXmOBL/gzDMPh8Uxq5RWWMv7w5ZrNzdqs1qOBzurKyMpo1a8ZDDz3EM888A8CcOXOYPn066enpeHt7AzB16lS++uorkpKSanxvBR8REXE1ZRVWFu1IZ96qg2w8dNJ2vHtsMA9c2ZJrOkXU+r5Pf5nIfzekAnBnn1j+NKKTU44patC7s3/zzTdkZmZy9913246tWbOGK6+80hZ6AIYNG0ZycjInT548220AKCkpITc3t9pLRETElXh5mLm+SxSfT7qcbx68glGXNcPbw8zmlGwmfrCRxz7ZQkFJ+UXdM7e4jHveXc9/N6RiNoHJBB/8msKshUkuvYu8SwafuXPnMmzYMKKjo23H0tPTCQ8Pr3Zd1c/p6ennvNfMmTMJCgqyvWJiYuqmaBERkXrQJTqY127pxqqpg5k4oCVmE3yxKY3r//YLiWk5NbpHWnYRN89Zw8o9J/D18uDtsT156XedAXhrxX7+sXxvXX6FOuXQ4DN16lRMJtN5X6d3Ux0+fJhFixZx77332qWGadOmkZOTY3ulpqba5b4iIiKOFBZgYerwdsyf0JfIIB8OnChg1D9X884vB87bYrP9cA4j/7GK5GN5NA2w8OnEvgztEM7tvWNtK0u/sng37/xyoL6+il05dAWkKVOmMH78+PNeEx8fX+3nefPm0bhxY2688cZqxyMiIjh27Fi1Y1U/R0Scu2/TYrFgsVguomoRERHX0btFKN8/3J8nP9/Gkp3HeGHBTlbvO8HLN3Ul1N+72rVLdh7j4Y83U1RWQbuIAN4Z34uoYF/b+fv6x5NfUs4bP+7hhQU7aWTx5JZertVT4tDgExYWRlhYWI2vNwyDefPmcdddd+Hl5VXtXN++fZk+fTplZWW2c0uWLKFt27aEhITYtW4RERFXEuLvzdtje/D+r4f484Jd/LjrONf+dSVv3NaNPvGNAZi36gAvLNiJYUD/1k3455jLCPDxOuNejwxpTUFJOf+38gB//GIbvt4e3NA1qr6/Uq251KyupUuXMnToUHbt2kW7du2qncvJyaFt27ZcffXV/PGPfyQxMZF77rmH119/XdPZRURETtlxJIeHPt7M/owCzCZ4aHBrcorKeHf1QQBu7x3DCyM64eVx7tEwhmEw/atEPlqbgqfZxL/u7MHQDuHnvP7099bFrLAGOZ39jjvu4NChQ6xateqs53+7gGGTJk146KGH+OMf/3hRn6HgIyIiDV1BSTkzvtnBZxsPVzs+dXg7HrgyvkbBxGo1eOyTLXy15Qjenmbmje/FFa2aVLumrMLKvox8dqTlsuNILjuO5JB8LI/VUwfj523fTqcGGXzqg4KPiIi4i682pzH9y+2UWQ1eu6Ur13e5uC6rsgorv/9wE0t2HsPP24OZozqTW1zOziM57DiSS1J6nm1l6d/6fNLl9Iiz7zAUBZ9aUvARERF3kl1YSmmFtdbbXJSUV3Dffzawcs+Js55vZPGkQ2QgHaIC6RgVSMeoIFqHNzpvV1pt1PT3t/a1FxERcWPBft4Xvug8LJ4evDW2B5M/3MTOo7m0i/hfwOkYFUhsqJ9TbXOh4CMiIiKXxM/bk3l393Z0GTXikis3i4iIiNSGgo+IiIi4DQUfERERcRsKPiIiIuI2FHxERETEbSj4iIiIiNtQ8BERERG3oeAjIiIibkPBR0RERNyGgo+IiIi4DQUfERERcRsKPiIiIuI2FHxERETEbSj4iIiIiNvwdHQBzsYwDAByc3MdXImIiIjUVNXv7arf4+ei4HOavLw8AGJiYhxciYiIiFysvLw8goKCznneZFwoGrkZq9XKkSNHCAgIwGQy2e2+ubm5xMTEkJqaSmBgoN3uK9XpOdcfPev6oedcP/Sc60ddPmfDMMjLyyMqKgqz+dwjedTicxqz2Ux0dHSd3T8wMFD/p6oHes71R8+6fug51w895/pRV8/5fC09VTS4WURERNyGgo+IiIi4DQWfemKxWJgxYwYWi8XRpTRoes71R8+6fug51w895/rhDM9Zg5tFRETEbajFR0RERNyGgo+IiIi4DQUfERERcRsKPiIiIuI2FHzqyT/+8Q+aN2+Oj48PCQkJrFu3ztElubSff/6ZG264gaioKEwmE1999VW184Zh8OyzzxIZGYmvry9Dhw5lz549jinWhc2cOZNevXoREBBA06ZNGTlyJMnJydWuKS4uZvLkyTRu3JhGjRoxevRojh075qCKXdOcOXPo0qWLbVG3vn378sMPP9jO6xnXjVmzZmEymfjDH/5gO6Znfemee+45TCZTtVe7du1s5x39jBV86sF///tfHnvsMWbMmMGmTZvo2rUrw4YN4/jx444uzWUVFBTQtWtX/vGPf5z1/Msvv8ybb77Jv/71L9auXYu/vz/Dhg2juLi4nit1bStWrGDy5Mn8+uuvLFmyhLKyMq6++moKCgps1zz66KN8++23fPrpp6xYsYIjR44watQoB1bteqKjo5k1axYbN25kw4YNDB48mBEjRrBjxw5Az7gurF+/nrfeeosuXbpUO65nbR8dO3bk6NGjttcvv/xiO+fwZ2xInevdu7cxefJk288VFRVGVFSUMXPmTAdW1XAAxpdffmn72Wq1GhEREcbs2bNtx7Kzsw2LxWJ8/PHHDqiw4Th+/LgBGCtWrDAMo/K5enl5GZ9++qntml27dhmAsWbNGkeV2SCEhIQY//73v/WM60BeXp7RunVrY8mSJcaAAQOMRx55xDAM/X22lxkzZhhdu3Y96zlneMZq8aljpaWlbNy4kaFDh9qOmc1mhg4dypo1axxYWcN14MAB0tPTqz3zoKAgEhIS9MwvUU5ODgChoaEAbNy4kbKysmrPul27dsTGxupZ11JFRQXz58+noKCAvn376hnXgcmTJ3PddddVe6agv8/2tGfPHqKiooiPj2fMmDGkpKQAzvGMtUlpHTtx4gQVFRWEh4dXOx4eHk5SUpKDqmrY0tPTAc76zKvOycWzWq384Q9/4IorrqBTp05A5bP29vYmODi42rV61hdv+/bt9O3bl+LiYho1asSXX35Jhw4d2LJli56xHc2fP59Nmzaxfv36M87p77N9JCQk8O6779K2bVuOHj3K888/T//+/UlMTHSKZ6zgIyI1MnnyZBITE6v11Yv9tG3bli1btpCTk8Nnn33GuHHjWLFihaPLalBSU1N55JFHWLJkCT4+Po4up8EaPny47c9dunQhISGBuLg4PvnkE3x9fR1YWSV1ddWxJk2a4OHhccaI9WPHjhEREeGgqhq2queqZ24/Dz74IAsWLGD58uVER0fbjkdERFBaWkp2dna16/WsL563tzetWrWiR48ezJw5k65du/LXv/5Vz9iONm7cyPHjx7nsssvw9PTE09OTFStW8Oabb+Lp6Ul4eLiedR0IDg6mTZs27N271yn+Piv41DFvb2969OjB0qVLbcesVitLly6lb9++Dqys4WrRogURERHVnnlubi5r167VM79IhmHw4IMP8uWXX7Js2TJatGhR7XyPHj3w8vKq9qyTk5NJSUnRs75EVquVkpISPWM7GjJkCNu3b2fLli22V8+ePRkzZoztz3rW9pefn8++ffuIjIx0jr/P9TKE2s3Nnz/fsFgsxrvvvmvs3LnTmDBhghEcHGykp6c7ujSXlZeXZ2zevNnYvHmzARivvfaasXnzZuPQoUOGYRjGrFmzjODgYOPrr782tm3bZowYMcJo0aKFUVRU5ODKXcukSZOMoKAg46effjKOHj1qexUWFtqumThxohEbG2ssW7bM2LBhg9G3b1+jb9++Dqza9UydOtVYsWKFceDAAWPbtm3G1KlTDZPJZCxevNgwDD3juvTbWV2GoWdtD1OmTDF++ukn48CBA8aqVauMoUOHGk2aNDGOHz9uGIbjn7GCTz3529/+ZsTGxhre3t5G7969jV9//dXRJbm05cuXG8AZr3HjxhmGUTml/ZlnnjHCw8MNi8ViDBkyxEhOTnZs0S7obM8YMObNm2e7pqioyPj9739vhISEGH5+fsbvfvc74+jRo44r2gXdc889RlxcnOHt7W2EhYUZQ4YMsYUew9AzrkunBx8960t36623GpGRkYa3t7fRrFkz49ZbbzX27t1rO+/oZ2wyDMOon7YlEREREcfSGB8RERFxGwo+IiIi4jYUfERERMRtKPiIiIiI21DwEREREbeh4CMiIiJuQ8FHRERE3IaCj4jIaUwmE1999ZWjyxCROqDgIyJOZfz48ZhMpjNe11xzjaNLE5EGwNPRBYiInO6aa65h3rx51Y5ZLBYHVSMiDYlafETE6VgsFiIiIqq9QkJCgMpuqDlz5jB8+HB8fX2Jj4/ns88+q/b+7du3M3jwYHx9fWncuDETJkwgPz+/2jXvvPMOHTt2xGKxEBkZyYMPPljt/IkTJ/jd736Hn58frVu35ptvvrGdO3nyJGPGjCEsLAxfX19at259RlATEeek4CMiLueZZ55h9OjRbN26lTFjxnDbbbexa9cuAAoKChg2bBghISGsX7+eTz/9lB9//LFasJkzZw6TJ09mwoQJbN++nW+++YZWrVpV+4znn3+eW265hW3btnHttdcyZswYsrKybJ+/c+dOfvjhB3bt2sWcOXNo0qRJ/T0AEam9etsOVUSkBsaNG2d4eHgY/v7+1V4vvviiYRiVO8ZPnDix2nsSEhKMSZMmGYZhGG+//bYREhJi5Ofn285/9913htlsNtLT0w3DMIyoqChj+vTp56wBMJ5++mnbz/n5+QZg/PDDD4ZhGMYNN9xg3H333fb5wiJSrzTGR0SczqBBg5gzZ061Y6GhobY/9+3bt9q5vn37smXLFgB27dpF165d8ff3t52/4oorsFqtJCcnYzKZOHLkCEOGDDlvDV26dLH92d/fn8DAQI4fPw7ApEmTGD16NJs2beLqq69m5MiRXH755bX6riJSvxR8RMTp+Pv7n9H1ZC++vr41us7Ly6vazyaTCavVCsDw4cM5dOgQ33//PUuWLGHIkCFMnjyZV155xe71ioh9aYyPiLicX3/99Yyf27dvD0D79u3ZunUrBQUFtvOrVq3CbDbTtm1bAgICaN68OUuXLr2kGsLCwhg3bhwffPABb7zxBm+//fYl3U9E6odafETE6ZSUlJCenl7tmKenp20A8aeffkrPnj3p168fH374IevWrWPu3LkAjBkzhhkzZjBu3Diee+45MjIyeOihhxg7dizh4eEAPPfcc0ycOJGmTZsyfPhw8vLyWLVqFQ899FCN6nv22Wfp0aMHHTt2pKSkhAULFtiCl4g4NwUfEXE6CxcuJDIystqxtm3bkpSUBFTOuJo/fz6///3viYyM5OOPP6ZDhw4A+Pn5sWjRIh555BF69eqFn58fo0eP5rXXXrPda9y4cRQXF/P666/z+OOP06RJE2666aYa1+ft7c20adM4ePAgvr6+9O/fn/nz59vhm4tIXTMZhmE4uggRkZoymUx8+eWXjBw50tGliIgL0hgfERERcRsKPiIiIuI2NMZHRFyKeudF5FKoxUdERETchoKPiIiIuA0FHxEREXEbCj4iIiLiNhR8RERExG0o+IiIiIjbUPARERERt6HgIyIiIm5DwUdERETcxv8DX0dpvf59+5UAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cudaq.set_target('nvidia')\n", "start_time = timeit.default_timer()\n", "result = minimize(cost,\n", " x0,\n", " method='COBYLA',\n", " callback=callback,\n", " options={'maxiter': 50})\n", "end_time = timeit.default_timer()\n", "\n", "print('UCCSD-VQE energy = ', result.fun)\n", "print('Total number of qubits = ', qubit_count)\n", "print('Total number of parameters = ', parameter_count)\n", "print('Total number of terms in the spin hamiltonian = ',\n", " spin_ham.get_term_count())\n", "print('Total elapsed time (s) = ', end_time - start_time)\n", "\n", "plt.plot(exp_vals)\n", "plt.xlabel('Epochs')\n", "plt.ylabel('Energy')\n", "plt.title('VQE')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result of this procedure is an estimate of the ground state energy of water. However, the convergence behavior is not perfect, more iterations would greatly improve the result, but would take a few minutes to run." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Parallel Parameter Shift Gradients" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One way to accelerate VQE is to use an optimizer that accepts a gradient. This can drastically lower the number of VQE iterations required at the cost of computing the gradient on the quantum side of the algorithm.\n", "\n", "The parameter shift rule is a common technique to compute the gradient for parameterized circuits. It is obtained by computing two expectation values for each parameter corresponding to a small forward and backward shift in the ith parameter. These results are used to estimate finite difference contribution to the gradient.\n", "\n", "![parametershift.png](./images/parametershift.png)\n", "\n", "This procedure can become cost prohibitive as the number of parameters becomes large." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Each of the expectation values needed to evaluate a parameter shift gradient can be computed independently. The CUDA-Q `nvidia-mqpu` backend is designed for parallel computations across multiple simulated QPUs. The function below uses `cudaq.observe_asynch` to distribute all of the expectation values evaluations across as many GPUs that are available. First, try it with `num_qpus` set to 1." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[\u001b[38;2;255;000;000mwarning\u001b[0m] Target \u001b[38;2;000;000;255mnvidia-mqpu\u001b[0m: \u001b[38;2;000;000;255mThis target is deprecating. Please use the 'nvidia' target with option 'mqpu,fp32' or 'mqpu' (fp32 is the default precision option) by adding the command line option '--target-option mqpu,fp32' or passing it as cudaq.set_target('nvidia', option='mqpu,fp32') in Python. Please refer to CUDA-Q \u001b]8;;https://nvidia.github.io/cuda-quantum/latest/using/backends/platform.html#nvidia-mqpu-platform\u001b\\documentation\u001b]8;;\u001b\\ for more information.\u001b[0m\n" ] } ], "source": [ "np.random.seed(42)\n", "x0 = np.random.normal(0, 1, parameter_count)\n", "\n", "cudaq.set_target(\"nvidia-mqpu\")\n", "\n", "num_qpus = cudaq.get_target().num_qpus()\n", "\n", "epsilon = np.pi / 4\n", "\n", "\n", "def batched_gradient_function(kernel, parameters, hamiltonian, epsilon):\n", "\n", " x = np.tile(parameters, (len(parameters), 1))\n", "\n", " xplus = x + (np.eye(x.shape[0]) * epsilon)\n", "\n", " xminus = x - (np.eye(x.shape[0]) * epsilon)\n", "\n", " g_plus = []\n", " g_minus = []\n", " gradients = []\n", "\n", " qpu_counter = 0 # Iterate over the number of GPU resources available\n", " for i in range(x.shape[0]):\n", "\n", " g_plus.append(\n", " cudaq.observe_async(kernel,\n", " hamiltonian,\n", " qubit_count,\n", " electron_count,\n", " xplus[i],\n", " qpu_id=qpu_counter%num_qpus))\n", " qpu_counter += 1\n", "\n", " g_minus.append(\n", " cudaq.observe_async(kernel,\n", " hamiltonian,\n", " qubit_count,\n", " electron_count,\n", " xminus[i],\n", " qpu_id=qpu_counter%num_qpus))\n", " qpu_counter += 1\n", "\n", " gradients = [\n", " (g_plus[i].get().expectation() - g_minus[i].get().expectation()) /\n", " (2 * epsilon) for i in range(len(g_minus))\n", " ]\n", "\n", " assert len(gradients) == len(\n", " parameters) == x.shape[0] == xplus.shape[0] == xminus.shape[0]\n", "\n", " return gradients" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The cost function needs to be slightly updated to make use of the gradient in the optimization procedure and allow for a gradient based optimizer like L-BFGS-B to be used." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "gradient = batched_gradient_function(kernel, x0, spin_ham, epsilon)\n", "\n", "exp_vals = []\n", "\n", "\n", "def objective_function(parameter_vector: list[float], \\\n", " gradient=gradient, hamiltonian=spin_ham, kernel=kernel):\n", "\n", " get_result = lambda parameter_vector: cudaq.observe\\\n", " (kernel, hamiltonian, qubit_count, electron_count, parameter_vector).expectation()\n", "\n", " cost = get_result(parameter_vector)\n", " exp_vals.append(cost)\n", " gradient_vector = batched_gradient_function(kernel, parameter_vector,\n", " spin_ham, epsilon)\n", "\n", " return cost, gradient_vector" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the code below. Notice how the result is converged to a lower energy using only 10% of the steps as optimization above without a gradient. " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "VQE-UCCSD energy= -73.19471262288755\n", "Total elapsed time (s) = 57.27010986900132\n" ] }, { "data": { "image/png": "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xaea/Pe//1W9evXk4+Ojtm3bavny5WZHcjm//vqrbrnlFtWuXVuGYejrr782O5LLeeGFF9SmTRsFBgYqKipKffr0UUpKitmxXM7UqVPVokULxyJv7dq1048//mh2LJf34osvyjAMPfLII2ZHcTkTJ06UYRhlbk2aNDElC8WnGnzyyScaM2aMJkyYoNWrV6tly5bq1auXjhw5YnY0l5KXl6eWLVvqv//9r9lRXNYvv/yikSNHatmyZZo/f76KiorUs2dP5eXlmR3NpcTGxurFF1/UqlWrtHLlSnXt2lW33XabNm3aZHY0l7VixQpNmzZNLVq0MDuKy2revLkOHTrkuP3++++m5OBy9mrQtm1btWnTRv/5z38kle4HFhcXp4ceekjjxo0zOZ1rMgxDX331lfr06WN2FJd29OhRRUVF6ZdfftH1119vdhyXFhYWpkmTJmno0KFmR3E5ubm5at26td566y39+9//1lVXXaXXXnvN7FguZeLEifr666+1du1as6Mw4lPVCgsLtWrVKnXv3t3xmMViUffu3bV06VITkwGXLysrS1LpjzKqRklJiT7++GPl5eWpXbt2ZsdxSSNHjtRNN91U5n+nUfm2b9+u2rVrKyEhQcnJydq7d68pOdiktIqlp6erpKRE0dHRZR6Pjo7W1q1bTUoFXD6bzaZHHnlE1113na644gqz47icDRs2qF27dsrPz1dAQIC++uorNWvWzOxYLufjjz/W6tWrtWLFCrOjuLS2bdvqvffeU+PGjXXo0CE9++yz6tixozZu3KjAwMBqzULxAVAhI0eO1MaNG007T+/qGjdurLVr1yorK0uff/65Bg0apF9++YXyU4n27dun0aNHa/78+fLx8TE7jkvr3bu3499btGihtm3bKj4+Xp9++mm1n76l+FSxiIgIeXh4KC0trczjaWlpqlWrlkmpgMszatQozZ49W7/++qtiY2PNjuOSvL291bBhQ0lSUlKSVqxYoddff13Tpk0zOZnrWLVqlY4cOaLWrVs7HispKdGvv/6q//znPyooKJCHh4eJCV1XSEiIEhMTtWPHjmr/28zxqWLe3t5KSkrSggULHI/ZbDYtWLCA8/VwOna7XaNGjdJXX32lhQsXqn79+mZHchs2m00FBQVmx3Ap3bp104YNG7R27VrH7eqrr1ZycrLWrl1L6alCubm52rlzp2JiYqr9bzPiUw3GjBmjQYMG6eqrr9Y111yj1157TXl5eRoyZIjZ0VxKbm5umf962L17t9auXauwsDDVrVvXxGSuY+TIkZo1a5a++eYbBQYG6vDhw5Kk4OBg+fr6mpzOdTzxxBPq3bu36tatq5ycHM2aNUuLFi3S3LlzzY7mUgIDA8+an+bv76/w8HDmrVWyxx57TLfccovi4+N18OBBTZgwQR4eHrr33nurPQvFpxrcc889Onr0qJ555hkdPnxYV111lebMmXPWhGdcnpUrV6pLly6O+2PGjJEkDRo0SO+9955JqVzL1KlTJUmdO3cu8/iMGTM0ePDg6g/koo4cOaL77rtPhw4dUnBwsFq0aKG5c+eqR48eZkcDKmT//v269957lZGRocjISHXo0EHLli1TZGRktWdhHR8AAOA2mOMDAADcBsUHAAC4DYoPAABwGxQfAADgNig+AADAbVB8AACA26D4AAAAt0HxAYAzGIahr7/+2uwYAKoAxQdAjTJ48GAZhnHW7YYbbjA7GgAXwJYVAGqcG264QTNmzCjzmNVqNSkNAFfCiA+AGsdqtapWrVplbqGhoZJKT0NNnTpVvXv3lq+vrxISEvT555+Xef2GDRvUtWtX+fr6Kjw8XMOGDVNubm6ZY9599101b95cVqtVMTExGjVqVJnn09PTdfvtt8vPz0+NGjXSt99+63ju2LFjSk5OVmRkpHx9fdWoUaOzihqAmoniA8DpPP300+rbt6/WrVun5ORk9evXT1u2bJEk5eXlqVevXgoNDdWKFSv02Wef6aeffipTbKZOnaqRI0dq2LBh2rBhg7799ls1bNiwzN949tlndffdd2v9+vW68cYblZycrMzMTMff37x5s3788Udt2bJFU6dOVURERPV9AQAqzg4ANcigQYPsHh4edn9//zK35557zm632+2S7MOHDy/zmrZt29pHjBhht9vt9nfeecceGhpqz83NdTz//fff2y0Wi/3w4cN2u91ur127tn38+PHnzSDJ/tRTTznu5+bm2iXZf/zxR7vdbrffcsst9iFDhlTOBwZQrZjjA6DG6dKli6ZOnVrmsbCwMMe/t2vXrsxz7dq109q1ayVJW7ZsUcuWLeXv7+94/rrrrpPNZlNKSooMw9DBgwfVrVu3C2Zo0aKF49/9/f0VFBSkI0eOSJJGjBihvn37avXq1erZs6f69Omj9u3bV+izAqheFB8ANY6/v/9Zp54qi6+vb7mO8/LyKnPfMAzZbDZJUu/evbVnzx798MMPmj9/vrp166aRI0dq8uTJlZ4XQOVijg8Ap7Ns2bKz7jdt2lSS1LRpU61bt055eXmO5xcvXiyLxaLGjRsrMDBQ9erV04IFCy4rQ2RkpAYNGqSZM2fqtdde0zvvvHNZ7wegejDiA6DGKSgo0OHDh8s85unp6ZhA/Nlnn+nqq69Whw4d9OGHH2r58uWaPn26JCk5OVkTJkzQoEGDNHHiRB09elQPPfSQBg4cqOjoaEnSxIkTNXz4cEVFRal3797KycnR4sWL9dBDD5Ur3zPPPKOkpCQ1b95cBQUFmj17tqN4AajZKD4Aapw5c+YoJiamzGONGzfW1q1bJZVecfXxxx/rwQcfVExMjD766CM1a9ZMkuTn56e5c+dq9OjRatOmjfz8/NS3b19NmTLF8V6DBg1Sfn6+Xn31VT322GOKiIjQnXfeWe583t7eeuKJJ5SamipfX1917NhRH3/8cSV8cgBVzbDb7XazQwBAeRmGoa+++kp9+vQxOwoAJ8QcHwAA4DYoPgAAwG0wxweAU+HsPIDLwYgPAABwGxQfAADgNig+AADAbVB8AACA26D4AAAAt0HxAQAAboPiAwAA3AbFBwAAuA2KDwAAcBv/P9DLX2dXO2bfAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "np.random.seed(42)\n", "init_params = np.random.normal(0, 1, parameter_count)\n", "\n", "start_time = timeit.default_timer()\n", "result_vqe = minimize(objective_function,\n", " init_params,\n", " method='L-BFGS-B',\n", " jac=True,\n", " tol=1e-8,\n", " options={'maxiter': 5})\n", "end_time = timeit.default_timer()\n", "\n", "print('VQE-UCCSD energy= ', result_vqe.fun)\n", "print('Total elapsed time (s) = ', end_time - start_time)\n", "\n", "plt.plot(exp_vals)\n", "plt.xlabel('Epochs')\n", "plt.ylabel('Energy')\n", "plt.title('VQE')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, run the code again (the three previous cells) and specify `num_qpus` to be more than one if you have access to multiple GPUs and notice resulting speedup. Thanks to CUDA-Q, this code could be used without modification in a setting where multiple physical QPUs were availible." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using an Active Space" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Performing electronic structure computations with all electrons and orbitals is often prohibitively expensive and unnecessary. Most of the interesting chemistry can be modeled by restricting simulations to the highest energy occupied molecular orbitals and lowest energy unoccupied molecular orbitals. This is known as the active space approximation. \n", "\n", "Below is an example of STO-3G water modeled with a 4 electron 3 orbital active space simulated with UCCSD-VQE. Using an active space means you can run VQE for the same molecule using fewer qubits and a more shallow circuit.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![cas.png](./images/cas.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The molecule is defined the same way, expect for you now include variables `nele_cas` and `norb_cas` to define the active space. The `ncore` " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "geometry = [('O', (0.1173, 0.0, 0.0)), ('H', (-0.4691, 0.7570, 0.0)),\n", " ('H', (-0.4691, -0.7570, 0.0))]\n", "basis = 'sto3g'\n", "multiplicity = 1\n", "charge = 0\n", "ncore = 3\n", "nele_cas, norb_cas = (4, 3)\n", "\n", "molecule = openfermionpyscf.run_pyscf(\n", " openfermion.MolecularData(geometry, basis, multiplicity, charge))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Hamiltonian is now constrcuted with the same steps, but only models the active space." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "molecular_hamiltonian = molecule.get_molecular_hamiltonian(\n", " occupied_indices=range(ncore),\n", " active_indices=range(ncore, ncore + norb_cas))\n", "\n", "fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)\n", "\n", "qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)\n", "\n", "spin_ham = cudaq.SpinOperator(qubit_hamiltonian)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, the kernel is defined only by the orbitals and electrons in the active space. Notice how this means you only need to optimize 8 parameters now. " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8\n" ] } ], "source": [ "electron_count = nele_cas\n", "qubit_count = 2 * norb_cas\n", "\n", "\n", "@cudaq.kernel\n", "def kernel(qubit_num: int, electron_num: int, thetas: list[float]):\n", " qubits = cudaq.qvector(qubit_num)\n", "\n", " for i in range(electron_num):\n", " x(qubits[i])\n", "\n", " cudaq.kernels.uccsd(qubits, thetas, electron_num, qubit_num)\n", "\n", "\n", "parameter_count = cudaq.kernels.uccsd_num_parameters(electron_count,\n", " qubit_count)\n", "\n", "print(parameter_count)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def cost(theta):\n", "\n", " exp_val = cudaq.observe(kernel, spin_ham, qubit_count, electron_count,\n", " theta).expectation()\n", " thetas = theta\n", " return exp_val\n", "\n", "\n", "exp_vals = []\n", "\n", "\n", "def callback(xk):\n", " exp_vals.append(cost(xk))\n", "\n", "\n", "# Initial variational parameters.\n", "np.random.seed(42)\n", "x0 = np.random.normal(0, 1, parameter_count)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The VQE procedure below is much faster using an active space compared to inclusion of all orbitals and electrons." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UCCSD-VQE energy = -74.96341992791962\n", "Total number of qubits = 6\n", "Total number of parameters = 8\n", "Total number of terms in the spin hamiltonian = 62\n", "Total elapsed time (s) = 1.754178541001238\n" ] }, { "data": { "image/png": "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ZrMhOzsbMpkMly9fxrhx41zWMHToUPFrX19fBAQEoKioCADw5JNP4sEHH8RPP/2Ee+65B/fffz8SExPbdK1E1LUYloioW/D19W3QLdZRvL29W3ScSqVyWpfJZLDZbACACRMm4Pz58/jyyy+xc+dOjBs3DvPnz8dbb73V4fUSUcfimCUi6hF++OGHBuvx8fEAgPj4ePzyyy+orKwU93///feQy+UYNGgQ/P390bdvX+zevbtdNeh0OsyYMQMbNmzAX/7yF6xbt65d5yOirsGWJSLqFkwmEwoKCpy2KZVKcRD15s2bMWLECNx6663497//jf379yM1NRUAMG3aNCxbtgwzZszAq6++iuLiYixcuBCPP/44evXqBQB49dVXMW/ePISFhWHChAkoLy/H999/j4ULF7aovldeeQU33XQTrr/+ephMJnz++ediWCMi98awRETdwvbt2xEREeG0bdCgQTh58iQA+5Nq//nPf/DUU08hIiICmzZtwuDBgwEAPj4+2LFjB5555hncfPPN8PHxwYMPPojVq1eL55oxYwZqamrw9ttv4/e//z1CQ0Px0EMPtbg+tVqNJUuW4Ny5c/D29kZSUhL+85//dMCVE1FnkwmCIEhdBBFRZ5LJZNi6dSvuv/9+qUshIg/EMUtERERELjAsEREREbnAMUtE1O1xtAERtQdbloiIiIhcYFgiIiIicoFhiYiIiMgFhiUiIiIiFxiWiIiIiFxgWCIiIiJygWGJiIiIyAWGJSIiIiIXGJaIiIiIXPh/kqbqlMUxo1YAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cudaq.set_target(\"nvidia\")\n", "\n", "start_time = timeit.default_timer()\n", "result = minimize(cost,\n", " x0,\n", " method='COBYLA',\n", " callback=callback,\n", " options={'maxiter': 500})\n", "end_time = timeit.default_timer()\n", "\n", "print('UCCSD-VQE energy = ', result.fun)\n", "print('Total number of qubits = ', qubit_count)\n", "print('Total number of parameters = ', parameter_count)\n", "print('Total number of terms in the spin hamiltonian = ',\n", " spin_ham.get_term_count())\n", "print('Total elapsed time (s) = ', end_time - start_time)\n", "\n", "plt.plot(exp_vals)\n", "plt.xlabel('Epochs')\n", "plt.ylabel('Energy')\n", "plt.title('VQE')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Gate Fusion for Larger Circuits" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "CUDA-Q simulations take advantage of a technique called gate fusion. Gate fusion is an optimization technique where consecutive gates are combined into a single gate operation to improve the efficiency of the simulation (See figure below). By targeting the `nvidia-mgpu` backend and setting the `CUDAQ_MGPU_FUSE` environment variable, you can select the degree of fusion that takes place. \n", "\n", "![gate-fuse.png](./images/gate-fuse.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is particularly important for larger circuits and can have a significant impact on the performance of the simulation. Each system is different, so you should test different gate fusion levels to find out what is best for your system. You can find more information [here](https://developer.nvidia.com/blog/new-nvidia-cuda-q-features-boost-quantum-application-performance/)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.12" } }, "nbformat": 4, "nbformat_minor": 4 }