On 07/05/2014 04:43 PM, Sébastien Bourdeauducq wrote:
> How about the following mechanism for parameters:
> * Experiment constructors take an additional "mvs" (Missing Value
> Supplier) parameter.
> * When creating an Experiment, if some parameter values were specified
> but not supplied as keyword arguments, the Experiment attempts to
> retrieve them from the MVS.
> * All keyword arguments are set as object attributes.
> * An Experiment can be used as MVS. If the requested parameter is within
> its attributes, the value of that attribute is returned. Otherwise, the
> request is forwarded to the parent MVS.
> * At the top-level, we may have a MVS that issues requests to a Redis
> database.
> 
> This system:
> * solves the problem of propagating parameters down the hierarchy.
> * keeps Experiments independent (they can be run without a database if
> all parameter values are supplied in the constructor) and does not use
> global variables.
> * retains a lot of flexibility (e.g. parameters can be renamed or
> computed before they are passed to sub-experiments).
> 
> This is exemplified in the following code:
> 
> class SubExperiment(Experiment):
>       parameters = "foo bar"
> 
>       @kernel
>       def run():
>               do_something(self.foo, self.bar)
> 
> class MainExperiment(Experiment):
>       parameters = "bar1 bar2 offset"
> 
>       def __init__(self, *args, **kwargs):
>               Experiment.__init__(self, *args, **kwargs)
>               self.exp1 = SubExperiment(self, bar=self.bar1)
>               self.exp2 = SubExperiment(self, bar=self.bar2)
>               self.exp3 = SubExperiment(self, bar=self.bar2 + self.offset)
> 
>       @kernel
>       def run():
>               self.exp1.run()
>               self.exp2.run()
>               self.exp3.run()
> 
> We can then use it in the following ways:
> MainExperiment(foo=1, bar1=2, bar2=3, offset=0) - does not require a
> database.
> MainExperiment(db_mvs, bar1=2, bar2=3) - "foo" and "offset" are
> automatically retrieved from the database.
> 
> If that works, we can have something similar for channels.

Good solution. Experiment.__init__() would then retrieve the parameters
from wherever it can and set attributes. I would factor out the last
lines of MainExperiment.__init__ into MainExperiment.build() so that
__init__ does not need to be overloaded each time with all the args and
kwargs passing.

Having thought about it for a bit, in my use cases I would probably
group kernels on the "feature" level, that is have an Experiment "Ion"
that offers kernels for cooling, detecting, and simple gates. And then
one "Transport" Experiment that has kernels that do transport.

class Main(Experiment):
        def build(self):
                self.ion1 = Ion(self, ...)
                self.ion2 = Ion(self, ...)
                self.transporter = Transporter(self, ...)

        @kernel
        def run(self):
                self.ion1.cool(duration=10*us)
                self.ion2.cool(frequency=...)
                self.transporter.move(speed=...)
                self.ion1.detect(duration=...)


Robert.
_______________________________________________
ARTIQ mailing list
https://ssl.serverraum.org/lists/listinfo/artiq
Migen/MiSoC: please use de...@lists.m-labs.hk instead.

Reply via email to