native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
native.x86.vnni.ccm
1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
2module;
3#include "native/isa_import.h"
4#include "native/x86/vnni.h"
5#include "native/x86/integer_constant.h"
6export module native.x86.vnni;
7export import native.x86.features;
8export import native.simd;
9// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0
10#if NATIVE_HOST_X86 || defined(NATIVE_DOXYGEN)
11export namespace native {
37
38 // 128-bit core operations.
40 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
42 constexpr simd<std::int32_t, 4, Arch> dpbusd(simd<std::int32_t, 4, Arch> accumulator, simd<std::uint8_t, 16, Arch> a, simd<std::int8_t, 16, Arch> b) noexcept {
43 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
44 else {
45 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
46 }
47 }
48
50 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
51 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
52 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
54 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
55 else {
56 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
57 }
58 }
59
61 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
62 Arch.has(x86_feature::avx512vl))
63 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
65 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false); }
66 else {
67 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::mask_dpbusd<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
68 }
69 }
70
72 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
73 Arch.has(x86_feature::avx512vl))
74 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
76 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true); }
77 else {
78 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::maskz_dpbusd<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
79 }
80 }
81
83 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
86 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
87 else {
88 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
89 }
90 }
91
93 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
94 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
95 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
97 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
98 else {
99 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
100 }
101 }
102
104 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
105 Arch.has(x86_feature::avx512vl))
106 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
108 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false); }
109 else {
110 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::mask_dpbusds<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
111 }
112 }
113
115 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
116 Arch.has(x86_feature::avx512vl))
117 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
119 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true); }
120 else {
121 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::maskz_dpbusds<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
122 }
123 }
124
126 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
129 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
130 else {
131 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
132 }
133 }
134
136 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
137 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
138 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
140 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
141 else {
142 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
143 }
144 }
145
147 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
148 Arch.has(x86_feature::avx512vl))
149 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
151 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false); }
152 else {
153 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::mask_dpwssd<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
154 }
155 }
156
158 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
159 Arch.has(x86_feature::avx512vl))
160 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
162 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true); }
163 else {
164 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::maskz_dpwssd<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
165 }
166 }
167
169 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
172 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
173 else {
174 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
175 }
176 }
177
179 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
180 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
181 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
183 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
184 else {
185 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
186 }
187 }
188
190 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
191 Arch.has(x86_feature::avx512vl))
192 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
194 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false); }
195 else {
196 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::mask_dpwssds<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
197 }
198 }
199
201 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
202 Arch.has(x86_feature::avx512vl))
203 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
205 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true); }
206 else {
207 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::maskz_dpwssds<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
208 }
209 }
210
211 // 256-bit core operations.
213 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
216 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
217 else {
218 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
219 }
220 }
221
223 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
224 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
225 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
227 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
228 else {
229 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
230 }
231 }
232
234 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
235 Arch.has(x86_feature::avx512vl))
236 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
238 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false); }
239 else {
240 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::mask_dpbusd<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
241 }
242 }
243
245 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
246 Arch.has(x86_feature::avx512vl))
247 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
249 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true); }
250 else {
251 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::maskz_dpbusd<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
252 }
253 }
254
256 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
259 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
260 else {
261 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
262 }
263 }
264
266 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
267 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
268 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
270 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
271 else {
272 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
273 }
274 }
275
277 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
278 Arch.has(x86_feature::avx512vl))
279 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
281 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false); }
282 else {
283 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::mask_dpbusds<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
284 }
285 }
286
288 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
289 Arch.has(x86_feature::avx512vl))
290 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
292 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true); }
293 else {
294 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::maskz_dpbusds<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
295 }
296 }
297
299 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
302 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
303 else {
304 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
305 }
306 }
307
309 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
310 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
311 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
313 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
314 else {
315 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
316 }
317 }
318
320 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
321 Arch.has(x86_feature::avx512vl))
322 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
324 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false); }
325 else {
326 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::mask_dpwssd<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
327 }
328 }
329
331 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
332 Arch.has(x86_feature::avx512vl))
333 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
335 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true); }
336 else {
337 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::maskz_dpwssd<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
338 }
339 }
340
342 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnni))
345 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
346 else {
347 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
348 }
349 }
350
352 template<isa<x86> Arch> requires(!Arch.has(x86_feature::avxvnni) &&
353 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))
354 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
356 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
357 else {
358 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
359 }
360 }
361
363 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
364 Arch.has(x86_feature::avx512vl))
365 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
367 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false); }
368 else {
369 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::mask_dpwssds<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
370 }
371 }
372
374 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
375 Arch.has(x86_feature::avx512vl))
376 native_nodiscard native_inline native_const native_target("avx512f,avx512vnni,avx512vl")
378 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true); }
379 else {
380 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::maskz_dpwssds<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
381 }
382 }
383
384 // 512-bit core operations.
386 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
389 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
390 else {
391 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::dpbusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
392 }
393 }
394
396 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
399 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false); }
400 else {
401 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::mask_dpbusd<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
402 }
403 }
404
406 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
409 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true); }
410 else {
411 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::maskz_dpbusd<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
412 }
413 }
414
416 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
419 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
420 else {
421 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::dpbusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
422 }
423 }
424
426 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
429 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false); }
430 else {
431 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::mask_dpbusds<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
432 }
433 }
434
436 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
439 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true); }
440 else {
441 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::maskz_dpbusds<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
442 }
443 }
444
446 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
449 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
450 else {
451 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::dpwssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
452 }
453 }
454
456 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
459 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false); }
460 else {
461 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::mask_dpwssd<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
462 }
463 }
464
466 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
469 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true); }
470 else {
471 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::maskz_dpwssd<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
472 }
473 }
474
476 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
479 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
480 else {
481 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::dpwssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
482 }
483 }
484
486 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
489 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false); }
490 else {
491 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::mask_dpwssds<Arch>(accumulator.to_native(), mask.to_bitset(), a.to_native(), b.to_native()));
492 }
493 }
494
496 template<isa<x86> Arch> requires(Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))
499 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true); }
500 else {
501 return simd<std::int32_t, 16, Arch>::from_native(detail::x86_vnni::maskz_dpwssds<Arch>(mask.to_bitset(), accumulator.to_native(), a.to_native(), b.to_native()));
502 }
503 }
504
506 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
509 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
510 else {
511 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
512 }
513 }
514
516 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
519 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
520 else {
521 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbssd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
522 }
523 }
524
526 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
529 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
530 else {
531 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
532 }
533 }
534
536 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
539 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
540 else {
541 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbssds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
542 }
543 }
544
546 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
549 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
550 else {
551 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbsud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
552 }
553 }
554
556 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
559 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
560 else {
561 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbsud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
562 }
563 }
564
566 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
569 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
570 else {
571 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpbsuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
572 }
573 }
574
576 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
579 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
580 else {
581 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpbsuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
582 }
583 }
584
586 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
589 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
590 else {
591 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vnni::dpbuud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
592 }
593 }
594
596 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
599 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
600 else {
601 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vnni::dpbuud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
602 }
603 }
604
606 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
609 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
610 else {
611 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vnni::dpbuuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
612 }
613 }
614
616 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint8))
619 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
620 else {
621 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vnni::dpbuuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
622 }
623 }
624
626 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
629 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
630 else {
631 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwsud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
632 }
633 }
634
636 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
639 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
640 else {
641 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwsud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
642 }
643 }
644
646 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
649 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
650 else {
651 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwsuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
652 }
653 }
654
656 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
659 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
660 else {
661 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwsuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
662 }
663 }
664
666 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
669 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
670 else {
671 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
672 }
673 }
674
676 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
679 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
680 else {
681 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwusd<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
682 }
683 }
684
686 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
689 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
690 else {
691 return simd<std::int32_t, 4, Arch>::from_native(detail::x86_vnni::dpwusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
692 }
693 }
694
696 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
699 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
700 else {
701 return simd<std::int32_t, 8, Arch>::from_native(detail::x86_vnni::dpwusds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
702 }
703 }
704
706 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
709 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
710 else {
711 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vnni::dpwuud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
712 }
713 }
714
716 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
719 if consteval { return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false); }
720 else {
721 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vnni::dpwuud<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
722 }
723 }
724
726 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
729 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
730 else {
731 return simd<std::uint32_t, 4, Arch>::from_native(detail::x86_vnni::dpwuuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
732 }
733 }
734
736 template<isa<x86> Arch> requires(Arch.has(x86_feature::avxvnniint16))
739 if consteval { return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false); }
740 else {
741 return simd<std::uint32_t, 8, Arch>::from_native(detail::x86_vnni::dpwuuds<Arch>(accumulator.to_native(), a.to_native(), b.to_native()));
742 }
743 }
744
746 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
747 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
748 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
750 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
751 }
752
754 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
755 Arch.has(x86_feature::avx512vl))) &&
756 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
758 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false);
759 }
760
762 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
763 Arch.has(x86_feature::avx512vl))) &&
764 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
766 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true);
767 }
768
770 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
771 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
772 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
774 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
775 }
776
778 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
779 Arch.has(x86_feature::avx512vl))) &&
780 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
782 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false);
783 }
784
786 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
787 Arch.has(x86_feature::avx512vl))) &&
788 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
790 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true);
791 }
792
794 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
795 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
796 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
798 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
799 }
800
802 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
803 Arch.has(x86_feature::avx512vl))) &&
804 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
806 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false);
807 }
808
810 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
811 Arch.has(x86_feature::avx512vl))) &&
812 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
814 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true);
815 }
816
818 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
819 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
820 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
822 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
823 }
824
826 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
827 Arch.has(x86_feature::avx512vl))) &&
828 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
830 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false);
831 }
832
834 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
835 Arch.has(x86_feature::avx512vl))) &&
836 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
838 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true);
839 }
840
842 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
843 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
844 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
846 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
847 }
848
850 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
851 Arch.has(x86_feature::avx512vl))) &&
852 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
854 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false);
855 }
856
858 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
859 Arch.has(x86_feature::avx512vl))) &&
860 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
862 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true);
863 }
864
866 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
867 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
868 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
870 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
871 }
872
874 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
875 Arch.has(x86_feature::avx512vl))) &&
876 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
878 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false);
879 }
880
882 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
883 Arch.has(x86_feature::avx512vl))) &&
884 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
886 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true);
887 }
888
890 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
891 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
892 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
894 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
895 }
896
898 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
899 Arch.has(x86_feature::avx512vl))) &&
900 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
902 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false);
903 }
904
906 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
907 Arch.has(x86_feature::avx512vl))) &&
908 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
910 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true);
911 }
912
914 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnni)) || (!Arch.has(x86_feature::avxvnni) &&
915 Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) && Arch.has(x86_feature::avx512vl))) &&
916 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
918 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
919 }
920
922 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
923 Arch.has(x86_feature::avx512vl))) &&
924 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
926 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false);
927 }
928
930 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni) &&
931 Arch.has(x86_feature::avx512vl))) &&
932 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
934 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true);
935 }
936
938 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
939 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::int8_t, 64, Arch>); })
941 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
942 }
943
945 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
946 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::int8_t, 64, Arch>); })
948 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false);
949 }
950
952 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
953 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::int8_t, 64, Arch>); })
955 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true);
956 }
957
959 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
960 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::int8_t, 64, Arch>); })
962 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
963 }
964
966 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
967 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::int8_t, 64, Arch>); })
969 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false);
970 }
971
973 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
974 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::uint8_t, 64, Arch>); sizeof(simd<std::int8_t, 64, Arch>); })
976 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true);
977 }
978
980 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
981 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::int16_t, 32, Arch>); })
983 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
984 }
985
987 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
988 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::int16_t, 32, Arch>); })
990 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), false);
991 }
992
994 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
995 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::int16_t, 32, Arch>); })
997 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, mask.to_bitset(), true);
998 }
999
1001 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
1002 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::int16_t, 32, Arch>); })
1004 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1005 }
1006
1008 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
1009 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::int16_t, 32, Arch>); })
1011 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), false);
1012 }
1013
1015 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avx512f) && Arch.has(x86_feature::avx512vnni))) &&
1016 requires { sizeof(simd<std::int32_t, 16, Arch>); sizeof(simd<std::int16_t, 32, Arch>); })
1018 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, mask.to_bitset(), true);
1019 }
1020
1022 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1023 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
1025 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1026 }
1027
1029 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1030 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
1032 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1033 }
1034
1036 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1037 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int8_t, 16, Arch>); })
1039 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1040 }
1041
1043 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1044 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int8_t, 32, Arch>); })
1046 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1047 }
1048
1050 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1051 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int8_t, 16, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); })
1053 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1054 }
1055
1057 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1058 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int8_t, 32, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); })
1060 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1061 }
1062
1064 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1065 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int8_t, 16, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); })
1067 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1068 }
1069
1071 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1072 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int8_t, 32, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); })
1074 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1075 }
1076
1078 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1079 requires { sizeof(simd<std::uint32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); })
1081 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1082 }
1083
1085 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1086 requires { sizeof(simd<std::uint32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); })
1088 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1089 }
1090
1092 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1093 requires { sizeof(simd<std::uint32_t, 4, Arch>); sizeof(simd<std::uint8_t, 16, Arch>); })
1095 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1096 }
1097
1099 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint8))) &&
1100 requires { sizeof(simd<std::uint32_t, 8, Arch>); sizeof(simd<std::uint8_t, 32, Arch>); })
1102 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1103 }
1104
1106 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1107 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); sizeof(simd<std::uint16_t, 8, Arch>); })
1109 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1110 }
1111
1113 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1114 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); sizeof(simd<std::uint16_t, 16, Arch>); })
1116 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1117 }
1118
1120 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1121 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::int16_t, 8, Arch>); sizeof(simd<std::uint16_t, 8, Arch>); })
1123 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1124 }
1125
1127 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1128 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::int16_t, 16, Arch>); sizeof(simd<std::uint16_t, 16, Arch>); })
1130 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1131 }
1132
1134 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1135 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint16_t, 8, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
1137 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1138 }
1139
1141 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1142 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint16_t, 16, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
1144 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1145 }
1146
1148 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1149 requires { sizeof(simd<std::int32_t, 4, Arch>); sizeof(simd<std::uint16_t, 8, Arch>); sizeof(simd<std::int16_t, 8, Arch>); })
1151 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1152 }
1153
1155 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1156 requires { sizeof(simd<std::int32_t, 8, Arch>); sizeof(simd<std::uint16_t, 16, Arch>); sizeof(simd<std::int16_t, 16, Arch>); })
1158 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1159 }
1160
1162 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1163 requires { sizeof(simd<std::uint32_t, 4, Arch>); sizeof(simd<std::uint16_t, 8, Arch>); })
1165 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1166 }
1167
1169 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1170 requires { sizeof(simd<std::uint32_t, 8, Arch>); sizeof(simd<std::uint16_t, 16, Arch>); })
1172 return detail::x86_instruction_constant::dot<false>(accumulator, a, b, ~std::uint64_t{0}, false);
1173 }
1174
1176 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1177 requires { sizeof(simd<std::uint32_t, 4, Arch>); sizeof(simd<std::uint16_t, 8, Arch>); })
1179 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1180 }
1181
1183 template<isa<x86> Arch> requires(!((Arch.has(x86_feature::avxvnniint16))) &&
1184 requires { sizeof(simd<std::uint32_t, 8, Arch>); sizeof(simd<std::uint16_t, 16, Arch>); })
1186 return detail::x86_instruction_constant::dot<true>(accumulator, a, b, ~std::uint64_t{0}, false);
1187 }
1188
1189 // Reject implicit register conversions, mixed tags and wrong element types.
1191 template<isa<x86> Arch, class... Args>
1192 void dpbusd(Args...) = delete;
1194 template<isa<x86> Arch, class... Args>
1195 void mask_dpbusd(Args...) = delete;
1197 template<isa<x86> Arch, class... Args>
1198 void maskz_dpbusd(Args...) = delete;
1200 template<isa<x86> Arch, class... Args>
1201 void dpbusds(Args...) = delete;
1203 template<isa<x86> Arch, class... Args>
1204 void mask_dpbusds(Args...) = delete;
1206 template<isa<x86> Arch, class... Args>
1207 void maskz_dpbusds(Args...) = delete;
1209 template<isa<x86> Arch, class... Args>
1210 void dpwssd(Args...) = delete;
1212 template<isa<x86> Arch, class... Args>
1213 void mask_dpwssd(Args...) = delete;
1215 template<isa<x86> Arch, class... Args>
1216 void maskz_dpwssd(Args...) = delete;
1218 template<isa<x86> Arch, class... Args>
1219 void dpwssds(Args...) = delete;
1221 template<isa<x86> Arch, class... Args>
1222 void mask_dpwssds(Args...) = delete;
1224 template<isa<x86> Arch, class... Args>
1225 void maskz_dpwssds(Args...) = delete;
1227 template<isa<x86> Arch, class... Args>
1228 void dpbssd(Args...) = delete;
1230 template<isa<x86> Arch, class... Args>
1231 void dpbssds(Args...) = delete;
1233 template<isa<x86> Arch, class... Args>
1234 void dpbsud(Args...) = delete;
1236 template<isa<x86> Arch, class... Args>
1237 void dpbsuds(Args...) = delete;
1239 template<isa<x86> Arch, class... Args>
1240 void dpbuud(Args...) = delete;
1242 template<isa<x86> Arch, class... Args>
1243 void dpbuuds(Args...) = delete;
1245 template<isa<x86> Arch, class... Args>
1246 void dpwsud(Args...) = delete;
1248 template<isa<x86> Arch, class... Args>
1249 void dpwsuds(Args...) = delete;
1251 template<isa<x86> Arch, class... Args>
1252 void dpwusd(Args...) = delete;
1254 template<isa<x86> Arch, class... Args>
1255 void dpwusds(Args...) = delete;
1257 template<isa<x86> Arch, class... Args>
1258 void dpwuud(Args...) = delete;
1260 template<isa<x86> Arch, class... Args>
1261 void dpwuuds(Args...) = delete;
1262
1264
1265}
1266#endif
#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
#define native_target(x)
this indicates a required feature set for the current multiversioned function.
Definition attributes.h:476
typename mask_traits< std::remove_cvref_t< T > >::type mask
Definition mask_traits.h:22
constexpr simd< std::int32_t, 4, Arch > maskz_dpbusds(predicate< 4, Arch > mask, simd< std::int32_t, 4, Arch > accumulator, simd< std::uint8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
dpbusds in active lanes; inactive lanes become zero.
constexpr simd< std::int32_t, 4, Arch > dpwssds(simd< std::int32_t, 4, Arch > accumulator, simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
Accumulate products of two signed words from a and b, with signed 32-bit saturation....
constexpr simd< std::uint32_t, 4, Arch > dpwuud(simd< std::uint32_t, 4, Arch > accumulator, simd< std::uint16_t, 8, Arch > a, simd< std::uint16_t, 8, Arch > b) noexcept
Accumulate products of two unsigned words from a and b, modulo 2^32.
constexpr simd< std::int32_t, 4, Arch > mask_dpbusd(simd< std::int32_t, 4, Arch > accumulator, predicate< 4, Arch > mask, simd< std::uint8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
dpbusd in active lanes; inactive lanes retain accumulator.
constexpr simd< std::int32_t, 4, Arch > mask_dpbusds(simd< std::int32_t, 4, Arch > accumulator, predicate< 4, Arch > mask, simd< std::uint8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
dpbusds in active lanes; inactive lanes retain accumulator.
constexpr simd< std::int32_t, 4, Arch > dpbssd(simd< std::int32_t, 4, Arch > accumulator, simd< std::int8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
Accumulate products of four signed bytes from a and b, modulo 2^32.
constexpr simd< std::int32_t, 4, Arch > mask_dpwssds(simd< std::int32_t, 4, Arch > accumulator, predicate< 4, Arch > mask, simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
dpwssds in active lanes; inactive lanes retain accumulator.
constexpr simd< std::int32_t, 4, Arch > dpbusds(simd< std::int32_t, 4, Arch > accumulator, simd< std::uint8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
Accumulate products of four unsigned bytes from a and signed bytes from b, with signed 32-bit saturat...
constexpr simd< std::int32_t, 4, Arch > dpbsuds(simd< std::int32_t, 4, Arch > accumulator, simd< std::int8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Accumulate products of four signed bytes from a and unsigned bytes from b, with signed 32-bit saturat...
constexpr simd< std::int32_t, 4, Arch > dpwssd(simd< std::int32_t, 4, Arch > accumulator, simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
Accumulate products of two signed words from a and b, modulo 2^32. Uses AVX-VNNI.
constexpr simd< std::int32_t, 4, Arch > dpbusd(simd< std::int32_t, 4, Arch > accumulator, simd< std::uint8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
Accumulate products of four unsigned bytes from a and signed bytes from b, modulo 2^32....
constexpr simd< std::int32_t, 4, Arch > mask_dpwssd(simd< std::int32_t, 4, Arch > accumulator, predicate< 4, Arch > mask, simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
dpwssd in active lanes; inactive lanes retain accumulator.
constexpr simd< std::int32_t, 4, Arch > dpwsuds(simd< std::int32_t, 4, Arch > accumulator, simd< std::int16_t, 8, Arch > a, simd< std::uint16_t, 8, Arch > b) noexcept
Accumulate products of two signed words from a and unsigned words from b, with signed 32-bit saturati...
constexpr simd< std::int32_t, 4, Arch > maskz_dpwssds(predicate< 4, Arch > mask, simd< std::int32_t, 4, Arch > accumulator, simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
dpwssds in active lanes; inactive lanes become zero.
constexpr simd< std::int32_t, 4, Arch > dpwusds(simd< std::int32_t, 4, Arch > accumulator, simd< std::uint16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
Accumulate products of two unsigned words from a and signed words from b, with signed 32-bit saturati...
constexpr simd< std::uint32_t, 4, Arch > dpwuuds(simd< std::uint32_t, 4, Arch > accumulator, simd< std::uint16_t, 8, Arch > a, simd< std::uint16_t, 8, Arch > b) noexcept
Accumulate products of two unsigned words from a and b, with unsigned 32-bit saturation.
constexpr simd< std::uint32_t, 4, Arch > dpbuuds(simd< std::uint32_t, 4, Arch > accumulator, simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Accumulate products of four unsigned bytes from a and b, with unsigned 32-bit saturation.
constexpr simd< std::int32_t, 4, Arch > dpbssds(simd< std::int32_t, 4, Arch > accumulator, simd< std::int8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
Accumulate products of four signed bytes from a and b, with signed 32-bit saturation.
constexpr simd< std::int32_t, 4, Arch > maskz_dpwssd(predicate< 4, Arch > mask, simd< std::int32_t, 4, Arch > accumulator, simd< std::int16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
dpwssd in active lanes; inactive lanes become zero.
constexpr simd< std::uint32_t, 4, Arch > dpbuud(simd< std::uint32_t, 4, Arch > accumulator, simd< std::uint8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Accumulate products of four unsigned bytes from a and b, modulo 2^32.
constexpr simd< std::int32_t, 4, Arch > dpwusd(simd< std::int32_t, 4, Arch > accumulator, simd< std::uint16_t, 8, Arch > a, simd< std::int16_t, 8, Arch > b) noexcept
Accumulate products of two unsigned words from a and signed words from b, modulo 2^32.
constexpr simd< std::int32_t, 4, Arch > dpwsud(simd< std::int32_t, 4, Arch > accumulator, simd< std::int16_t, 8, Arch > a, simd< std::uint16_t, 8, Arch > b) noexcept
Accumulate products of two signed words from a and unsigned words from b, modulo 2^32.
constexpr simd< std::int32_t, 4, Arch > maskz_dpbusd(predicate< 4, Arch > mask, simd< std::int32_t, 4, Arch > accumulator, simd< std::uint8_t, 16, Arch > a, simd< std::int8_t, 16, Arch > b) noexcept
dpbusd in active lanes; inactive lanes become zero.
constexpr simd< std::int32_t, 4, Arch > dpbsud(simd< std::int32_t, 4, Arch > accumulator, simd< std::int8_t, 16, Arch > a, simd< std::uint8_t, 16, Arch > b) noexcept
Accumulate products of four signed bytes from a and unsigned bytes from b, modulo 2^32.
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Standard-library adaptations documented here for SIMD value types.
Omitted architecture arguments use the native.simd provider's baseline.