Context Managers¶
These context managers wrap trace-time or execution-time behavior without transforming an IR.
- autoform.fold()[source]¶
Evaluate immediately within the context.
Inside
af.trace(...), primitive calls normally build IR equations. Afoldblock instead runs primitive implementations while tracing and returns concrete values that can be embedded as literals in the surrounding IR. If a primitive inside the block depends on a dynamic traced value, anAssertionErroris raised. Outside tracing,foldis a no-op.Example
>>> import autoform as af >>> def program(x): ... with af.fold(): ... prefix = af.concat("hello", " ") ... return af.concat(prefix, x) >>> ir = af.trace(program)("seed") >>> len(ir.ir_eqns) 1 >>> ir.call("world") 'hello world'
Fold is useful when a trace-time computation should decide ordinary Python control flow. Autoform cannot stage Python branches whose conditions depend on dynamic IR values; those conditions must be known while tracing. A folded computation runs immediately, so its concrete result can safely choose the branch that is traced into the IR.
Example
>>> def program(x): ... with af.fold(): ... route = af.concat("priority", ": high") ... if route == "priority: high": ... return af.concat("yes: ", x) ... return af.concat("no: ", x) >>> ir = af.trace(program)("seed") >>> ir.call("answer") 'yes: answer'
- Return type:
Generator[None, None, None]
- autoform.tag(*tags)[source]¶
Attach tags to equations at trace time.
Equations built inside nested
tagblocks receive the tags from all active blocks. Equations built after a block exits do not receive that block’s tags.Example
>>> import autoform as af >>> def program(x): ... with af.tag("outer"): ... head = af.concat(x, "!") ... with af.tag("inner"): ... return af.concat(head, "?") >>> ir = af.trace(program)("seed") >>> ir.ir_eqns[0].tags == frozenset({"outer"}) True >>> ir.ir_eqns[1].tags == frozenset({"outer", "inner"}) True
- autoform.memoize()[source]¶
Cache primitive results within the context.
Example
>>> import autoform as af >>> def program(x): ... a = af.concat(x, "!") ... b = af.concat(x, "!") # same call, will be cached ... return af.concat(a, b) >>> ir = af.trace(program)("test") >>> with af.memoize(): ... result = ir.call("hello") >>> result 'hello!hello!'
Tracing a program with memoize will act as compile-time deduplication of identical primitive calls (including stochastic primitives like
lm_call()). Non-memoizable primitives are not memoized.Example
>>> def program(x): ... with af.memoize(): ... a = af.concat(x, "!") ... b = af.concat(x, "!") # same call, will be cached ... return a, b >>> ir = af.trace(program)("test") >>> len(ir.ir_eqns) 1
- Return type:
Generator[None, None, None]
- autoform.collect(*, collection)[source]¶
Collect checkpoint values produced during IR execution.
collectis an execution-time context. Trace the program first, then placecollectaroundir.call(...)orir.acall(...). Values are appended when executedautoform.checkpoint()primitives run.Example
>>> import autoform as af >>> def program(x): ... normalized = af.format("item: {}", x) ... normalized = af.checkpoint(normalized, key="normalized", collection="debug") ... return af.concat(normalized, "!") >>> ir = af.trace(program)("test") >>> with af.collect(collection="debug") as collected: ... result = ir.call("alpha") >>> result 'item: alpha!' >>> collected["normalized"] ['item: alpha']
Transformed IR execution is also execution, so collection works there too.
Example
>>> batched = af.batch(ir) >>> with af.collect(collection="debug") as collected: ... result = batched.call(["alpha", "beta"]) >>> result ['item: alpha!', 'item: beta!'] >>> collected["normalized"] ['item: alpha', 'item: beta']
Do not wrap trace construction with
collect. Tracing builds IR equations; it does not produce concrete runtime checkpoint values. Do not usecollectinside the function being traced either; during tracing, dynamic values are placeholders, not runtime values.
- autoform.inject(*, collection, values)[source]¶
Inject values for checkpoints within the context.
Values are consumed from lists in encounter order for each key. A dictionary produced by
autoform.collect()can be supplied here to reproduce or modify checkpointed intermediates.Around
ir.call(...)orir.acall(...),injectperforms runtime checkpoint substitution by replacing matching checkpoint values as the IR executes.Example
>>> import autoform as af >>> def program(x): ... normalized = af.format("item: {}", x) ... normalized = af.checkpoint(normalized, key="normalized", collection="cache") ... return af.concat(normalized, "!") >>> ir = af.trace(program)("test") >>> with af.inject(collection="cache", values={"normalized": ["cached item"]}): ... ir.call("alpha") 'cached item!'
Inside the function being traced,
injectperforms trace-time specialization. A matching checkpoint is replaced by the injected literal while the IR is being built, so later calls to the traced IR reuse that specialized value.Example
>>> def program(x): ... normalized = af.format("item: {}", x) ... with af.inject(collection="cache", values={"normalized": ["cached item"]}): ... normalized = af.checkpoint(normalized, key="normalized", collection="cache") ... return af.concat(normalized, "!") >>> ir = af.trace(program)("test") >>> [ir_eqn.prim.name for ir_eqn in ir.ir_eqns] ['format', 'concat'] >>> ir.call("alpha") 'cached item!' >>> ir.call("beta") 'cached item!'
- autoform.lm_client(client)[source]¶
Set the LM client for all lm primitives.
The client must expose
.completion()and.acompletion()matching LiteLLM’s chat completion signature.Acceptable clients include the default direct LiteLLM adapter, a configured
litellm.Router, or any wrapper object that forwards those two methods while preserving the LiteLLM request and response shapes.Example
>>> import autoform as af >>> from litellm import Router >>> client = Router( ... model_list=[ ... dict(model_name="gpt-4", litellm_params=dict(model="gpt-5.5")), ... ], ... max_parallel_requests=10, ... ) >>> with af.lm_client(client): ... ir.call(inputs)
- Parameters:
client (LMClient)
- Return type:
Generator[LMClient, None, None]