Operation Runtime Resources
TT-Metal programs separate reusable structure from dispatch values. Kernel definitions, program semaphore layout, and runtime-argument schema determine which program can be reused; per-core runtime-argument words may change for each dispatch. Execution may also require host or device objects to remain alive while the program runs.
The runtime_resource_factory callback supplies caller-defined program
semaphores and JIT definitions, per-core dispatch words, and host owners for a
TT-Lang operation. It runs once for each device execution, before the runner
constructs program descriptors and after the current tensors, launch range,
and compiler-reserved semaphore IDs are known. Resources select logical kernels
rather than generated descriptor indices, which can change with target
selection and core specialization.
The callback has the following keyword-only contract:
def make_resources(*, tensors, core_ranges, first_free_semaphore_id):
...
tensorscontains the current invocation tensors.core_rangescontains the operation worker cores.first_free_semaphore_idis the first ID after compiler-managed semaphores.
The callback executes once for every device execution and returns a
ttl.ProgramRuntimeResources. The callback result is not cached. Its structural
fingerprint may select an existing cached TT-Metal program, while its current
runtime-argument words are supplied for that dispatch.
For an operation with synchronized DFB reconfiguration, caller-defined per-core runtime arguments retain their documented zero-based indices. The runtime appends compiler-owned configuration addresses and supplies the caller argument count through a compile-time argument. Different caller argument counts produce descriptors for disjoint core sets so each generated kernel uses the correct configuration-address offset.
Typed Records
All resource records are frozen, and all collection fields are tuples.
Record |
Purpose |
|---|---|
|
Contains caller semaphore descriptors, logical-kernel resources, external fabric bindings, and retained owners. |
|
Selects one logical kernel and supplies per-core runtime arguments and JIT definitions. |
|
Associates one ordered integer vector with one worker coordinate. |
|
Associates one definition name with its string value. |
|
Identifies one external fabric manager and its logical kernel. |
|
Associates a manager claim with its connection requirements and ABI identity. |
|
Reserves one fixed forwarding link for specified logical devices and worker nodes. |
KernelDefine is compile-affecting program structure even though the factory
returns it for each execution. CoreRuntimeArgs.values contains the dispatch
words that may change while the cached program is reused.
The following example creates one caller semaphore and configures an operation-owned data-movement kernel:
def make_collective(runtime_owner):
sender = ttl.Kernel(ttl.KernelKind.DATA_MOVEMENT)
def make_resources(*, tensors, core_ranges, first_free_semaphore_id):
semaphore = ttnn.SemaphoreDescriptor(
first_free_semaphore_id,
core_ranges=core_ranges,
initial_value=0,
)
return ttl.ProgramRuntimeResources(
semaphore_descriptors=(semaphore,),
kernel_resources=(
ttl.KernelRuntimeResources(
kernel=sender,
runtime_args=(
ttl.CoreRuntimeArgs(
ttnn.CoreCoord(0, 0),
(first_free_semaphore_id, 0),
),
ttl.CoreRuntimeArgs(
ttnn.CoreCoord(1, 0),
(first_free_semaphore_id, 1),
),
),
defines=(ttl.KernelDefine("FABRIC_2D", "1"),),
),
),
lifetimes=(runtime_owner, semaphore),
)
@ttl.operation(grid=(2, 1), runtime_resource_factory=make_resources)
def collective(input_tensor, output_tensor):
ttl.call_extern_func(
HEADER,
"collective_sender",
func_args=[input_tensor, output_tensor],
kernel=sender,
)
return collective
KernelKind.COMPUTE and KernelKind.DATA_MOVEMENT select canonical kernels.
A captured Kernel identifies an operation-owned kernel when an operation has
multiple kernels of one kind. The operation and its resource factory must
capture the same Kernel object. The external functions
reference describes logical-kernel selection.
External Fabric Managers
An external kernel may own routing-plane connections that must not overlap
compiler-generated managers. A captured FabricManagerClaim records this
ownership without exposing the external kernel’s runtime-argument ABI.
acquire(), use(), and release() describe a manager lifetime across opaque
calls; scoped() describes one call that acquires, uses, and releases it.
Ownership begins when the acquire call starts and ends after the release call
returns.
The runtime resource factory supplies one FabricConnectionBinding for each
captured claim. Its requirements must cover every active logical-device and
worker-node instance of the selected kernel. fixed_link_index is an ABI
constraint: target binding rejects a link that the active control plane does
not expose for the destination. The compiler validates external and generated
manager intervals together before modifying program descriptors.
Claim identity, abi_identity, logical endpoints, worker nodes, and fixed links
participate in program-cache identity. Objects in a binding’s lifetimes tuple
remain referenced through execution.
Validation and Specialization
Runtime resource planning validates the complete factory result before the
runner constructs a TTNN KernelDescriptor or ProgramDescriptor. Invalid
resources raise an exception without materializing a partial program.
Validation includes the following rules:
The result and every nested resource use the documented record and tuple types.
Every explicit
Kernelis bound to the executing operation and identifies an emitted logical kernel.Runtime argument coordinates and semaphore ranges must be inside the operation worker range.
Each runtime argument coordinate occurs at most once per logical kernel, and its values are integer-indexable non-boolean objects.
Caller semaphore IDs must be unique and greater than or equal to
first_free_semaphore_id.Each logical kernel may have at most one
KernelRuntimeResourcesentry.Definition names and values must be strings, and each definition name must occur at most once in that entry.
Core specialization can produce several descriptors for one logical kernel. Definitions apply to every descriptor for that identity. Runtime arguments are partitioned by coordinate, and every coordinate must match exactly one descriptor.
Program Cache and Lifetimes
Resource structure participates in program-cache identity. The identity includes logical destinations, descriptor coordinates, definitions, runtime-argument coordinates and vector lengths, caller semaphore properties, and external fabric binding structure. Runtime-argument words, tensor addresses, and lifetime object identities are excluded, so cached programs accept new dispatch values.
Objects in ProgramRuntimeResources.lifetimes remain referenced through
execution. A successful invocation replaces the retained owner tuple. A failed
invocation preserves the previous valid owners.
Emitted Runners and Simulator
An emitted runner for a resource-aware operation requires the factory on every call:
runner.run(
tensors,
runtime_resource_factory=make_resources,
device=device,
)
The runner reconstructs logical-kernel identities and uses the same planner and materializer as decorated operation execution. It does not serialize live owners or dispatch values; the caller supplies them through the factory.
Operation runtime resources are a hardware execution interface. The simulator
does not model TTNN program descriptors or per-core kernel runtime arguments
and rejects runtime_resource_factory.