{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Defining and using custom Plugins\n", "\n", "Inside the QLM, Plugins can be attached to QPUs in order to create more powerful computation stacks.\n", "\n", "This notebook will present the Plugin interface and explain how to implement your own Plugin.\n", "\n", "The **Plugin** interface is described inside a python abstract class `AbstractPlugin`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from qat.core.plugins import AbstractPlugin" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Let us build a simple Plugin that prints any circuit passing through on their way to the QPU and all results coming back to the user from the QPU.\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from qat.core import Batch, HardwareSpecs, Result\n", "from qat.core.util import get_syntax\n", "\n", "## As stated, our Plugin should inherit from the AbstractPlugin class:\n", "class Printer(AbstractPlugin):\n", " ## Plugins must implement a compile method\n", " ## here batch will be a Batch object (see doc) that contains a list of Jobs\n", " ## Specs will contain the specs of the attached QPU\n", " def compile(self, batch : Batch, specs : HardwareSpecs) -> Batch:\n", " print(\"Compiling a batch of size\", len(batch.jobs))\n", " for count, job in enumerate(batch.jobs):\n", " print(\"Job #\", count)\n", " for index in range(len(job.circuit.ops)):\n", " syntax = get_syntax(job.circuit, index)\n", " print(syntax)\n", " ## We can use the meta_data field of the batch to store infos\n", " batch.meta_data = {\"printer\" : \"this batch was printed!\"}\n", " return batch\n", " \n", " ## Plugins must implement a post_process method\n", " ## here results will be a list of Results and\n", " ## meta_data a string,string dictionary that is attached to the corresponding\n", " ## Batch object\n", " def post_process(self, batch_result):\n", " print(\"We got\", len(batch_result.results), \"results\")\n", " for result in batch_result.results:\n", " print(len(result), \"samples in this result\")\n", " for sample in result:\n", " print(sample)\n", " print(\"Sanity check : \", batch_result.meta_data) ## Just to check that we saw the Batch on its way in.\n", " return batch_result\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Plugins** can be attached to **QPUs** using a pipe operator, or by invoquing the `push_plugin` method. If a job is submitted to the resulting QPU:\n", " 1. First, the circuit is compiled by each plugin (method `compile` of each plugin is called)\n", " 2. Second, the circuit is executed by the QPU\n", " 3. Then, results are post-processed by each plugin (method `post_process` of each plugin is called)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "from qat.lang.AQASM import *\n", "prog = Program()\n", "qbits = prog.qalloc(2)\n", "for qb in qbits:\n", " prog.apply(H, qb)\n", "\n", "\n", "from qat.qpus import get_default_qpu\n", "qpu = Printer() |Printer() |Printer() |Printer() |Printer() |Printer() | get_default_qpu()\n", "\n", "job = prog.to_circ().to_job()\n", "results = qpu.submit(job)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you are not convincedby the '|' notation, you can use a more traditional way of adding a plugin to a QPU:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "other_qpu = get_default_qpu()\n", "other_qpu.push_plugin(Printer())\n", "results = other_qpu.submit(job)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "authors": [ "Simon Martiel" ], "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.6.8" } }, "nbformat": 4, "nbformat_minor": 2 }