1616
1717// ================================================================================
1818// this file has been auto-generated, do not modify its contents!
19- // date: 2026-08-25 17:05:35.335482
20- // git hash: f4e2d65be6e0f28156781eb766bae0fbcbe48b42
19+ // date: 2026-08-28 13:42:54.102829
20+ // git hash: 14a94fbc188ca3285e7351e5bb79184ce89c75d7
2121// ================================================================================
2222
2323#ifndef KERNEL_FLOAT_MACROS_H
@@ -2771,17 +2771,14 @@ constexpr size_t gcd(size_t a, size_t b) {
27712771}
27722772
27732773/* *
2774- * Returns true if a value of `bytes` bytes can be reinterpreted as one of the built-in types supported by
2775- * the `__ldXX`/`__stXX` cache-modifier intrinsics (this covers exactly the sizes of `char`, `short`,
2776- * `int`/`float`, ` long long`/`double` and `int4`/`double2`/`ulonglong2`) .
2774+ * Maps a size in bytes to the built-in type that a value of that size can be reinterpreted as for the
2775+ * `__ldXX`/`__stXX` cache-modifier intrinsics. Only the sizes of `char`, `short`, `int`/`float `,
2776+ * `long long`/`double` and `int4`/`double2`/`ulonglong2` are supported; every other size maps to `void` .
27772777 */
2778- KERNEL_FLOAT_INLINE
2779- constexpr bool cache_intrinsic_supported (size_t bytes) {
2780- return bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8 || bytes == 16 ;
2781- }
2782-
27832778template <size_t Bytes>
2784- struct cache_intrinsic_type ;
2779+ struct cache_intrinsic_type {
2780+ using type = void ;
2781+ };
27852782
27862783template <>
27872784struct cache_intrinsic_type <1 > {
@@ -2808,6 +2805,14 @@ struct cache_intrinsic_type<16> {
28082805 using type = ulonglong2;
28092806};
28102807
2808+ /* *
2809+ * Returns true if a value of `Bytes` bytes can be reinterpreted as one of the built-in types supported by
2810+ * the cache-modifier intrinsics.
2811+ */
2812+ template <size_t Bytes>
2813+ static constexpr bool cache_intrinsic_supported =
2814+ !is_same_type<typename cache_intrinsic_type<Bytes>::type, void >;
2815+
28112816/* *
28122817 * Loads a value of type `S` from `ptr`, applying the given cache-eviction hint. Falls back to a plain load
28132818 * if `Modifier` is `normal`, if `S` does not match one of the sizes supported by the cache intrinsics, or if
@@ -2816,7 +2821,7 @@ struct cache_intrinsic_type<16> {
28162821template <typename S, cache_modifier Modifier>
28172822KERNEL_FLOAT_INLINE S cache_load (const S* ptr) {
28182823#if KERNEL_FLOAT_IS_CUDA && KERNEL_FLOAT_IS_DEVICE
2819- if constexpr (!cache_intrinsic_supported ( sizeof (S)) || Modifier == cache_modifier::normal) {
2824+ if constexpr (!cache_intrinsic_supported< sizeof (S)> || Modifier == cache_modifier::normal) {
28202825 return *ptr;
28212826 } else {
28222827 using R = typename cache_intrinsic_type<sizeof (S)>::type;
@@ -2855,7 +2860,7 @@ KERNEL_FLOAT_INLINE S cache_load(const S* ptr) {
28552860template <typename S, cache_modifier Modifier>
28562861KERNEL_FLOAT_INLINE void cache_store (S* ptr, const S& value) {
28572862#if KERNEL_FLOAT_IS_CUDA && KERNEL_FLOAT_IS_DEVICE
2858- if constexpr (!cache_intrinsic_supported ( sizeof (S)) || Modifier == cache_modifier::normal) {
2863+ if constexpr (!cache_intrinsic_supported< sizeof (S)> || Modifier == cache_modifier::normal) {
28592864 *ptr = value;
28602865 } else {
28612866 using R = typename cache_intrinsic_type<sizeof (S)>::type;
@@ -3106,11 +3111,6 @@ struct access_policy {
31063111 KERNEL_FLOAT_INLINE access_policy (access_policy<U, M, RP , WP >) {}
31073112 access_policy () = default;
31083113
3109- /* *
3110- * Returns the policy to use after the pointer has been offset by a multiple of `N` elements. This stateless
3111- * policy simply constructs the offset policy type; a stateful policy should override this to carry its state
3112- * forward so that derived `vector_ref`s observe the same state.
3113- */
31143114 template <size_t N>
31153115 KERNEL_FLOAT_INLINE with_offset<N> offset_impl (size_t index) const {
31163116 return with_offset<N> {};
@@ -3451,15 +3451,20 @@ operator+(size_t i, vector_ptr<T, N, P> p) {
34513451 return p.offset (i);
34523452}
34533453
3454+ /* *
3455+ * Offsets `p` in place by `i * N` elements.
3456+ *
3457+ * This is only available when offsetting the pointer does not lose alignment, i.e. when the policy after
3458+ * offsetting is convertible back to the original policy. Otherwise `p + i` has a different (less aligned)
3459+ * type than `p` and cannot be assigned back; capture it in a new variable instead (e.g. `auto q = p + i`).
3460+ */
34543461template <
34553462 typename T,
34563463 size_t N,
3457- typename U,
3458- size_t A,
3459- typename = enable_if_t <
3460- detail::is_policy_convertible<access_policy<U, A>, access_policy<U, N * sizeof (U)>>::value>>
3461- KERNEL_FLOAT_INLINE vector_ptr<T, N, access_policy<U, A>>&
3462- operator +=(vector_ptr<T, N, access_policy<U, A>>& p, size_t i) {
3464+ typename P,
3465+ typename =
3466+ enable_if_t <detail::is_policy_convertible<P, typename P::template with_offset<N>>::value>>
3467+ KERNEL_FLOAT_INLINE vector_ptr<T, N, P>& operator +=(vector_ptr<T, N, P>& p, size_t i) {
34633468 return p = p + i;
34643469}
34653470
@@ -3690,8 +3695,11 @@ make_vec_ptr(T* ptr) {
36903695template <typename T, size_t N = 1 , typename U = T, size_t Align = N>
36913696using vec_ptr = vector_ptr<T, N, access_policy<U, Align * sizeof (U)>>;
36923697
3698+ template <typename T, size_t N = 1 , typename U = T>
3699+ using unaligned_ptr = vector_ptr<T, N, access_policy<U, alignof (U)>>;
3700+
36933701template <cache_modifier modifier, typename T, size_t N = 1 , typename U = T, size_t Align = N>
3694- using cache_vec_ptr = vector_ptr<T, N, access_policy<U, Align * sizeof (U), modifier>>;
3702+ using cache_ptr = vector_ptr<T, N, access_policy<U, Align * sizeof (U), modifier>>;
36953703
36963704template <typename T, typename U = T>
36973705using scalar_ptr = vector_ptr<T, 1 , access_policy<U>>;
0 commit comments