{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Circuit Compilation\n", "\n", "This tutorial highlights circuit compilation in InQuanto. \n", "Circuit compilation is an important step in quantum computation. \n", "In this step measurement circuits are optimized, making them backend compatible and often cheaper to run. \n", "Compilation follows the instantiation and building of the protocol and precedes running the protocol and evaluating the results. \n", "In this tutorial we highlight the outcomes of different levels of compilation. \n", "\n", "We take advantage of IBM's Aer Backend through the `pytket-qiskit` extension in this tutorial. \n", "With some adjustment to how the protocols are run, this notebook can also take advantage of backends available through [Quantinuum Nexus](https://docs.quantinuum.com/nexus/index.html). \n", "Refer to this [page](https://docs.quantinuum.com/inquanto/tutorials/backends_overview.html#backends-overview-top) for instructions on how to run InQuanto calculations on other backends. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1. System Preparation\n", "\n", "First, we import the Hamiltonian, space, and state of a converged mean-field (Hartree-Fock) simulation through the `get_system()` method of `inquanto.express`. Here we use H2 in the 6-31G basis set as our system." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from inquanto.express import get_system\n", "from inquanto.ansatzes import FermionSpaceAnsatzUCCSD\n", "\n", "fermion_hamiltonian, space, state = get_system(\"h2_631g_symmetry.h5\")\n", "# Jordan-Wigner encoding\n", "qubit_hamiltonian = fermion_hamiltonian.qubit_encode()\n", "ansatz = FermionSpaceAnsatzUCCSD(space, state)\n", "\n", "# Define a set of random variables for the ansatz\n", "params = ansatz.state_symbols.construct_random(seed=6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.2. Instancing and Building the Protocol\n", "\n", "A number of different [protocols](https://docs.quantinuum.com/inquanto/manual/protocols_overview.html) are available in InQuanto. \n", "There are state vector protocols, protocols for quantum phase estimation, and averaging protocols.\n", "We use the shot-based `PauliAveraging()` protocol, which can partition the Pauli gates that measure the Hamiltonian into sets that are simultaneously measurable. \n", "More on the Pauli averaging protocol can be found [here](https://docs.quantinuum.com/inquanto/manual/protocols/expval.html#pauliaveraging). \n", "In this tutorial we build and then [pickle](https://docs.python.org/3/library/pickle.html) a template of this protocol. \n", "This allows us to use a clean instance of the protocol each time we demonstrate different compilations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pytket.extensions.qiskit import AerBackend\n", "from inquanto.protocols import PauliAveraging\n", "from pytket.partition import PauliPartitionStrat\n", "\n", "# Shot based IBM backend\n", "backend = AerBackend()\n", "\n", "# Instantiate protocol\n", "protocol_template = PauliAveraging(\n", " backend,\n", " shots_per_circuit=10,\n", " pauli_partition_strategy=PauliPartitionStrat.CommutingSets\n", ")\n", "# Build protocol\n", "protocol_template.build(params, ansatz, qubit_hamiltonian)\n", "protocol_pickle = protocol_template.dumps()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.3. Circuit Compilation\n", "\n", "We are now able to begin compiling circuits with the instantiated and built protocol. \n", "If we inspect a circuit from the built protocol we find that it is comprised of two Pauli X gates, a number of circuit boxes and then a measurement circuit. \n", "The circuit boxes are abstractions built from sets of gates that pytket uses to exploit any higher-level structure within the circuit. \n", "These circuit boxes are themselves comprised of Pauli exponential circuit boxes. \n", "While all of these boxes can be useful to break large and complex circuits down into manageable sub-routines, they are not typically compatible circuit execution. \n", "We can check the validity of our sample circuit with the Aer backend using the `valid_circuit()` method from pytket, and see that the circuits in their current form are not compatible. \n", "However, this will change once they are compiled. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "