[Data oriented] Add template_primitives parameter default True#789
Conversation
Make @qd.data_oriented a dual-form decorator that accepts a template_primitives keyword (default True, unchanged behaviour). When set False on a class, its primitive members reached through a kernel template arg should be lifted to runtime kernel args rather than baked. Adds the wants_runtime_primitives() metaclass-safe MRO helper that reads the flag.
…ntime args Implement the runtime lifting for @qd.data_oriented(template_primitives=False) template args, mirroring the existing ndarray-member path: - _predeclare_struct_primitives walks the reachable attribute graph of a flagged template arg, builds a provenance map keyed by (id(parent), attr), and (in the enforcing pass) declares a scalar kernel arg per primitive the body actually accesses, inferring dtype from default_ip / default_fp. - build_Attribute returns the arg-load Expr for a lifted primitive instead of baking getattr; in the discovery pass it marks the access used (pruning), and it raises QuadrantsSyntaxError if a lifted primitive is used inside qd.static. - Pruning rides the existing two-pass __qd_-name used-set machinery (tracked under KERNEL_FUNC_ID so it also serialises through fastcache), so only accessed primitives become kernel args (avoids MAX_ARG_NUM blowup). - launch_kernel binds live primitive values via _set_struct_primitive_args and marks the launch context non-cacheable (values change between launches). The spec key is unchanged (weakref.ref per instance), so mutating a lifted primitive never triggers recompilation.
…mitives Cover int/float/bool mutation without recompile, signed ints, nested dataclass / data_oriented members, self-method kernels, pruning (600 unused members compile fine), the qd.static hard error, the opt-in boundary (default still bakes), fastcache/pure, and distinct instances.
…tives Add a "Runtime primitives" subsection to the compound-types user guide covering the opt-in flag, dtype defaults, pruning, the qd.static restriction, and no-recompile-on-mutation semantics.
…e in fastcache The fastcache args hasher walked every @qd.data_oriented child as a baked template primitive, folding the value into the cache key. For a class declared template_primitives=False the primitives are lifted to runtime scalar args, so baking the value made fastcache recompile/restore a new entry on every value change — defeating the feature. Walk such objects' children with a non-Template arg_meta so primitive members contribute type only (field children still warn and disable fastcache). Add regression tests and document the exception.
The template_primitives=False feature stored a (possibly empty) launch-info entry for every materialized kernel and unconditionally did a tuple-keyed ``self._struct_primitive_launch_info_by_key.get(key)`` on every cache-missing launch. That hashed the kernel key on the launch hot path for ALL kernels, even the overwhelming majority that don't lift primitives, costing ~0.5us/launch. For CPU / unbatched genesis steps -- which are dominated by many tiny cache-missing kernel launches -- this showed up as a ~2-3% runtime regression. Only record an entry when a kernel actually lifts primitives (keeping the dict empty otherwise) and guard the launch-path block with a cheap empty-dict check, so kernels without lifted primitives skip the work entirely. Verified on a dedicated node: orig was +3.3%/launch over main, fixed is back to main within noise. template_primitives correctness unchanged (tests + engine E/F mirrors).
…late-primitives # Conflicts: # docs/source/user_guide/fastcache.md
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
… factor out lifted-primitive helper
…age (doc-quality check)
… (type-change coerces, may truncate)
…cions for lifted primitives
|
The documents LGTM. Agents can figure out what I need easily. It's good to have a precise and mathematical definition of "pure kernel" and "capture behaviour" in the future, because auto-passing
|
…ss is not scope capture
…ss member access (drop qd.template lead)
…taclass (dataclass primitives are runtime scalars, not baked)
… section on why qd.field disables fastcache
…ds flatten to kernel params)
|
The new document looks perfect to me now |
|
ok to merge |



Issue: #
Brief Summary
copilot:summary
Walkthrough
copilot:walkthrough