m-labs / artiq

A leading-edge control system for quantum information experiments
https://m-labs.hk/artiq
GNU Lesser General Public License v3.0
426 stars 197 forks source link

inhomogeneous kernel lists #519

Open dleibrandt opened 8 years ago

dleibrandt commented 8 years ago

I find the lack of support for inhomogeneous lists on the kernel pretty restrictive. What are the prospects for supporting them?

One example use case is the following. We make a lot of laser pulses where multiple beamlines are turned on at a time. I'd like to put all of the code for doing this in a class, such as that below, but this doesn't work because the list LaserPulse.beamlines is not homogeneous.

class LaserBeamline(HasEnvironment):
    ...
    @kernel
    def set_dds_on(self):
        ...
    @kernel
    def set_dac_on(self):
        ...

class LaserBeamline397pi(LaserBeamline):
    ...

class LaserBeamline866(LaserBeamline):
    ...

class LaserPulse(HasEnvironment):
    def build(self):
        ...
        self.beamlines = []
        self.beamlines.append(LaserBeamline397pi(parent=self))
        self.beamlines.append(LaserBeamline866(parent=self))
        ...
    @kernel
    def pulse(self):
        for i in range(len(self.beamlines)):
            self.beamlines[i].set_dac_on()
        with self.core_dds.batch:
            for i in range(len(self.beamlines)):
                self.beamlines[i].set_dds_on()
        delay(self.t)
        for i in range(len(self.beamlines)):
            self.beamlines[i].set_ttl_off()
whitequark commented 8 years ago

Inhomogeneous lists in kernels are impossible to implement. What is possible is implementing iteration through tuples using for loops:

for x in self.beamlines:
  x.set_ttl_off()

This would be expanded at compilation time into a sequence similar to:

a, b, c, ..., x = self.beamlines
a.set_ttl_off()
b.set_ttl_off()
c.set_ttl_off()
...
x.set_ttl_off()

There would be no indexing, or other fancy stuff like range(self.beamlines) since there's no point if you cannot index them. Though enumerate could be done, once it's also implemented elsewhere.

whitequark commented 8 years ago

Strictly speaking inhomogeneous lists are not "impossible" to implement but it is almost certainly a bad idea for the following reasons:

dleibrandt commented 8 years ago

Tuples might be OK. One additional thing I'd like to be able to do is, for example, scan one of the attributes of one of the beamline objects, using something like:

LaserPulse_instance.beamlines[0].freq = x

Would this be possible with tuples?

whitequark commented 8 years ago

No, but you could assign that object to another variable, or deconstruct it as in:

beamline_397, beamline_866 = LaserPulse_instance.beamlines
beamline_397.freq = x

The reason for the restriction is that, while it is possible to implement the LaserPulse_instance.beamlines[0].xxx syntax, it is not composable; you cannot abstract this operation into a function that accepts the index of the beamline. Thus, it's better to avoid it entirely.

dleibrandt commented 8 years ago

That works for me. I'd be happy with this solution.