Hello, I have an experiment that involves multiple classes, with each class having its own kernels. There is a main Class, within which the experiment logic is executed through:

@kernel 
def run (self):
      xxx
      xxx

The question is how can I run the kernels of other Classes from the main Class's "@kernel run()"? Because ARTIQ Python supports a subset of standard Python, errors arise when the main Class' run kernel tries to access other Classes' kernels or functions. I tried to make things dynamic, the kernels of other Classes are dynamic parameters passed in through a list.

For example:

[<reset_all.Reset object at 0x7f9836d60c10>, <doppler_cooling.DopplerCooling object at 0x7f9836d60be0>]
<synthesized>:1:2-1:46: error: cannot unify <instance reset_all.Reset> with <instance doppler_cooling.DopplerCooling>
[`<reset_all.Reset object at 0x7f9836d60c10>`, `<doppler_cooling.DopplerCooling object at 0x7f9836d60be0>`]
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
exp/main_experiment.py:34:1: note: expanded from here
def run(self):
^
<synthesized>:1:2-1:46: note: a list element of type <instance reset_all.Reset {
                __objectid__: numpy.int32
        }>
[`<reset_all.Reset object at 0x7f9836d60c10>`, `<doppler_cooling.DopplerCooling object at 0x7f9836d60be0>`]
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<synthesized>:1:48-1:107: note: a list element of type <instance doppler_cooling.DopplerCooling {
                __objectid__: numpy.int32
        }>

Any comments?

thanks

wenji

6 days later

If your classes have related features, you may try to let some of your classes to inherit from your main class, and use codes like super().run() to access the run() function in the main class from other classes.

12 days later

Hey Wenji,

This is definitely possible, but the problem I think you're facing is how you're implementing it.
You can't access lists with multiple types (e.g. a DopplerCooling class and a Reset class, as you're doing here) in ARTIQ 7 (I think this is supported in ARTIQ 8 with the new compiler?).
Instead, try instantiating them as instance variables of your main experiment class, then you should be able to call those methods directly, e.g.:

def prepare(self):
     self.doppler_cool_class = DopplerCooling(self)

@kernel
def run(self):
   self.doppler_cool_class.run_doppler_cooling()