-
Notifications
You must be signed in to change notification settings - Fork 31
[Doc] Fix compound types doc #767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hughperkins
wants to merge
3
commits into
main
Choose a base branch
from
hp/fix-compound-types-doc
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -19,8 +19,6 @@ The following compound types are available: | |||||||||||||||||||
| | Member declaration | type-annotated class fields | live attributes (no annotations) | type-annotated class fields | | ||||||||||||||||||||
| | Kernel-arg annotation | `MyStruct` (the dataclass type) | `qd.Template` | `MyStruct` (the struct type) | | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Note on the "Members can be tensors" row for `@qd.dataclass`: a `@qd.dataclass`'s members must be primitives, fixed vectors, or fixed matrices — not `qd.field` / `qd.ndarray`. However, *allocating* a `@qd.dataclass` as a tensor of structs in SoA layout (`MyStruct.field(shape=(N,), layout=qd.Layout.SOA)`) extrudes each member into its own length-`N` tensor — so the resulting *collection* effectively behaves like a struct of parallel tensors, even though the `@qd.dataclass` type itself doesn't have tensor-typed members. See the [`@qd.dataclass` section](#qddataclass-qdtypesstruct) below. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| > ⚠️ **Deprecation: `@dataclasses.dataclass` instance passed via `qd.Template`.** | ||||||||||||||||||||
| > Passing a `@dataclasses.dataclass` instance into a `qd.Template`-annotated kernel parameter is not supported and emits a `DeprecationWarning` at compile time. In a future release it will become an error. | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -171,7 +169,7 @@ sim.step() | |||||||||||||||||||
|
|
||||||||||||||||||||
| ### Primitive members | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Primitive members on `self` (e.g. `int`, `float`, `bool`, `enum.Enum`) are supported, but they are treated as **template values**: each distinct primitive value across instances triggers a new kernel compilation, with the value baked into the kernel IR. | ||||||||||||||||||||
| Primitive members on `self` (e.g. `int`, `float`, `bool`, `enum.Enum`) are supported, but they are treated as **template values**: each distinct primitive value across instances triggers a new kernel compilation, with the value baked into the compiled kernel. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| ```python | ||||||||||||||||||||
| @qd.data_oriented | ||||||||||||||||||||
|
|
@@ -191,7 +189,7 @@ Simulation(200).step() # compiles kernel #2 with n=200 baked in | |||||||||||||||||||
|
|
||||||||||||||||||||
| ### Tensor members | ||||||||||||||||||||
|
|
||||||||||||||||||||
| `@qd.data_oriented` classes may hold tensor members of any backend: `qd.field`, `qd.ndarray`, or `qd.Tensor`. | ||||||||||||||||||||
| `@qd.data_oriented` classes may hold tensor members of any backend: `qd.field`, `qd.ndarray`, or [qd.Tensor](tensor.md). | ||||||||||||||||||||
|
|
||||||||||||||||||||
| ```python | ||||||||||||||||||||
| @qd.data_oriented | ||||||||||||||||||||
|
|
@@ -240,6 +238,8 @@ A `@qd.dataclass` can be turned into a tensor of structs (e.g. `MyStruct.field(s | |||||||||||||||||||
| - **Struct-of-arrays (SoA)** (`qd.Layout.SOA`): extrudes each member of the struct into its own tensor of length `N`. | ||||||||||||||||||||
| - **Array-of-structs (AoS)** (`qd.Layout.AOS`): the storage is an array of `N` struct cells laid out contiguously in memory. AoS is only available with `qd.field` backing. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Note that although a `@qd.dataclass`'s members can't themselves be tensors, allocating one in SoA layout (`MyStruct.field(shape=(N,), layout=qd.Layout.SOA)`) extrudes each member into its own length-`N` tensor — so the resulting *collection* effectively behaves like a struct of parallel tensors, even though the `@qd.dataclass` type itself doesn't have tensor-typed members. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| ```python | ||||||||||||||||||||
| @qd.dataclass | ||||||||||||||||||||
| class Particle: | ||||||||||||||||||||
|
|
@@ -292,7 +292,7 @@ Unlike the other two compound types, `@qd.dataclass` is a real kernel-side type | |||||||||||||||||||
|
|
||||||||||||||||||||
| ## Nesting compatibility | ||||||||||||||||||||
|
|
||||||||||||||||||||
| This table summarizes which member types are allowed inside which container type. "yes" means the member is walked correctly when the container is passed to a kernel; "no" means the member is ignored or the combination raises an error. | ||||||||||||||||||||
| This table summarizes which member types are allowed inside which container type. "yes" means the member is handled correctly when the container is passed to a kernel; "no" means the member is ignored or the combination raises an error. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | Container ↓ / Member → | `qd.ndarray` | `qd.field` | primitive | `dataclasses.dataclass` | `@qd.data_oriented` | `@qd.dataclass` | | ||||||||||||||||||||
| |---|:---:|:---:|:---:|:---:|:---:|:---:| | ||||||||||||||||||||
|
|
@@ -302,17 +302,11 @@ This table summarizes which member types are allowed inside which container type | |||||||||||||||||||
|
|
||||||||||||||||||||
| ### Outer kernel-arg annotation | ||||||||||||||||||||
|
|
||||||||||||||||||||
| The outermost annotation you put on the kernel parameter determines how the container is walked: | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | Annotation | Kernel-arg walker | Notes | | ||||||||||||||||||||
| |---|---|---| | ||||||||||||||||||||
| | `qd.types.NDArray[...]` | ndarray slot | leaf-level only | | ||||||||||||||||||||
| | `MyDataclass` (dataclass type) | per-member flatten using annotations | recommended for `@dataclasses.dataclass`; needs every member to have a quadrants-typed annotation | | ||||||||||||||||||||
| | `qd.Template` | value-driven walk of `vars(self)` | for `@qd.data_oriented` containers (and primitives). **Not** supported for `@dataclasses.dataclass` — see the [deprecation notice in Overview](#overview). | | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Practical consequence: | ||||||||||||||||||||
| The outermost annotation you put on the kernel parameter should match the parameter type as follows: | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - **`@qd.data_oriented` containers** must be passed via `qd.Template` (or be the `self` of a `@qd.kernel` method on a `@qd.data_oriented` class). Using a typed-dataclass annotation on the outermost arg errors. | ||||||||||||||||||||
| | Kernel parameter compound type | Annotation | | ||||||||||||||||||||
| | `@dataclasses.dataclass` | `MyDataclass` (dataclass type) | | ||||||||||||||||||||
| | `@qd.data_oriented` | `qd.Template` | | ||||||||||||||||||||
|
Comment on lines
+307
to
+309
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The markdown table is missing the required separator row between the header and data rows. Without the separator row (e.g., The table should be: | Kernel parameter compound type | Annotation |
|---|---|
| `@dataclasses.dataclass` | `MyDataclass` (dataclass type) |
| `@qd.data_oriented` | `qd.Template` |
Suggested change
Spotted by Graphite |
||||||||||||||||||||
|
|
||||||||||||||||||||
| ### Reassigning ndarray members | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -321,7 +315,7 @@ For `@qd.data_oriented` containers passed via `qd.Template`, reassigning an ndar | |||||||||||||||||||
| ### Restrictions | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - **`@qd.dataclass` cannot contain `qd.ndarray` or `qd.field` members.** See the [`@qd.dataclass`](#qddataclass-qdtypesstruct) section above for the full list of allowed member types. (The function-form factory `qd.types.struct(...)` has the same restrictions.) | ||||||||||||||||||||
| - **A typed-dataclass kernel-arg annotation cannot have a `@qd.data_oriented` member type** — errors clearly at compile time. Typed-dataclass kernel args are flattened from annotations, but `@qd.data_oriented` carries no per-member annotations, so its members can only be walked from the live instance, which only happens on the `qd.Template` path. | ||||||||||||||||||||
| - **Declare all ndarray members on a `@qd.data_oriented` class in `__init__`.** The template-mapper caches the set of ndarray-attribute paths reachable from each instance on its first kernel launch — *per instance*, not per class — so two instances of the same class can legitimately carry different ndarray attribute sets (e.g. an optional `*_adjoint_cache` member that's only allocated when `requires_grad=True`). But: | ||||||||||||||||||||
| - **Deleting an ndarray attribute** that was present on an instance's first launch raises `AttributeError` on the next launch on that instance (the cached path still tries to `getattr` the missing attribute). | ||||||||||||||||||||
| - **Adding a new ndarray attribute after first launch** on a given instance won't be tracked by the args-hash invalidator on that instance — reassigning the new attribute to a tensor of a different `dtype` / `ndim` after that point will silently reuse the originally compiled kernel. | ||||||||||||||||||||
| - **A typed-dataclass kernel-arg annotation cannot have a `@qd.data_oriented` member type** — errors clearly at compile time | ||||||||||||||||||||
| - **Declare all ndarray members on a `@qd.data_oriented` class in `__init__`.** | ||||||||||||||||||||
| - **Deleting an ndarray attribute** that was present on an `@qd.data_oriented` instance's first launch raises `AttributeError` on the next launch on that instance. | ||||||||||||||||||||
| - **Adding a new ndarray attribute after first launch** on a given `@qd.data_oriented` instance will cause incorrect undefined behavior. | ||||||||||||||||||||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new table goes directly from the header to the first data row, so Markdown/MyST will not recognize it as a table; readers will see the raw pipe-delimited text instead of the intended annotation matrix. Please add a delimiter row such as
|---|---|before this row.Useful? React with 👍 / 👎.