Skip to content

collect

collect

Assemble the per-request save payloads of one trace into its results.

Locally, the invoke blocks of one trace share their outer names: a container bound above the invokes (rows = [None] * n; rows.save()) is ONE object every invoke mutates. On the engine each invoke rides its own request into the worker process with its own COPY, so the copies come back one per request, each carrying only that request's writes. :func:merge_shared_saves reproduces the shared-object semantics before results are pushed back into the trace frame.

merge_shared_saves

merge_shared_saves(mediators: list, per_request_saves: list) -> dict

Merge same-name saves across a multi-invoke trace's requests, in place.

A name that was bound and saved ABOVE the invokes (mediator.presaved) is one object locally, so its per-request copies merge element-wise — same-length lists slot-wise with None as the unwritten marker (the common pattern: a pre-sized slot list each invoke fills at its own index), dicts by key-union, everything else (and any conflicting slot several requests wrote) keeping the later request's copy — and the merged value is written into every mediator's scope so results push identically whichever mediator they're read from.

A name each block saved for itself is NOT merged, however many requests shipped it: those are separate values, not copies of one, and merging them would keep only the last, leaving three prompts holding one prompt's activation. The caller returns those as a list instead.

Returns the merged shared values by name (the caller re-marks them saved: the merge builds new containers the save-gate hasn't seen).

dumps_compact

dumps_compact(value) -> bytes

Pickle value, writing each tensor that views a larger storage as a copy of itself.

A block's reads are rows narrowed out of the whole step's buffers, and pickling a tensor writes its entire storage: a save from one request would otherwise carry every request's rows home, which across a few hundred invokes runs to gigabytes. Hooked into the pickler rather than walking the payload, so a tensor is found wherever it sits (in a dataclass, a namedtuple, an output object), and an object saved under two names is still one object when it arrives. The bytes load with plain pickle.loads.