Skip to content

QLayer

Classiq exports the QLayer object, which inherits from torch.nn.Module (like most objects in the torch.nn namespace), and it acts like one!

The QLayer object is defined as:

class QLayer(nn.Module):
    def __init__(
        self,
        circuit: Circuit,
        execute: ExecuteFunciton,
        post_process: PostProcessFunction,
    ):
        ...

The first parameter, circuit, is the result of model_designer.synthesize(). Note that the parameters are assumed to follow the API stated in qnn.

The second parameter is a callable, taking in a Circuit, and a dictionary, mapping each parameter name to its value, and returning a MultipleExecutionDetails, which is a wrapper to Executor.execute_quantum_program_batch.

The third parameter is a callble, taking in an ExecutionDetails, parsing it, and returning a Tensor

An example of such callables is:

import torch
from classiq.interface.executor.result import MultipleExecutionDetails
from classiq.applications.qnn.types import MultipleArguments, Circuit


def execute(circuit: Circuit, arguments: MultipleArguments) -> MultipleExecutionDetails:
    return Executor(prefereces).execute_batch(circuit, arguments)


def post_process(result: ExecutionDetails) -> Tensor:
    # for example, post process can take some value out of `result.counts`, which is a `dict`
    value = _post_process_result(result)
    return torch.tensor(value)

Behind the scenes

behind the scenes, the QLayer does the following

  • handles processing the PQC
  • handles initializing and tracking parameters
  • handles passing the inputs and weights (as multi dimensional tensors) to the execution function
  • handles gradient calculation on the PQC