-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Structs and StructFields: passing them into and returning them from kernels #8441
Comments
Whilst I definitely agree, this would be awesome. What I do for this currently is to pack my structures into vectors, and then write some little helper functions to convert. So for a sphere I'd do something like this:
For a trivial example like this it seems like unnecessary boilerplate - but used in larger pieces of code it seems a lot more reasonable. |
@oliver-batchelor interesting workaround, but would there be any performance impact from marshaling bits and deserializing structs like this inside the kernel, or would that get optimized away by the compiler? If not, I think you're better off (performance-wise) with a static StructField. Also, I'm seeing now from your example that taichi dataclasses (which just provide a thin wrapper around structs, from my understanding) don't support things like |
The other thing I considered was argpack types, but given the inability to pass a field/vector of argpacks, you end up in a situation that just recreates passing disjoint fields into kernels. This pretty much defeats the purpose of argpacks and makes it more cumbersome to write "fat kernels", which is a major selling point for Taichi otherwise. Maybe I'm just missing something obvious, but I can't think of a clean way to deal with semantically heterogeneous data that doesn't require use of globally-scoped data containers. Even compiler support for destructured assignment would be nice. Without that (unless you want to sacrifice performance) it seems that you're limited to index-fiddling and/or excessive boilerplate. |
Fields are global and just can't be "passed" into the kernel... The only way to do it is to use |
I haven't seen any bad performance from doing this - if anything it seems better than the alternative which is to pass "Struct of Array" style in ndarrays, where you pass in an array corresponding to every field. Clearly it doesn't work with structs which have a whole lot of mixed data types so well, but most of mine are simple geometric types which are OK. I've been refactoring taichi_3d_gaussian_splatting into this style a bit here if you want to see what it looks like, though some other applications will have more demanding usage. |
You're totally right - I've been relying on ndarray so heavily that I somehow completely missed the fact that fields can only be treated as global. Out of curiosity: why are the two constructs treated with this distinction? Why allow users to pass in ndarrays by reference, but require them to treat fields as global? |
Fields are an older design, and because the advanced layout it allows requires some complex GPU runtime and memory management that's non-transparent and always there, it makes it hard to make a reference out of them... actually for the CUDA backend especially we practically don't know the address of a field on the host other than asking the GPU runtime itself |
Hi,
Let's say I create a StructField like so:
With the latest release of taichi (1.7.0), I still cannot pass this object (by reference or value/copy) into a kernel directly, as a parameter. Indeed, there seems to be nothing in
taichi.types
in the way of annotating StructFields. Instead, I have to treat it as a global (compile-time) variable and rely on a closure to bring it into the body of the kernel. The other thing we can do is initialize a@taichi.data_oriented
class with a StructField member, and have the kernel method pull that field fromself
.While the second option is acceptable for an object-oriented style of programming, the inability to decouple a top-level kernel from the global scope renders explicitly functional/pure programming pretty much impossible. This is not ideal from a clean coding/architecture standpoint.
This seems to be something that a lot of people want (see here, also the project backlog with "struct" as a query yields a bunch of issues that are variations on this request). Is this the sort of thing we can expect in the next version (1.8.0) of taichi? If so, where can we track progress?
Thanks again for a making such a great library!
The text was updated successfully, but these errors were encountered: