native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
dotprod.h
1// SPDX-FileCopyrightText: 2026 Edward Kmett <ekmett@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
3#pragma once
5#include "native/config.h"
6#include "native/attributes.h"
7#include "native/isa.h"
8#if NATIVE_HOST_NEON
9#include <arm_neon.h>
10#endif
11#if NATIVE_HOST_NEON || defined(NATIVE_DOXYGEN)
12
13namespace native::detail {
14
15 template<isa<arm> Arch> requires(Arch.has(arm_feature::dotprod))
16 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
17 int32x2_t sdot(int32x2_t accumulator, int8x8_t lhs, int8x8_t rhs) noexcept {
18 return vdot_s32(accumulator, lhs, rhs);
19 }
20
21 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 2)
22 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
23 int32x2_t sdot_lane(int32x2_t accumulator, int8x8_t lhs, int8x8_t rhs) noexcept {
24 return vdot_lane_s32(accumulator, lhs, rhs, Lane);
25 }
26
27 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 4)
28 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
29 int32x2_t sdot_lane(int32x2_t accumulator, int8x8_t lhs, int8x16_t rhs) noexcept {
30 return vdot_laneq_s32(accumulator, lhs, rhs, Lane);
31 }
32
33 template<isa<arm> Arch> requires(Arch.has(arm_feature::dotprod))
34 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
35 int32x4_t sdot(int32x4_t accumulator, int8x16_t lhs, int8x16_t rhs) noexcept {
36 return vdotq_s32(accumulator, lhs, rhs);
37 }
38
39 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 2)
40 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
41 int32x4_t sdot_lane(int32x4_t accumulator, int8x16_t lhs, int8x8_t rhs) noexcept {
42 return vdotq_lane_s32(accumulator, lhs, rhs, Lane);
43 }
44
45 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 4)
46 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
47 int32x4_t sdot_lane(int32x4_t accumulator, int8x16_t lhs, int8x16_t rhs) noexcept {
48 return vdotq_laneq_s32(accumulator, lhs, rhs, Lane);
49 }
50
51 template<isa<arm> Arch> requires(Arch.has(arm_feature::dotprod))
52 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
53 uint32x2_t udot(uint32x2_t accumulator, uint8x8_t lhs, uint8x8_t rhs) noexcept {
54 return vdot_u32(accumulator, lhs, rhs);
55 }
56
57 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 2)
58 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
59 uint32x2_t udot_lane(uint32x2_t accumulator, uint8x8_t lhs, uint8x8_t rhs) noexcept {
60 return vdot_lane_u32(accumulator, lhs, rhs, Lane);
61 }
62
63 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 4)
64 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
65 uint32x2_t udot_lane(uint32x2_t accumulator, uint8x8_t lhs, uint8x16_t rhs) noexcept {
66 return vdot_laneq_u32(accumulator, lhs, rhs, Lane);
67 }
68
69 template<isa<arm> Arch> requires(Arch.has(arm_feature::dotprod))
70 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
71 uint32x4_t udot(uint32x4_t accumulator, uint8x16_t lhs, uint8x16_t rhs) noexcept {
72 return vdotq_u32(accumulator, lhs, rhs);
73 }
74
75 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 2)
76 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
77 uint32x4_t udot_lane(uint32x4_t accumulator, uint8x16_t lhs, uint8x8_t rhs) noexcept {
78 return vdotq_lane_u32(accumulator, lhs, rhs, Lane);
79 }
80
81 template<isa<arm> Arch, int Lane> requires(Arch.has(arm_feature::dotprod) && Lane >= 0 && Lane < 4)
82 native_nodiscard native_inline native_const __attribute__((target("dotprod")))
83 uint32x4_t udot_lane(uint32x4_t accumulator, uint8x16_t lhs, uint8x16_t rhs) noexcept {
84 return vdotq_laneq_u32(accumulator, lhs, rhs, Lane);
85 }
86
87 // Reject Clang's lax vector conversions and scalar narrowing when an exact
88 // instruction shape or immediate lane is unavailable.
89
90 template<isa<arm> Arch, class A, class B, class C>
91 void sdot(A, B, C) = delete;
92 template<isa<arm> Arch, int Lane, class A, class B, class C>
93 void sdot_lane(A, B, C) = delete;
94 template<isa<arm> Arch, class A, class B, class C>
95 void udot(A, B, C) = delete;
96 template<isa<arm> Arch, int Lane, class A, class B, class C>
97 void udot_lane(A, B, C) = delete;
98
99
100}
101#endif
Compiler attributes for host code, with shader-safe shared modifiers.
constexpr simd< std::uint32_t, 2, Arch > udot_lane(simd< std::uint32_t, 2, Arch > accumulator, simd< std::uint8_t, 8, Arch > lhs, simd< std::uint8_t, 8, Arch > rhs) noexcept
UDOT by element: broadcast rhs byte group Lane to every accumulator lane.
constexpr simd< std::int32_t, 2, Arch > sdot(simd< std::int32_t, 2, Arch > accumulator, simd< std::int8_t, 8, Arch > lhs, simd< std::int8_t, 8, Arch > rhs) noexcept
SDOT: four byte products per accumulator lane, modulo 2^32.
constexpr simd< std::int32_t, 2, Arch > sdot_lane(simd< std::int32_t, 2, Arch > accumulator, simd< std::int8_t, 8, Arch > lhs, simd< std::int8_t, 8, Arch > rhs) noexcept
SDOT by element: broadcast rhs byte group Lane to every accumulator lane.
constexpr simd< std::uint32_t, 2, Arch > udot(simd< std::uint32_t, 2, Arch > accumulator, simd< std::uint8_t, 8, Arch > lhs, simd< std::uint8_t, 8, Arch > rhs) noexcept
UDOT: four byte products per accumulator lane, modulo 2^32.
#define native_inline
inline [[always_inline]]
Definition attributes.h:212
#define native_nodiscard
C++17 [[nodiscard]].
Definition attributes.h:189
#define native_const
[[const]] is not const
Definition attributes.h:108
constexpr int target
First matching requirement, with every later choice checked for shadowing.
Definition isa.h:396