Skip to content

Conversation

Firestar99
Copy link
Member

@Firestar99 Firestar99 commented Oct 14, 2025

Requires #439, #440

/// A `VectorOrScalarComposite` is a type that is either
/// * a [`Scalar`]
/// * a [`Vector`]
/// * an array of `VectorOrScalarComposite`
/// * a struct where all members are `VectorOrScalarComposite`
/// * an enum with a `repr` that is a [`Scalar`]
///
/// By calling [`Self::transform`] you can visit all the individual [`Scalar`] and [`Vector`] values this composite is
/// build out of and transform them into some other value. This is particularly useful for subgroup intrinsics sending
/// data to other threads.
///
/// To derive `#[derive(VectorOrScalarComposite)]` on a struct, all members must also implement
/// `VectorOrScalarComposite`.
///
/// To derive it on an enum, the enum must implement `From<N>` and `Into<N>` where `N` is defined by the `#[repr(N)]`
/// attribute on the enum and is an [`Integer`], like `u32`.
/// Note that some [safe subgroup operations] may return an "undefined result", so your `From<N>` must gracefully handle
/// arbitrary bit patterns being passed to it. While panicking is legal, it is discouraged as it may result in
/// unexpected control flow.
/// To implement these conversion traits, we recommend [`FromPrimitive`] and [`IntoPrimitive`] from the [`num_enum`]
/// crate. [`FromPrimitive`] requires that either the enum is exhaustive, or you provide it with a variant to default
/// to, by either implementing [`Default`] or marking a variant with `#[num_enum(default)]`. Note to disable default
/// features on the [`num_enum`] crate, or it won't compile on SPIR-V.
///
/// [`Integer`]: crate::Integer
/// [subgroup operations]: crate::arch::subgroup_shuffle
/// [`FromPrimitive`]: https://docs.rs/num_enum/latest/num_enum/derive.FromPrimitive.html
/// [`IntoPrimitive`]: https://docs.rs/num_enum/latest/num_enum/derive.IntoPrimitive.html
/// [`num_enum`]: https://crates.io/crates/num_enum
pub trait ScalarOrVectorComposite: Copy + Send + Sync + 'static {
/// Transform the individual [`Scalar`] and [`Vector`] values of this type to a different value.
///
/// See [`Self`] for more detail.
fn transform<F: ScalarOrVectorTransform>(self, f: &mut F) -> Self;
}

Also see previous iteration at #411

todo

  • derive enums
  • subgroup_all_equal()

closes #410

@Firestar99 Firestar99 force-pushed the scalar-or-vector-composite branch 2 times, most recently from ce822f1 to 5b6cf85 Compare October 14, 2025 17:37
Copy link
Contributor

@nazar-pc nazar-pc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, assuming this is zero cost abstraction (like when a struct contains a single scalar field I expect it to compile to the same code as if it was just a single scalar), this makes sense to me.

One opaque thing I do not like as much is that it can implicitly result in multiple subgroup operations. For example like when array is used it'll clearly iterate over each individual value instead of calling a vector form with all or part of the values, which may not be what the user would expect to happen.

@Firestar99 Firestar99 force-pushed the scalar-or-vector-composite branch from 5b6cf85 to 5ebd674 Compare October 16, 2025 10:35
@Firestar99 Firestar99 changed the title ScalarOrVectorComposite add trait ScalarOrVectorComposite Oct 16, 2025
@Firestar99 Firestar99 force-pushed the scalar-or-vector-composite branch from 5ebd674 to 6a62178 Compare October 16, 2025 14:12
@Firestar99
Copy link
Member Author

assuming this is zero cost abstraction

Pretty much, otherwise you'd see the subgroup compiletests with disassembly fail due to different codegen.

it can implicitly result in multiple subgroup operations

If you can't observe the difference between a single operation and multiple operations back-to-back, does that actually matter?
Also, you can expect all modern hardware to decompose any kind of vector op into multiple scalar ops, so us emitting actual vector ops won't give us any real benefit. Apart from maybe saving a few bytes of shader IR.

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

Successfully merging this pull request may close these issues.

2 participants