How should one go about maintaining a device through class compositionality?

I am trying to compose the template RandomLayers into a random neural network architecture. I have created a class lets call it MyCircuit, and that class inherits from nn.Module. I want the forward function to be implemented as a quantum function so that I may just call backward through the entire model. I am running into a problem while trying to assign a device to the qnode representing the forward function and would like to understand the best practices regarding end-to-end differentiable hybrid models.

So my question is:
How should one go about maintaining a device through class compositionality?

Example:
MyModel has a layer that is a MyCircuit. I instantiate MyModel into my_model by passing in hyperparameters.

I want to be able to pass the device through the instantiation of my_model so it may be used for the layer which is a MyCircuit.

Generally though the class hierarchy can be much more complicated. I suppose this question is related to the device management of GPU’s TPU’s, and now QPU’s.

The current problem I am running into by passing a device in through the instantiation of my_model is that somewhere between that pass, and the forward method call the device is no longer recognized as a valid PennyLane device.

In devising this question, I came to a similar thread, why not just have a default.qubit as the device with a number of wires defined in the function itself? While it wouldn’t completely solve the problem of passing devices through composable classes it would be more dynamic and in my mind would lead to quicker prototyping of circuits.

I use pytorch.

Incentive of being able to pass device down through class stack, more levels of abstraction become possible.

Thank you for your time in reading and responding.

Hi @TylerRoost, thank you for asking this question. We’re taking a look at it and we will get back to you very soon.

1 Like

Thank you dearly. Please let me know if the description is not sufficient to reach the problems I was running into.

Hi Tyler, have you taken a look at the Pennylane TorchLayer? https://pennylane.readthedocs.io/en/stable/code/api/pennylane.qnn.TorchLayer.html?highlight=torchlayer#pennylane.qnn.TorchLayer

Looks like it should do the job, I’ll close if so, thank you for your time.

1 Like

While I haven’t gotten it working I’m curious what the best practice class structure used for hybrid models is.

I think my problem could be solved if instead of a callable function I could decorate an object that is callable or would I just decorate the class?

It didn’t seem based on qnode documentation that decorating a class was possible, though actually decorating an instance may be better for my use case.

I’m more used to treating layers like objects I suppose, so the torchlayer transformation works if I add one more layer of abstraction oooooo I see so myhybridmodel has a mycircuitlayer of mycircuit, that inherits from torchlayer, and mycircuit can inherit from qnode if I’m not mistaken, but also some part of me feels wrong.

Would love some feedback on how others have been composing object hierarchies for hybrid models.

For best practises on including quantum nodes in torch network, this might help here https://pennylane.ai/qml/demos/tutorial_qnn_module_torch.html. If not, maybe you could share a code snippet (even if not working) of what you’re doing possibly?