Executing / Compiling quantum jobs
QPUs & Plugins on Qaptiva
A QPU, or Quantum Processor Unit is the abstraction used on Qaptiva for designating either the workflow of a quantum computer, or an emulator of such a workflow. provides several classical emulators of QPUs.
See Quantum Processing Unit (QPU) for more information on QPUs.
A Plugin is an object from the Qaptiva API that can be used to process quantum circuits (or jobs) on their way to or on their way back from a QPU. A plugin can also be used independently from any QPU, they are in this case used only for compiling a circuit without executing it on a QPU.
See Extending a QPU (by using Plugins) for more information on plugins.
Getting a remote object
QPUs and plugins can respectively be “imported” from Qaptiva as remote QPUs and remote plugins.
A remote QPU can then be instanciated, creating a QLMaaSQPU
.
Similarly, a remote plugin can be instanciated, creating a QLMaaSPlugin
.
These instanciated objects can then be used to process jobs.
Getting a remote object
Warning
This sample of code requires a configuration file (to connect automatically to the server)
If a configuration file is set, myQLM is able to automatically connect to the Qaptiva Access server. The modules
qlmaas.qpus
andqlmaas.plugins
allow for easily creating remote QPUs and plugins.Equivalent code on Qaptiva
from qat.qpus import LinAlg from qat.plugins import Nnizer qpu = LinAlg() plugin = Nnizer()from qlmaas.qpus import LinAlg from qlmaas.plugins import Nnizer qpu = LinAlg() plugin = Nnizer()This “import” is done with the QLMaaSConnection
get_qpu()
andget_plugin()
methods. As an example, the following code would create a remote QPU for LinAlg and a remote plugin for Nnizer:Equivalent code on Qaptiva
from qat.qpus import LinAlg from qat.plugins import Nnizer qpu = LinAlg() plugin = Nnizer()from qat.qlmaas.connection import QLMaaSConnection # importing a remote QPU and a remote plugin connection = QLMaaSConnection() LinAlg = connection.get_qpu("qat.qpus:LinAlg") Nnizer = connection.get_plugin("qat.plugins:Nnizer") # the remote QPU and plugin can then be instanciated in the usual way qpu = LinAlg() plugin = Nnizer()
Submitting a job to a remote QPU
A job can be submitted to a remote QPU by using a remote QPU’s submit()
method. This method is asynchronous, meaning that its use is different from the submit method used
directly on Qaptiva. See next section for retrieving the result of a
simulation. Here is an example of job submission to a remote LinAlg QPU:
Equivalent code on Qaptiva
from qat.lang.AQASM import Program, H, CNOT
qprog = Program()
qbits = qprog.qalloc(2)
H(qbits[0])
CNOT(qbits[0], qbits[1])
circuit = qprog.to_circ()
job = circuit.to_job()
from qat.qpus import LinAlg
qpu = LinAlg()
# this is not strictly equivalent, since the Qaptiva's QPU submit method is synchronous
# while the QLMaaSQPU submit method is asynchronous
qpu.submit(job)
# creating a circuit and its corresponding job by using qat.lang
from qat.lang.AQASM import Program, H, CNOT
qprog = Program()
qbits = qprog.qalloc(2)
H(qbits[0])
CNOT(qbits[0], qbits[1])
circuit = qprog.to_circ()
job = circuit.to_job()
# creating a remote QPU - use of module 'qlmaas'
from qlmaas.qpus import LinAlg
# submitting the job
asynchronous_result = qpu.submit(job)
Getting the result of a job
There are a number of ways of obtaining the result of a job previously submited to a remote . Using one method or another depends on your workflow.
Getting the result of a job
As seen above, the
submit()
method returns aAsyncResult
object (and so does thecompile()
method).This object can then be used to check the status of the corresponding job with its
get_status()
method, and get its result when it is available by using eitherget_result()
orjoin()
.# check the status of a job status = asynchronous_result.get_status() # returns its result if the job is finished result = asynchronous_result.get_result() # for waiting until the job is finished and then get the result result = asynchronous_result.join()Warning
This sample of code requires a configuration file (to connect automatically to the server)
If a configuration file is set, myQLM is able to automatically connect to the Qaptiva Access server. The module
qlmaas.jobs
will contains all the job submitted by a user (except the job having a status DELETED).from qlmaas.jobs import Job17 # Check the status of the job status = Job17.get_status() # Get the result result = Job17.get_result()Another way to interact with a submitted job is by using its job_id. This job_id can be obtained in various way; it is printed to the standard output when using the submit method, but it also is a field from
AsyncResult
.The job_id can be used to get the result of your job later, as long as you have a QLMaaSConnection object to the same Qaptiva Access server:
from qat.qlmaas.connection import QLMaaSConnection # recreating a connection to the server connection = QLMaaSConnection() # let us say that our job_id was Job17 JOB_ID = "Job17" # check the status of the job status = connection.get_status(JOB_ID) # get the result of the job result = connection.get_result(JOB_ID)
Building a custom execution stack
The Qaptiva syntax of using plugins and QPUs to build execution stacks is reproduced on Qaptiva Access. Building a remote stack by using Qaptiva Access would therefore look like that:
Equivalent code on Qaptiva
from qat.plugins import Plugin1, Plugin2, ..., PluginN
from qat.qpus import QPU
stack = Plugin1() | Plugin2() | ... | PluginN() | QPU()
# simple syntax using a configuration file
from qlmaas.plugins import Plugin1, Plugin2, ..., PluginN
from qlmaas.qpus import QPU
# the remote qpu and plugins are stacked and instanciated
stack = Plugin1() | Plugin2() | ... | PluginN() | QPU()
Such remote stack can then be used to submit jobs as with a remote qpu. This time, let us retrieve the result by using the job_id.
Equivalent code on the Qaptiva
result = stack.submit(batch)
# submit the stack
asynchronous_result = stack.submit(batch)
# get the result
result = asynchronous_result.get_result()
Compiling a quantum circuit
As on Qaptiva, a quantum circuit can be compiled with a plugin.
This can be done with a remote plugin’s compile()
method.
Let us take the example of an Nnizer.
Equivalent code on Qaptiva
from qat.plugins import Nnizer
nnizer = Nnizer()
from qat.core import HardwareSpecs, Topology, TopologyType
specs = HardwareSpecs(topology=Topology(type=TopologyType.LNN))
new_batch = nnizer.compile(batch, specs)
# get the remote Nnizer (simple syntax using a configuration file)
from qlmaas.plugins import Nnizer
nnizer = Nnizer()
# define a limited LNN connectivity by using the qat.core library
from qat.core import HardwareSpecs, Topology, TopologyType
specs = HardwareSpecs(topology=Topology(type=TopologyType.LNN))
# a batch of jobs can then be compiled remotely
asynchronous_batch = nnizer.compile(batch, specs)
new_batch = asynchronous_batch.join()
# bonus: the QLMaaS syntax allows for compiling Job objects as well as Batch objects
asynchronous_job = nnizer.compile(job, specs)
new_job = asynchronous_job.join()