Quantum Layer¶
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.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
.
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.applications.qnn.types import (
MultipleArguments,
Circuit,
MultipleExecutionDetails,
)
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