Skip to content
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

Add bytemuck integration for vector types #80

Closed
Kixiron opened this issue Dec 4, 2021 · 10 comments
Closed

Add bytemuck integration for vector types #80

Kixiron opened this issue Dec 4, 2021 · 10 comments

Comments

@Kixiron
Copy link

Kixiron commented Dec 4, 2021

As far as I can tell all of the various vector types can be Pod and maybe even Zeroable, adding a bytemuck feature that enables implementations for the various vec types would allow (for example) casting slices of vectors into slices of bytes safety, among other things.
As a real-world example this could be used within Rust-CUDA here to convert the buffer safety

@yoanlcq
Copy link
Owner

yoanlcq commented Dec 5, 2021

Why not! I'll look into it and get back to you soon.

@yoanlcq
Copy link
Owner

yoanlcq commented Dec 5, 2021

Just now, I published 0.15.4, which adds support for bytemuck for vector types.

I did not implement these traits for matrices, quaternions and others, because the order of their members is not "standardized", but they can be explicitly converted to vectors if needed.

I'll close this issue but feel free to let me know of any remarks or requests you may have!

@jedjoud10
Copy link
Contributor

jedjoud10 commented Jan 13, 2023

Sorry in advance for commenting on an old issue, but is there a reason why bytemuck traits are not implemented for matrices?

@yoanlcq
Copy link
Owner

yoanlcq commented Jan 13, 2023

Hi @jedjoud10 , actually bytemuck's Pod trait could be implemented for all #[repr(C)] types of this crate, except #[repr(simd)] matrices (because a SIMD Mat3's memory layout is generally Vec3<Vec4<T>> rather than Vec3<Vec3<T>> as intuition would suggest, and I'm afraid this violates one of the requirements for Pod).
That would result in feature asymmetry between repr_c and repr_simd, but that doesn't bother me.

In my last comment my argument was:

I did not implement these traits for matrices, quaternions and others, because the order of their members is not "standardized", but they can be explicitly converted to vectors if needed.

I'm not sure how much that holds, actually. What I think I meant is that the order of members within a quaternion is not guaranteed (some libs store them as WXYZ), and for matrices you have to know whether you're using a row-major or column-major layout; all of that meaning that if you want to (de-)serialize, you should convert to a stable intermediate representation that you control; one of these being vectors; the order of their members will always be the same, there is no question about what the memory layout is.

So what you can do is convert your quaternions and matrices to vectors or vectors-of-vectors respectively, and then do bytemuck stuff with these vectors (which have a stable, well-known bit pattern).
That was my intent when I wrote that comment, but I realize now it puts a practically unncessary burden on the user.

I'd accept a PR that does this; if you'd prefer I do it, feel free to ask, but I can't guarantee how soon I'll get to work on it, due to limited time.

@jedjoud10
Copy link
Contributor

I have a PR ready, sorry it took a while I was busy with other stuff. Really small change as well. Just to make sure I understand correctly though, you'd only implement bytemuck's Pod and Zeroable only for Mat4s, right?

@yoanlcq
Copy link
Owner

yoanlcq commented Jul 14, 2023

Just to make sure I understand correctly though, you'd only implement bytemuck's Pod and Zeroable only for Mat4s, right?

If you do it for Mat4, please also do it for Mat2 and Mat3. If you add the trait impl inside mat_impl_mat! then it will work that way.
Also, in that case, why not also do it for Quaternion as well, since it's one of the fundamental types!

I don't think people care that much about using bytemuck on the other types such as bézier curves etc.

Thanks!

@jedjoud10
Copy link
Contributor

Oh okay sure!
I'll have to somehow figure out a way to detect if a $Mat is either #[repr(C)] or #[repr(simd)] since Mat3's have different layouts (per your last reply, I never used simd matrices so I wouldn't know). Other than that I think it's alright to implement it for other simd types.

@yoanlcq
Copy link
Owner

yoanlcq commented Jul 15, 2023

Actually I've taken a look at the codebase and remembered that at some point, I made Vec3 #[repr(C)] even in the repr_simd modules; this was because at some point, the compiler stopped supporting non-power-of-two-length #[repr(simd)] vectors.
So I think you can just implement Pod for types in both repr_c and repr_simd modules, which is fortunate as it makes your task simpler.

It would be extra nice to add a test that proves that repr_simd::Vec3 has no unused/padding bytes: something like assert_eq!(size_of::<repr_simd::Vec3<f32>>, 3*4); should be enough with a comment explaining that it's to assert that Pod can be implemented for it.

@jedjoud10
Copy link
Contributor

Just FYI, I needed to upgrade the version of serde since one of its dependencies failed compilation (proc-macro2) (see rust-lang/rust#113152).
I added that padding test, and it works nicely. I'd be ready to submit a PR to be honest.

@yoanlcq
Copy link
Owner

yoanlcq commented Jul 15, 2023

Sure, go ahead!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants