<rjo>
sb0: i think that is a feasible API. i don't see how we could magically extract the pdq preparation stuff from @kernel code otherwise.
<rjo>
sb0: this way, all that needs to be passed from host-side prepare() to @kernel code is the frame id and segment metadata (duration and triggering).
<rjo>
sb0: if you find bugs or unclear/impossible behaviour, let me know ;)
<rjo>
sb0: could'nt we automatically add **kwargs that are passed to AutoContext.__init__() and are not yet in AutoContext.parameters?
<rjo>
s/d'nt/dn't/
elaforest has quit [Ping timeout: 240 seconds]
<sb0>
rjo, it's already doing that, isn't it?
<sb0>
parameters only lists what must be requested from the database unless it's passed as kwarg
<sb0>
"ensures all segments have been advanced() through" << what should it do when not the case? throw an exception?
<sb0>
btw you can use array() in non-kernel code, instead of [0] * self.nbins
<sb0>
its advantage there, besides consistency with kernel code, is it avoids the list reference problems with [[0]*x]*y
gric_ has joined #m-labs
<sb0>
rjo, you can also just do self.histograms = [] in scan() and then self.histograms.append(hist[i]) in kernel. since the last round of inline transform refactoring/bugfixing, it RPCs the right thing...
gric has quit [*.net *.split]
<sb0>
rjo, seems to me the compiler should be able to handle all this stuff already.
<sb0>
one small thing we can add is supporting iterators for parameters (in addition to the spaces), to avoid having to use a space at the end of the 1st line
<sb0>
where should your *.npz files live? in the same repository as the experiment sources?
rjo_ has joined #m-labs
<rjo_>
sb0: re additional parameters. nice! i didn't check.
<rjo_>
sb0: yes. if the method can not do what it is asked to do because it is in the middle of another frame, that is an error in any case. otherwise the voltages would jump.
<rjo_>
sb0: ... that is even it it was possible to leave a frame
<rjo_>
sb0: re array(): ack. but [[0]*x]*y] does not have an array() equivalent :)
<sb0>
array(array(0, x), y)
<rjo_>
sb0: ah. yed.
<rjo_>
sb0: ah. yes.
<sb0>
works both in interpreter and kernel
<rjo_>
true.
<rjo_>
i had leaped to complex slices array(0, nd, ny)[x, y] ...
<rjo_>
sb0: yeah. you done quite a bit of refactoring. i have to geat my bearings straight...
<rjo_>
sb0: oh. it rpc's methods. that is nice.
<sb0>
right now the main limitation is all arguments need to be 32-bit ints, but I plan to improve that
<rjo_>
sb0: re npz. they are very much like the other nomeric parameters that represent some "calibration" things, like duration of pulses, frequencies etc.
<sb0>
so they should rather be in the parameter database?
<rjo_>
sb0: yeah. i tried to think through a way have prepare() and transport() -- that is the host/slow part and the kernel part -- interleaved and have the transforms do the rest but i think that will be very difficult.
<sb0>
the main issue is when to call prepare()
<rjo_>
sb0: yes. conceptually the parameter database should support "large" data, like numpy arrays.
<sb0>
and with which waveforms
<rjo_>
sb0: yes. and to ensure that all methods to frame and pdq2 do not break the notion of not changing the waveform between repeats...
<rjo_>
sb0: i think having split prepare() and transport() is just fine. especially since the code to verify the lock-step between pdq2 segments and rtio does not seem too difficult.
<sb0>
how large? too large for json?
<sb0>
rjo_, we can also call an auto-built prepare() every time before entering kernel mode, with all the possible waveforms that the core device might want
<sb0>
(for that kernel execution)
<sb0>
though I'm not sure about performance problems, and how they could be alleviated by caching and omitting the programming of waveforms that are already there - since they'd need to be extracted everytime anyway
<rjo_>
sb0: well master-to-controller json is going to be fine. i am doing tens of MB with json easily. i'll have to think about larger data for e.g. controller-to-core
<rjo_>
sb0: the remark about large data would be for the versioning.
<rjo_>
sb0: pdq2 has typical order of magnitude of 500 points per channel. that is 500*36 knots for all channels in a single pdq2 rack.
<sb0>
git would only version the diffs, no?
<sb0>
do you expect a lot of diffs?
<rjo_>
sb0: i see yes. something like a "with self.electrodes.prepared(): ..." context from within the kernel. but autobuilding prepare() is difficult. how do you telll if something that may or may note touch the waveform is suppposed to end up in prepare()?
<rjo_>
sb0: yeah. but the npz-diffs are unreadable (by humans).
<rjo_>
sb0: no. the waveforms are rarely goig to change.
* rjo_
is slightly drunk
<rjo_>
s/goig/going/ and so forth.
<sb0>
how about not using npz, and storing arrays as json?
<sb0>
(waveforms) the main issue there is that the sequence of calls that trigger waveform parts can be inside a complicated algorithm
<rjo_>
sb0: i think json is fine.
<sb0>
one would have to unroll that algorithm, which may or may not be possible, to find out what the sequence of waveform parts is
<rjo_>
sb0: yes. unraveling waveform construction from actual rtio-like things would be difficult. if you see a way to do it that would be great, otherwise i think the split is readable.
<sb0>
the general case is essentially solving the halting problem. one would have to put potentially user-unfriendly restrictions on what algorithms can benefit from the auto-extraction
<rjo_>
sb0: that example with appending the reverse transport is just a simple one. there can be more array juggling.
<sb0>
by user-unfriendly, I mean we can have some heuristics, but they will always be some cases where they fail. in that case, the user would have to rewrite their code to use the split prepare/trigger form
<sb0>
*there will
<rjo_>
sb0: yes. looks like the halting problem. what a relief!
<rjo_>
:)
<rjo_>
the advantage is also that it is obvious what the code will actually do if it is split().
<rjo_>
damn. just "split."
<rjo_>
not every word is a function...
<rjo_>
also. one could actually name the segments like append("a_to_b", t, u) and then recall them by name advance("a_to_b") and just error out if the sequence is wrong.
<rjo_>
that would make it explicit what segment advance() actually plays and force the user to do the right thing.