usearch 2.26.1 → 2.26.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +1 -1
  2. package/include/usearch/index.hpp +5 -1
  3. package/numkong/CITATION.cff +13 -9
  4. package/numkong/CONTRIBUTING.md +29 -24
  5. package/numkong/Cargo.toml +1 -1
  6. package/numkong/README.md +21 -7
  7. package/numkong/binding.gyp +47 -31
  8. package/numkong/build.rs +15 -5
  9. package/numkong/c/dispatch.h +0 -1
  10. package/numkong/c/parallel.c +139 -0
  11. package/numkong/c/parallel.h +47 -0
  12. package/numkong/cmake/toolchain-wasi.cmake +39 -5
  13. package/numkong/include/README.md +24 -17
  14. package/numkong/include/numkong/attention/sapphireamx.h +6 -6
  15. package/numkong/include/numkong/attention/sme.h +2 -2
  16. package/numkong/include/numkong/capabilities.h +2 -2
  17. package/numkong/include/numkong/cast/README.md +9 -7
  18. package/numkong/include/numkong/cast/loongsonasx.h +48 -40
  19. package/numkong/include/numkong/cast/serial.h +89 -11
  20. package/numkong/include/numkong/cast.h +3 -3
  21. package/numkong/include/numkong/curved/README.md +10 -10
  22. package/numkong/include/numkong/curved/neon.h +1 -0
  23. package/numkong/include/numkong/curved/neonbfdot.h +1 -0
  24. package/numkong/include/numkong/curved/smef64.h +1 -0
  25. package/numkong/include/numkong/dot/README.md +18 -18
  26. package/numkong/include/numkong/dot/alder.h +8 -8
  27. package/numkong/include/numkong/dot/haswell.h +8 -8
  28. package/numkong/include/numkong/dot/icelake.h +12 -12
  29. package/numkong/include/numkong/dot/loongsonasx.h +6 -6
  30. package/numkong/include/numkong/dot/neon.h +2 -1
  31. package/numkong/include/numkong/dot/neonbfdot.h +1 -0
  32. package/numkong/include/numkong/dot/neonfhm.h +1 -0
  33. package/numkong/include/numkong/dot/neonsdot.h +1 -0
  34. package/numkong/include/numkong/dot/powervsx.h +3 -3
  35. package/numkong/include/numkong/dot/serial.h +19 -6
  36. package/numkong/include/numkong/dot/skylake.h +4 -4
  37. package/numkong/include/numkong/dot/svehalf.h +1 -1
  38. package/numkong/include/numkong/dot/v128relaxed.h +24 -23
  39. package/numkong/include/numkong/dots/README.md +26 -26
  40. package/numkong/include/numkong/dots/genoa.h +3 -1
  41. package/numkong/include/numkong/dots/icelake.h +1 -0
  42. package/numkong/include/numkong/dots/powervsx.h +1 -1
  43. package/numkong/include/numkong/dots/serial.h +32 -33
  44. package/numkong/include/numkong/dots/sierra.h +4 -3
  45. package/numkong/include/numkong/each/README.md +5 -3
  46. package/numkong/include/numkong/each/sapphire.h +2 -0
  47. package/numkong/include/numkong/each/skylake.h +1 -0
  48. package/numkong/include/numkong/geospatial/README.md +6 -6
  49. package/numkong/include/numkong/geospatial/v128relaxed.h +1 -0
  50. package/numkong/include/numkong/maxsim/README.md +5 -5
  51. package/numkong/include/numkong/maxsim/genoa.h +4 -0
  52. package/numkong/include/numkong/maxsim/icelake.h +1 -0
  53. package/numkong/include/numkong/maxsim/serial.h +22 -9
  54. package/numkong/include/numkong/maxsim/sme.h +3 -2
  55. package/numkong/include/numkong/mesh/README.md +7 -4
  56. package/numkong/include/numkong/mesh/genoa.h +2 -2
  57. package/numkong/include/numkong/mesh/haswell.h +8 -8
  58. package/numkong/include/numkong/mesh/neon.h +6 -6
  59. package/numkong/include/numkong/mesh/neonbfdot.h +3 -2
  60. package/numkong/include/numkong/mesh/neonfhm.h +3 -2
  61. package/numkong/include/numkong/mesh/rvv.h +4 -4
  62. package/numkong/include/numkong/mesh/serial.h +17 -17
  63. package/numkong/include/numkong/mesh/skylake.h +4 -4
  64. package/numkong/include/numkong/mesh/v128relaxed.h +4 -4
  65. package/numkong/include/numkong/mesh.hpp +2 -2
  66. package/numkong/include/numkong/numkong.h +1 -1
  67. package/numkong/include/numkong/numkong.hpp +1 -1
  68. package/numkong/include/numkong/probability/README.md +17 -15
  69. package/numkong/include/numkong/probability/skylake.h +1 -1
  70. package/numkong/include/numkong/reduce/README.md +27 -21
  71. package/numkong/include/numkong/reduce/genoa.h +2 -1
  72. package/numkong/include/numkong/reduce/icelake.h +1 -0
  73. package/numkong/include/numkong/reduce/neon.h +1 -1
  74. package/numkong/include/numkong/reduce/serial.h +9 -9
  75. package/numkong/include/numkong/reduce/skylake.h +4 -4
  76. package/numkong/include/numkong/reduce.hpp +38 -0
  77. package/numkong/include/numkong/scalar/README.md +29 -28
  78. package/numkong/include/numkong/set/README.md +17 -14
  79. package/numkong/include/numkong/set/haswell.h +15 -16
  80. package/numkong/include/numkong/set/icelake.h +15 -16
  81. package/numkong/include/numkong/set/loongsonasx.h +12 -10
  82. package/numkong/include/numkong/set/neon.h +15 -19
  83. package/numkong/include/numkong/set/powervsx.h +15 -21
  84. package/numkong/include/numkong/set/serial.h +19 -20
  85. package/numkong/include/numkong/set/v128relaxed.h +10 -8
  86. package/numkong/include/numkong/sets/icelake.h +1 -0
  87. package/numkong/include/numkong/sparse/README.md +4 -4
  88. package/numkong/include/numkong/sparse/icelake.h +1 -0
  89. package/numkong/include/numkong/sparse/neon.h +1 -0
  90. package/numkong/include/numkong/sparse/serial.h +10 -3
  91. package/numkong/include/numkong/sparse/turin.h +1 -0
  92. package/numkong/include/numkong/spatial/README.md +25 -24
  93. package/numkong/include/numkong/spatial/alder.h +2 -1
  94. package/numkong/include/numkong/spatial/haswell.h +48 -40
  95. package/numkong/include/numkong/spatial/icelake.h +2 -1
  96. package/numkong/include/numkong/spatial/neon.h +54 -46
  97. package/numkong/include/numkong/spatial/neonbfdot.h +1 -1
  98. package/numkong/include/numkong/spatial/powervsx.h +54 -46
  99. package/numkong/include/numkong/spatial/serial.h +56 -46
  100. package/numkong/include/numkong/spatial/sierra.h +4 -3
  101. package/numkong/include/numkong/spatial/skylake.h +27 -22
  102. package/numkong/include/numkong/spatial/sve.h +6 -6
  103. package/numkong/include/numkong/spatial/svebfdot.h +1 -1
  104. package/numkong/include/numkong/spatial/svehalf.h +1 -1
  105. package/numkong/include/numkong/spatial/v128relaxed.h +36 -30
  106. package/numkong/include/numkong/spatials/README.md +15 -15
  107. package/numkong/include/numkong/spatials/genoa.h +3 -0
  108. package/numkong/include/numkong/spatials/graniteamx.h +2 -0
  109. package/numkong/include/numkong/spatials/icelake.h +1 -0
  110. package/numkong/include/numkong/spatials/sierra.h +1 -0
  111. package/numkong/include/numkong/tensor.hpp +236 -123
  112. package/numkong/include/numkong/trigonometry/README.md +4 -4
  113. package/numkong/include/numkong/trigonometry/serial.h +6 -6
  114. package/numkong/include/numkong/trigonometry/v128relaxed.h +1 -0
  115. package/numkong/include/numkong/types.hpp +46 -16
  116. package/numkong/include/numkong/vector.hpp +116 -23
  117. package/numkong/javascript/@numkong-darwin-arm64/package.json +1 -1
  118. package/numkong/javascript/@numkong-darwin-x64/package.json +1 -1
  119. package/numkong/javascript/@numkong-linux-arm64/package.json +1 -1
  120. package/numkong/javascript/@numkong-linux-x64/package.json +1 -1
  121. package/numkong/javascript/@numkong-win32-arm64/package.json +1 -1
  122. package/numkong/javascript/@numkong-win32-x64/package.json +1 -1
  123. package/numkong/javascript/README.md +18 -16
  124. package/numkong/javascript/numkong.c +70 -40
  125. package/numkong/package.json +8 -8
  126. package/numkong/rust/README.md +19 -9
  127. package/numkong/rust/cast.rs +52 -1
  128. package/numkong/rust/each.rs +480 -7
  129. package/numkong/rust/matrix.rs +877 -216
  130. package/numkong/rust/numkong.rs +12 -8
  131. package/numkong/rust/reduce.rs +433 -5
  132. package/numkong/rust/tensor.rs +450 -842
  133. package/numkong/rust/vector.rs +520 -101
  134. package/numkong/swift/README.md +5 -3
  135. package/numkong/test/README.md +4 -4
  136. package/numkong/test/test-wasi.mjs +17 -0
  137. package/numkong/test/test_each.cpp +30 -1
  138. package/numkong/test/test_each.py +74 -1
  139. package/numkong/test/test_reduce.cpp +51 -0
  140. package/numkong/test/test_tensor.cpp +2 -63
  141. package/numkong/test/test_tensor.py +93 -0
  142. package/package.json +1 -1
  143. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  144. package/prebuilds/linux-arm64/usearch.node +0 -0
  145. package/prebuilds/linux-x64/usearch.node +0 -0
  146. package/prebuilds/win32-x64/usearch.node +0 -0
@@ -11,9 +11,9 @@
11
11
  * - `f16` & `bf16` ↔ `f32` - often used for half-precision dot-products on older CPUs,
12
12
  *
13
13
  * Unlike most operation classes in NumKong, these are dependent on two input types: "from" & "to".
14
- * It contains scalar helpers named like `nk_f16_to_f32_serial_` as well as buffer-to-buffer
15
- * `memcpy`-like vectorized operations, such as `nk_cast_f16_to_f32` with `nk_cast_f16_to_f32_serial`,
16
- * `nk_cast_f16_to_f32_neon`, `nk_cast_f16_to_f32_skylake`, and other platform-specific variants.
14
+ * It contains scalar helpers named like `nk_f16_to_f32_serial` as well as buffer-to-buffer
15
+ * `memcpy`-like vectorized operations, such as `nk_cast` with `nk_cast_serial`,
16
+ * `nk_cast_neon`, `nk_cast_skylake`, and other platform-specific variants.
17
17
  *
18
18
  * It also includes "partial load" and "partial store" type-punned helper functions for handling
19
19
  * IO between memory and registers, that are extensively reused in reductions, elementwise ops, and
@@ -42,19 +42,19 @@ def bilinear_complex(a: np.ndarray, b: np.ndarray, C: np.ndarray) -> complex:
42
42
 
43
43
  Real bilinear and Mahalanobis:
44
44
 
45
- | Input Type | Output Type | Description |
46
- | ---------- | ----------- | ---------------------------------------------- |
47
- | `f64` | `f64` | 64-bit IEEE 754 double precision |
48
- | `f32` | `f32` | 32-bit IEEE 754 single precision |
49
- | `f16` | `f32` | 16-bit IEEE 754 half precision, widened output |
50
- | `bf16` | `f32` | 16-bit brain float, widened output |
45
+ | Input Type | Output Type | Description |
46
+ | ---------- | ----------- | ------------------------------------------------ |
47
+ | `f64` | `f64` | 64-bit IEEE 754 double precision |
48
+ | `f32` | `f64` | 32-bit IEEE 754 single precision, widened output |
49
+ | `f16` | `f32` | 16-bit IEEE 754 half precision, widened output |
50
+ | `bf16` | `f32` | 16-bit brain float, widened output |
51
51
 
52
52
  Complex bilinear:
53
53
 
54
54
  | Input Type | Output Type | Description |
55
55
  | ---------- | ----------- | ------------------------------------------ |
56
56
  | `f64c` | `f64c` | 64-bit complex pairs |
57
- | `f32c` | `f32c` | 32-bit complex pairs |
57
+ | `f32c` | `f64c` | 32-bit complex pairs, widened output |
58
58
  | `f16c` | `f32c` | 16-bit complex pairs, widened output |
59
59
  | `bf16c` | `f32c` | 16-bit brain complex pairs, widened output |
60
60
 
@@ -179,7 +179,7 @@ Measured with Wasmtime v42 (Cranelift backend).
179
179
  | `nk_bilinear_bf16c_neonbfdot` | 5.05 gso/s, 17.0 ulp | 4.20 gso/s, 17.0 ulp | 4.04 gso/s, 17.0 ulp |
180
180
  | __f16c__ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ |
181
181
  | `nk_bilinear_f16c_serial` | 2.81 gso/s, 51.8 ulp | 2.54 gso/s, 51.8 ulp | 2.48 gso/s, 51.8 ulp |
182
- | `nk_bilinear_f16c_neonhalf` | 5.00 gso/s, 17.3 ulp | 4.16 gso/s, 17.3 ulp | 4.00 gso/s, 16.4 ulp |
182
+ | `nk_bilinear_f16c_neon` | 5.00 gso/s, 17.3 ulp | 4.16 gso/s, 17.3 ulp | 4.00 gso/s, 16.4 ulp |
183
183
  | __f64__ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ |
184
184
  | `nk_bilinear_f64_serial` | 0.717 gso/s, 0.4 ulp | 0.711 gso/s, 0.4 ulp | 0.721 gso/s, 0.4 ulp |
185
185
  | `nk_mahalanobis_f64_serial` | 0.664 gso/s, 0.5 ulp | 0.667 gso/s, 0.5 ulp | 0.672 gso/s, 0.5 ulp |
@@ -196,8 +196,8 @@ Measured with Wasmtime v42 (Cranelift backend).
196
196
  | __f16__ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ |
197
197
  | `nk_bilinear_f16_serial` | ? gso/s, ? ulp | ? gso/s, ? ulp | ? gso/s, ? ulp |
198
198
  | `nk_mahalanobis_f16_serial` | ? gso/s, ? ulp | ? gso/s, ? ulp | ? gso/s, ? ulp |
199
- | `nk_bilinear_f16_neonhalf` | ? gso/s, ? ulp | ? gso/s, ? ulp | ? gso/s, ? ulp |
200
- | `nk_mahalanobis_f16_neonhalf` | ? gso/s, ? ulp | ? gso/s, ? ulp | ? gso/s, ? ulp |
199
+ | `nk_bilinear_f16_neon` | ? gso/s, ? ulp | ? gso/s, ? ulp | ? gso/s, ? ulp |
200
+ | `nk_mahalanobis_f16_neon` | ? gso/s, ? ulp | ? gso/s, ? ulp | ? gso/s, ? ulp |
201
201
 
202
202
  #### WASM
203
203
 
@@ -29,6 +29,7 @@
29
29
 
30
30
  #include "numkong/types.h"
31
31
  #include "numkong/spatial/neon.h" // nk_f64_sqrt_neon
32
+ #include "numkong/dot/serial.h" // `nk_dot_f16c_serial`, `nk_vdot_f16c_serial`
32
33
 
33
34
  #if defined(__cplusplus)
34
35
  extern "C" {
@@ -30,6 +30,7 @@
30
30
  #include "numkong/types.h" // `nk_bf16_t`
31
31
  #include "numkong/spatial/neon.h" // `nk_f32_sqrt_neon`
32
32
  #include "numkong/cast/serial.h" // `nk_bf16_to_f32_serial`
33
+ #include "numkong/dot/serial.h" // `nk_dot_f16c_serial`, `nk_vdot_f16c_serial`
33
34
 
34
35
  #if defined(__cplusplus)
35
36
  extern "C" {
@@ -56,6 +56,7 @@
56
56
  #include "numkong/spatial/neon.h" // `nk_f64_sqrt_neon`
57
57
  #include "numkong/dots/sme.h" // `nk_sme_zero_za64_tile_0_`
58
58
  #include "numkong/curved/serial.h" // `nk_bilinear_f64_serial`
59
+ #include "numkong/dot/serial.h" // `nk_dot_f16c_serial`, `nk_vdot_f16c_serial`
59
60
 
60
61
  #if defined(__cplusplus)
61
62
  extern "C" {
@@ -46,28 +46,28 @@ def vdot_complex(a: List[number], b: List[number]) -> Tuple[number, number]:
46
46
 
47
47
  Real and integer dot products:
48
48
 
49
- | Input Type | Output Type | Description |
50
- | ---------- | ----------- | ---------------------------------------------- |
51
- | `f64` | `f64` | 64-bit IEEE 754 double precision |
52
- | `f32` | `f32` | 32-bit IEEE 754 single precision |
53
- | `f16` | `f32` | 16-bit IEEE 754 half precision, widened output |
54
- | `bf16` | `f32` | 16-bit brain float, widened output |
55
- | `e4m3` | `f32` | 8-bit Float8: 4 exponent, 3 mantissa bits |
56
- | `e5m2` | `f32` | 8-bit Float8: 5 exponent, 2 mantissa bits |
57
- | `e2m3` | `f32` | 8-bit MX format: 2 exponent, 3 mantissa bits |
58
- | `e3m2` | `f32` | 8-bit MX format: 3 exponent, 2 mantissa bits |
59
- | `i8` | `i32` | 8-bit signed integers |
60
- | `u8` | `u32` | 8-bit unsigned integers |
61
- | `i4` | `i32` | 4-bit signed integers, packed nibble pairs |
62
- | `u4` | `u32` | 4-bit unsigned integers, packed nibble pairs |
63
- | `u1` | `u32` | 1-bit binary packed octets, popcount of AND |
49
+ | Input Type | Output Type | Description |
50
+ | ---------- | ----------- | ------------------------------------------------ |
51
+ | `f64` | `f64` | 64-bit IEEE 754 double precision |
52
+ | `f32` | `f64` | 32-bit IEEE 754 single precision, widened output |
53
+ | `f16` | `f32` | 16-bit IEEE 754 half precision, widened output |
54
+ | `bf16` | `f32` | 16-bit brain float, widened output |
55
+ | `e4m3` | `f32` | 8-bit Float8: 4 exponent, 3 mantissa bits |
56
+ | `e5m2` | `f32` | 8-bit Float8: 5 exponent, 2 mantissa bits |
57
+ | `e2m3` | `f32` | 8-bit MX format: 2 exponent, 3 mantissa bits |
58
+ | `e3m2` | `f32` | 8-bit MX format: 3 exponent, 2 mantissa bits |
59
+ | `i8` | `i32` | 8-bit signed integers |
60
+ | `u8` | `u32` | 8-bit unsigned integers |
61
+ | `i4` | `i32` | 4-bit signed integers, packed nibble pairs |
62
+ | `u4` | `u32` | 4-bit unsigned integers, packed nibble pairs |
63
+ | `u1` | `u32` | 1-bit binary packed octets, popcount of AND |
64
64
 
65
65
  Complex dot products (both `dot` and `vdot`):
66
66
 
67
67
  | Input Type | Output Type | Description |
68
68
  | ---------- | ----------- | ------------------------------------------ |
69
69
  | `f64c` | `f64c` | 64-bit complex pairs |
70
- | `f32c` | `f32c` | 32-bit complex pairs |
70
+ | `f32c` | `f64c` | 32-bit complex pairs, widened output |
71
71
  | `f16c` | `f32c` | 16-bit complex pairs, widened output |
72
72
  | `bf16c` | `f32c` | 16-bit brain complex pairs, widened output |
73
73
 
@@ -330,8 +330,8 @@ Measured with Wasmtime v42 (Cranelift backend).
330
330
  | __f16c__ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ |
331
331
  | `nk_dot_f16c_serial` | 15.8 gb/s, 20.8 ulp | 13.0 gb/s, 64.1 ulp | 12.3 gb/s, 73.1 ulp |
332
332
  | `nk_vdot_f16c_serial` | 15.8 gb/s, 24.8 ulp | 13.0 gb/s, 31.9 ulp | 12.3 gb/s, 137 ulp |
333
- | `nk_dot_f16c_neonhalf` | 26.1 gb/s, 3.0 ulp | 18.4 gb/s, 6.5 ulp | 16.8 gb/s, 20.5 ulp |
334
- | `nk_vdot_f16c_neonhalf` | 26.1 gb/s, 34.9 ulp | 18.5 gb/s, 40.7 ulp | 17.0 gb/s, 73.1 ulp |
333
+ | `nk_dot_f16c_neon` | 26.1 gb/s, 3.0 ulp | 18.4 gb/s, 6.5 ulp | 16.8 gb/s, 20.5 ulp |
334
+ | `nk_vdot_f16c_neon` | 26.1 gb/s, 34.9 ulp | 18.5 gb/s, 40.7 ulp | 17.0 gb/s, 73.1 ulp |
335
335
  | `nk_dot_f16c_neonfhm` | 25.3 gb/s, 3.0 ulp | 17.1 gb/s, 6.5 ulp | 15.9 gb/s, 20.5 ulp |
336
336
  | `nk_vdot_f16c_neonfhm` | 25.0 gb/s, 31.4 ulp | 17.0 gb/s, 38.6 ulp | 15.8 gb/s, 67.6 ulp |
337
337
  | __f64__ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ | ░░░░░░░░░░░░░░░░░░░░░░░░ |
@@ -192,8 +192,8 @@ NK_INTERNAL void nk_dot_i8x32_finalize_alder(
192
192
  nk_dot_i8x32_state_alder_t const *state_c, nk_dot_i8x32_state_alder_t const *state_d, //
193
193
  nk_size_t total_dimensions, //
194
194
  nk_i32_t a_sum, /* A row sum (unused for i8) */ //
195
- nk_b128_vec_t b_sums, /* 4 × i32 B column sums */ //
196
- nk_b128_vec_t *results) {
195
+ nk_b128_vec_t const *b_sums_vec, /* 4 × i32 B column sums */ //
196
+ nk_b128_vec_t *result_vec) {
197
197
  nk_unused_(total_dimensions);
198
198
  nk_unused_(a_sum);
199
199
 
@@ -217,8 +217,8 @@ NK_INTERNAL void nk_dot_i8x32_finalize_alder(
217
217
  _mm_add_epi32(_mm_unpacklo_epi64(t_ab_high, t_cd_high), _mm_unpackhi_epi64(t_ab_high, t_cd_high)));
218
218
 
219
219
  // Apply compensation: result = biased − 128 × Σb
220
- __m128i correction_i32x4 = _mm_slli_epi32(b_sums.xmm, 7); // × 128
221
- results->xmm = _mm_sub_epi32(biased_i32x4, correction_i32x4);
220
+ __m128i correction_i32x4 = _mm_slli_epi32(b_sums_vec->xmm, 7); // × 128
221
+ result_vec->xmm = _mm_sub_epi32(biased_i32x4, correction_i32x4);
222
222
  }
223
223
 
224
224
  NK_PUBLIC void nk_dot_u8_alder(nk_u8_t const *a_scalars, nk_u8_t const *b_scalars, nk_size_t count_scalars,
@@ -312,8 +312,8 @@ NK_INTERNAL void nk_dot_u8x32_finalize_alder(
312
312
  nk_dot_u8x32_state_alder_t const *state_c, nk_dot_u8x32_state_alder_t const *state_d, //
313
313
  nk_size_t total_dimensions, //
314
314
  nk_i32_t a_sum, /* A row sum (unused for u8) */ //
315
- nk_b128_vec_t b_sums, /* 4 × u32 B column sums */ //
316
- nk_b128_vec_t *result) {
315
+ nk_b128_vec_t const *b_sums_vec, /* 4 × u32 B column sums */ //
316
+ nk_b128_vec_t *result_vec) {
317
317
  nk_unused_(total_dimensions);
318
318
  nk_unused_(a_sum);
319
319
 
@@ -337,8 +337,8 @@ NK_INTERNAL void nk_dot_u8x32_finalize_alder(
337
337
  _mm_add_epi32(_mm_unpacklo_epi64(t_ab_high, t_cd_high), _mm_unpackhi_epi64(t_ab_high, t_cd_high)));
338
338
 
339
339
  // Apply compensation: result = biased + 128 × Σb
340
- __m128i correction_i32x4 = _mm_slli_epi32(b_sums.xmm, 7); // × 128
341
- result->xmm = _mm_add_epi32(biased_i32x4, correction_i32x4);
340
+ __m128i correction_i32x4 = _mm_slli_epi32(b_sums_vec->xmm, 7); // × 128
341
+ result_vec->xmm = _mm_add_epi32(biased_i32x4, correction_i32x4);
342
342
  }
343
343
 
344
344
  /**
@@ -895,7 +895,7 @@ nk_dot_e3m2_haswell_cycle:
895
895
 
896
896
  /**
897
897
  * @brief Internal helper state for dot-products of low-precision types, where 32-bit accumulation is enough.
898
- * @sa nk_dot_f16x8_state_haswell_t, nk_dot_bf16x8_state_haswell_t
898
+ * @sa nk_dot_f16x8_state_haswell_t, nk_dot_bf16x16_state_haswell_t
899
899
  * @sa nk_dot_e4m3x16_state_haswell_t, nk_dot_e5m2x16_state_haswell_t
900
900
  */
901
901
  typedef struct nk_dot_through_f32_state_haswell_t_ {
@@ -904,7 +904,7 @@ typedef struct nk_dot_through_f32_state_haswell_t_ {
904
904
 
905
905
  /**
906
906
  * @brief Initializes 32-bit accumulators for low-precision dot-products.
907
- * @sa nk_dot_f16x8_init_haswell, nk_dot_bf16x8_init_haswell
907
+ * @sa nk_dot_f16x8_init_haswell, nk_dot_bf16x16_init_haswell
908
908
  * @sa nk_dot_e4m3x16_init_haswell, nk_dot_e5m2x16_init_haswell
909
909
  */
910
910
  NK_INTERNAL void nk_dot_through_f32_init_haswell_(nk_dot_through_f32_state_haswell_t_ *state) {
@@ -913,7 +913,7 @@ NK_INTERNAL void nk_dot_through_f32_init_haswell_(nk_dot_through_f32_state_haswe
913
913
 
914
914
  /**
915
915
  * @brief Fuses 32-bit multiplication and accumulation for low-precision dot-products.
916
- * @sa nk_dot_f16x8_update_haswell, nk_dot_bf16x8_update_haswell
916
+ * @sa nk_dot_f16x8_update_haswell, nk_dot_bf16x16_update_haswell
917
917
  * @sa nk_dot_e4m3x16_update_haswell, nk_dot_e5m2x16_update_haswell
918
918
  */
919
919
  NK_INTERNAL void nk_dot_through_f32_update_haswell_(nk_dot_through_f32_state_haswell_t_ *state, nk_b256_vec_t a,
@@ -991,7 +991,7 @@ NK_INTERNAL void nk_dot_e4m3x32_update_haswell_(nk_dot_through_f32_state_haswell
991
991
 
992
992
  /**
993
993
  * @brief Finalizes 4x low-precision dot-products placing them into 4x consecutive 32-bit slots.
994
- * @sa nk_dot_f16x8_finalize_haswell, nk_dot_bf16x8_finalize_haswell
994
+ * @sa nk_dot_f16x8_finalize_haswell, nk_dot_bf16x16_finalize_haswell
995
995
  * @sa nk_dot_e4m3x16_finalize_haswell, nk_dot_e5m2x16_finalize_haswell
996
996
  *
997
997
  * The goal of this kernel is simple - compute 4x horizontal reductions, each involving 8x floats.
@@ -1637,8 +1637,8 @@ NK_INTERNAL void nk_dot_i4x32_finalize_haswell(
1637
1637
  nk_dot_i4x32_state_haswell_t const *state_c, nk_dot_i4x32_state_haswell_t const *state_d, //
1638
1638
  nk_size_t total_dimensions, //
1639
1639
  nk_i32_t a_sum, /* A row sum (signed sum of i4 values) */ //
1640
- nk_b128_vec_t b_sums, /* 4 × i32 B column sums */ //
1641
- nk_b128_vec_t *result) {
1640
+ nk_b128_vec_t const *b_sums_vec, /* 4 × i32 B column sums */ //
1641
+ nk_b128_vec_t *result_vec) {
1642
1642
 
1643
1643
  // Compensated 4-way reduction with external correction sums.
1644
1644
  // Formula: result = biased_product − 8×(Σa + Σb) − 64×depth_padded
@@ -1666,10 +1666,10 @@ NK_INTERNAL void nk_dot_i4x32_finalize_haswell(
1666
1666
 
1667
1667
  // Apply compensation: result = biased − 8×(Σa + Σb) − 64×depth_padded
1668
1668
  __m128i a_sum_broadcast_i32x4 = _mm_set1_epi32(a_sum);
1669
- __m128i ab_sums_i32x4 = _mm_add_epi32(a_sum_broadcast_i32x4, b_sums.xmm);
1669
+ __m128i ab_sums_i32x4 = _mm_add_epi32(a_sum_broadcast_i32x4, b_sums_vec->xmm);
1670
1670
  __m128i correction_i32x4 = _mm_slli_epi32(ab_sums_i32x4, 3); // × 8
1671
1671
  __m128i offset_i32x4 = _mm_set1_epi32((nk_i32_t)(-64LL * (nk_i64_t)depth_nibbles));
1672
- result->xmm = _mm_add_epi32(_mm_sub_epi32(biased_i32x4, correction_i32x4), offset_i32x4);
1672
+ result_vec->xmm = _mm_add_epi32(_mm_sub_epi32(biased_i32x4, correction_i32x4), offset_i32x4);
1673
1673
  }
1674
1674
 
1675
1675
  /**
@@ -246,8 +246,8 @@ NK_INTERNAL void nk_dot_i8x64_finalize_icelake(
246
246
  nk_dot_i8x64_state_icelake_t const *state_c, nk_dot_i8x64_state_icelake_t const *state_d, //
247
247
  nk_size_t total_dimensions, //
248
248
  nk_i32_t a_sum, /* A row sum (unused for i8) */ //
249
- nk_b128_vec_t b_sums, /* 4 × i32 B column sums */ //
250
- nk_b128_vec_t *results) {
249
+ nk_b128_vec_t const *b_sums_vec, /* 4 × i32 B column sums */ //
250
+ nk_b128_vec_t *result_vec) {
251
251
  nk_unused_(total_dimensions);
252
252
  nk_unused_(a_sum);
253
253
 
@@ -277,8 +277,8 @@ NK_INTERNAL void nk_dot_i8x64_finalize_icelake(
277
277
  _mm_add_epi32(_mm_unpacklo_epi64(t_ab_high, t_cd_high), _mm_unpackhi_epi64(t_ab_high, t_cd_high)));
278
278
 
279
279
  // Apply compensation: result = biased − 128 × Σb
280
- __m128i correction_i32x4 = _mm_slli_epi32(b_sums.xmm, 7); // × 128
281
- results->xmm = _mm_sub_epi32(biased_i32x4, correction_i32x4);
280
+ __m128i correction_i32x4 = _mm_slli_epi32(b_sums_vec->xmm, 7); // × 128
281
+ result_vec->xmm = _mm_sub_epi32(biased_i32x4, correction_i32x4);
282
282
  }
283
283
 
284
284
  typedef struct nk_dot_u8x64_state_icelake_t {
@@ -313,8 +313,8 @@ NK_INTERNAL void nk_dot_u8x64_finalize_icelake(
313
313
  nk_dot_u8x64_state_icelake_t const *state_c, nk_dot_u8x64_state_icelake_t const *state_d, //
314
314
  nk_size_t total_dimensions, //
315
315
  nk_i32_t a_sum, /* A row sum (unused for u8) */ //
316
- nk_b128_vec_t b_sums, /* 4 × u32 B column sums */ //
317
- nk_b128_vec_t *result) {
316
+ nk_b128_vec_t const *b_sums_vec, /* 4 × u32 B column sums */ //
317
+ nk_b128_vec_t *result_vec) {
318
318
  nk_unused_(total_dimensions);
319
319
  nk_unused_(a_sum);
320
320
 
@@ -344,8 +344,8 @@ NK_INTERNAL void nk_dot_u8x64_finalize_icelake(
344
344
  _mm_add_epi32(_mm_unpacklo_epi64(t_ab_high, t_cd_high), _mm_unpackhi_epi64(t_ab_high, t_cd_high)));
345
345
 
346
346
  // Apply compensation: result = biased + 128 × Σb
347
- __m128i correction_i32x4 = _mm_slli_epi32(b_sums.xmm, 7); // × 128
348
- result->xmm = _mm_add_epi32(biased_i32x4, correction_i32x4);
347
+ __m128i correction_i32x4 = _mm_slli_epi32(b_sums_vec->xmm, 7); // × 128
348
+ result_vec->xmm = _mm_add_epi32(biased_i32x4, correction_i32x4);
349
349
  }
350
350
 
351
351
  /**
@@ -568,8 +568,8 @@ NK_INTERNAL void nk_dot_i4x128_finalize_icelake(
568
568
  nk_dot_i4x128_state_icelake_t const *state_c, nk_dot_i4x128_state_icelake_t const *state_d, //
569
569
  nk_size_t total_dimensions, //
570
570
  nk_i32_t a_sum, /* A row sum (signed sum of i4 values) */ //
571
- nk_b128_vec_t b_sums, /* 4 × i32 B column sums */ //
572
- nk_b128_vec_t *result) {
571
+ nk_b128_vec_t const *b_sums_vec, /* 4 × i32 B column sums */ //
572
+ nk_b128_vec_t *result_vec) {
573
573
 
574
574
  // Compensated 4-way reduction with external correction sums.
575
575
  // Formula: result = biased_product − 8×(Σa + Σb) − 64×depth_padded
@@ -606,10 +606,10 @@ NK_INTERNAL void nk_dot_i4x128_finalize_icelake(
606
606
 
607
607
  // Apply compensation: result = biased − 8×(Σa + Σb) − 64×depth_padded
608
608
  __m128i a_sum_broadcast_i32x4 = _mm_set1_epi32(a_sum);
609
- __m128i ab_sums_i32x4 = _mm_add_epi32(a_sum_broadcast_i32x4, b_sums.xmm);
609
+ __m128i ab_sums_i32x4 = _mm_add_epi32(a_sum_broadcast_i32x4, b_sums_vec->xmm);
610
610
  __m128i correction_i32x4 = _mm_slli_epi32(ab_sums_i32x4, 3); // × 8
611
611
  __m128i offset_i32x4 = _mm_set1_epi32((nk_i32_t)(-64LL * (nk_i64_t)depth_nibbles));
612
- result->xmm = _mm_add_epi32(_mm_sub_epi32(biased_i32x4, correction_i32x4), offset_i32x4);
612
+ result_vec->xmm = _mm_add_epi32(_mm_sub_epi32(biased_i32x4, correction_i32x4), offset_i32x4);
613
613
  }
614
614
 
615
615
  typedef struct nk_dot_u4x128_state_icelake_t {
@@ -19,7 +19,7 @@
19
19
  * @section dot_loongsonasx_stateful Stateful Streaming Logic
20
20
  *
21
21
  * - nk_dot_f64x4 state with Dot2 stable dot-products,
22
- * - nk_dot_f32x4 state with double-precision numerics,
22
+ * - nk_dot_f32x8 state with double-precision numerics,
23
23
  * - nk_dot_through_i32 state for 8-bit signed and unsigned integer inputs.
24
24
  */
25
25
  #ifndef NK_DOT_LOONGSONASX_H
@@ -348,7 +348,7 @@ NK_INTERNAL void nk_dot_f32x8_finalize_loongsonasx(
348
348
 
349
349
  /**
350
350
  * @brief Internal helper state for dot-products of integer types, where 32-bit accumulation is enough.
351
- * @sa nk_dot_i8x16_state_loongsonasx_t, nk_dot_u8x16_state_loongsonasx_t
351
+ * @sa nk_dot_i8x32_state_loongsonasx_t, nk_dot_u8x32_state_loongsonasx_t
352
352
  */
353
353
  typedef struct nk_dot_through_i32_state_loongsonasx_t_ {
354
354
  __m256i sum_i32x8;
@@ -356,7 +356,7 @@ typedef struct nk_dot_through_i32_state_loongsonasx_t_ {
356
356
 
357
357
  /**
358
358
  * @brief Initializes 32-bit accumulators for integer dot-products.
359
- * @sa nk_dot_i8x16_update_loongsonasx, nk_dot_u8x16_update_loongsonasx
359
+ * @sa nk_dot_i8x32_update_loongsonasx, nk_dot_u8x32_update_loongsonasx
360
360
  */
361
361
  NK_INTERNAL void nk_dot_through_i32_init_loongsonasx_(nk_dot_through_i32_state_loongsonasx_t_ *state) {
362
362
  state->sum_i32x8 = __lasx_xvreplgr2vr_w(0);
@@ -364,7 +364,7 @@ NK_INTERNAL void nk_dot_through_i32_init_loongsonasx_(nk_dot_through_i32_state_l
364
364
 
365
365
  /**
366
366
  * @brief Finalizes 4x integer dot-products placing them into 4x consecutive 32-bit slots.
367
- * @sa nk_dot_i8x16_update_loongsonasx, nk_dot_u8x16_update_loongsonasx
367
+ * @sa nk_dot_i8x32_update_loongsonasx, nk_dot_u8x32_update_loongsonasx
368
368
  */
369
369
  NK_INTERNAL void nk_dot_through_i32_finalize_loongsonasx_( //
370
370
  nk_dot_through_i32_state_loongsonasx_t_ const *state_a, nk_dot_through_i32_state_loongsonasx_t_ const *state_b, //
@@ -474,7 +474,7 @@ NK_INTERNAL void nk_dot_through_f32_init_loongsonasx_(nk_dot_through_f32_state_l
474
474
 
475
475
  /**
476
476
  * @brief Fuses 32-bit multiplication and accumulation for pre-converted f32 vectors.
477
- * @sa nk_dot_bf16x8_update_loongsonasx
477
+ * @sa nk_dot_bf16x16_update_loongsonasx
478
478
  */
479
479
  NK_INTERNAL void nk_dot_through_f32_update_loongsonasx_(nk_dot_through_f32_state_loongsonasx_t_ *state, nk_b256_vec_t a,
480
480
  nk_b256_vec_t b, nk_size_t depth_offset,
@@ -486,7 +486,7 @@ NK_INTERNAL void nk_dot_through_f32_update_loongsonasx_(nk_dot_through_f32_state
486
486
 
487
487
  /**
488
488
  * @brief Finalizes 4x low-precision dot-products placing them into 4x consecutive 32-bit slots.
489
- * @sa nk_dot_bf16x8_finalize_loongsonasx
489
+ * @sa nk_dot_bf16x16_finalize_loongsonasx
490
490
  *
491
491
  * Computes 4x horizontal reductions, each involving 8x floats, using LASX interleave instructions.
492
492
  */
@@ -89,7 +89,8 @@
89
89
  #if NK_TARGET_ARM64_
90
90
  #if NK_TARGET_NEON
91
91
 
92
- #include "numkong/cast/neon.h" // `nk_e4m3x8_to_f16x8_neon_`
92
+ #include "numkong/cast/neon.h" // `nk_e4m3x8_to_f16x8_neon_`
93
+ #include "numkong/dot/serial.h" // `nk_dot_f16c_serial`, `nk_vdot_f16c_serial`
93
94
 
94
95
  #if defined(__cplusplus)
95
96
  extern "C" {
@@ -63,6 +63,7 @@
63
63
  #include "numkong/types.h"
64
64
  #include "numkong/cast/serial.h" // `nk_partial_load_b8x8_serial_`
65
65
  #include "numkong/cast/neon.h" // `nk_e4m3x8_to_bf16x8_neon_`
66
+ #include "numkong/dot/serial.h" // `nk_dot_bf16c_serial`, `nk_vdot_bf16c_serial`
66
67
 
67
68
  #if defined(__cplusplus)
68
69
  extern "C" {
@@ -65,6 +65,7 @@
65
65
  #include "numkong/types.h"
66
66
  #include "numkong/cast/serial.h" // `nk_partial_load_b8x8_serial_`
67
67
  #include "numkong/cast/neon.h" // `nk_e4m3x8_to_f16x8_neon_`
68
+ #include "numkong/dot/serial.h" // `nk_dot_f16c_serial`, `nk_vdot_f16c_serial`
68
69
 
69
70
  #if defined(__cplusplus)
70
71
  extern "C" {
@@ -100,6 +100,7 @@
100
100
  #if NK_TARGET_NEONSDOT
101
101
 
102
102
  #include "numkong/types.h"
103
+ #include "numkong/cast/serial.h" // `nk_partial_load_b8x16_serial_`
103
104
 
104
105
  #if defined(__cplusplus)
105
106
  extern "C" {
@@ -599,7 +599,7 @@ NK_INTERNAL void nk_dot_i8x16_finalize_powervsx(
599
599
  nk_dot_i8x16_state_powervsx_t const *state_a, nk_dot_i8x16_state_powervsx_t const *state_b, //
600
600
  nk_dot_i8x16_state_powervsx_t const *state_c, nk_dot_i8x16_state_powervsx_t const *state_d, //
601
601
  nk_size_t total_dimensions, //
602
- nk_i32_t a_sum, nk_b128_vec_t b_sums, nk_b128_vec_t *result) {
602
+ nk_i32_t a_sum, nk_b128_vec_t const *b_sums_vec, nk_b128_vec_t *result_vec) {
603
603
  nk_unused_(total_dimensions);
604
604
  nk_unused_(a_sum);
605
605
 
@@ -624,8 +624,8 @@ NK_INTERNAL void nk_dot_i8x16_finalize_powervsx(
624
624
  // Correction: VMSUMMBM(b, a⊕0x80) = Σ(b_i·(a_i+128)) = a·b + 128·Σb
625
625
  // So a·b = biased − 128·Σb. B column sums are precomputed during packing.
626
626
  nk_vu32x4_t shift_u32x4 = vec_splats((nk_u32_t)7);
627
- nk_vi32x4_t correction_i32x4 = (nk_vi32x4_t)vec_sl((nk_vu32x4_t)b_sums.vi32x4, shift_u32x4);
628
- result->vi32x4 = vec_sub(biased_i32x4, correction_i32x4);
627
+ nk_vi32x4_t correction_i32x4 = (nk_vi32x4_t)vec_sl((nk_vu32x4_t)b_sums_vec->vi32x4, shift_u32x4);
628
+ result_vec->vi32x4 = vec_sub(biased_i32x4, correction_i32x4);
629
629
  }
630
630
 
631
631
  /** @brief Running state for i8 column sum precomputation on Power VSX. */
@@ -273,6 +273,12 @@ typedef struct nk_dot_f64x2_state_serial_t {
273
273
  nk_f64_t compensations[2];
274
274
  } nk_dot_f64x2_state_serial_t;
275
275
 
276
+ #if defined(__clang__)
277
+ #pragma clang attribute pop
278
+ #elif defined(__GNUC__)
279
+ #pragma GCC pop_options
280
+ #endif
281
+
276
282
  NK_INTERNAL void nk_dot_f64x2_init_serial(nk_dot_f64x2_state_serial_t *state) {
277
283
  state->sums[0] = 0, state->sums[1] = 0;
278
284
  state->compensations[0] = 0, state->compensations[1] = 0;
@@ -808,6 +814,13 @@ NK_INTERNAL void nk_dot_i4x16_finalize_serial(nk_dot_i4x16_state_serial_t const
808
814
 
809
815
  #pragma region Binary
810
816
 
817
+ #if defined(__clang__)
818
+ #pragma clang attribute push(__attribute__((noinline)), apply_to = function)
819
+ #elif defined(__GNUC__)
820
+ #pragma GCC push_options
821
+ #pragma GCC optimize("no-tree-vectorize", "no-tree-slp-vectorize", "no-ipa-cp-clone", "no-inline")
822
+ #endif
823
+
811
824
  NK_PUBLIC void nk_dot_u1_serial(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n_bits, nk_u32_t *result) {
812
825
  nk_u32_t dot = 0;
813
826
  nk_size_t bytes = nk_size_divide_round_up_(n_bits, NK_BITS_PER_BYTE);
@@ -819,6 +832,12 @@ typedef struct nk_dot_u1x128_state_serial_t {
819
832
  nk_u32_t dot_count;
820
833
  } nk_dot_u1x128_state_serial_t;
821
834
 
835
+ #if defined(__clang__)
836
+ #pragma clang attribute pop
837
+ #elif defined(__GNUC__)
838
+ #pragma GCC pop_options
839
+ #endif
840
+
822
841
  NK_INTERNAL void nk_dot_u1x128_init_serial(nk_dot_u1x128_state_serial_t *state) { state->dot_count = 0; }
823
842
 
824
843
  NK_INTERNAL void nk_dot_u1x128_update_serial(nk_dot_u1x128_state_serial_t *state, nk_b128_vec_t a, nk_b128_vec_t b,
@@ -876,12 +895,6 @@ NK_INTERNAL nk_i32_t nk_sum_i4x32_finalize_serial(nk_sum_i4x32_state_serial_t co
876
895
 
877
896
  #pragma endregion Stateful Element Sum Helpers
878
897
 
879
- #if defined(__clang__)
880
- #pragma clang attribute pop
881
- #elif defined(__GNUC__)
882
- #pragma GCC pop_options
883
- #endif
884
-
885
898
  #if defined(__cplusplus)
886
899
  } // extern "C"
887
900
  #endif
@@ -145,8 +145,8 @@ NK_INTERNAL void nk_dot_through_f32_init_skylake_(nk_dot_through_f32_state_skyla
145
145
 
146
146
  /**
147
147
  * @brief Fuses 32-bit multiplication and accumulation for low-precision dot-products.
148
- * @sa nk_dot_f16x16_udpate_skylake, nk_dot_bf16x16_udpate_skylake
149
- * @sa nk_dot_e4m3x16_udpate_skylake, nk_dot_e5m2x16_udpate_skylake
148
+ * @sa nk_dot_f16x16_update_skylake, nk_dot_bf16x16_update_skylake
149
+ * @sa nk_dot_e4m3x16_update_skylake, nk_dot_e5m2x16_update_skylake
150
150
  */
151
151
  NK_INTERNAL void nk_dot_through_f32_update_skylake_(nk_dot_through_f32_state_skylake_t_ *state, nk_b512_vec_t a,
152
152
  nk_b512_vec_t b, nk_size_t depth_offset,
@@ -188,8 +188,8 @@ NK_INTERNAL void nk_dot_e5m2x64_update_skylake_(nk_dot_through_f32_state_skylake
188
188
 
189
189
  /**
190
190
  * @brief Finalizes 4x low-precision dot-products placing them into 4x consecutive 32-bit slots.
191
- * @sa nk_dot_f16x16_udpate_skylake, nk_dot_bf16x16_udpate_skylake
192
- * @sa nk_dot_e4m3x16_udpate_skylake, nk_dot_e5m2x16_udpate_skylake
191
+ * @sa nk_dot_f16x16_update_skylake, nk_dot_bf16x16_update_skylake
192
+ * @sa nk_dot_e4m3x16_update_skylake, nk_dot_e5m2x16_update_skylake
193
193
  *
194
194
  * The goal of this kernel is simple - compute 4x horizontal reductions, each involing 16x floats.
195
195
  * The lack of vectorized horizontal instruction implies many consecutive shuffles producing a tree-like
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @brief SIMD-accelerated Dot Products for SVE FP16.
3
- * @file include/numkong/dot/sve.h
3
+ * @file include/numkong/dot/svehalf.h
4
4
  * @author Ash Vardanian
5
5
  * @date December 27, 2025
6
6
  *
@@ -691,21 +691,22 @@ NK_INTERNAL void nk_dot_u8x16_update_v128relaxed(nk_dot_u8x16_state_v128relaxed_
691
691
  NK_INTERNAL void nk_dot_u8x16_finalize_v128relaxed( //
692
692
  nk_dot_u8x16_state_v128relaxed_t const *state_a, nk_dot_u8x16_state_v128relaxed_t const *state_b, //
693
693
  nk_dot_u8x16_state_v128relaxed_t const *state_c, nk_dot_u8x16_state_v128relaxed_t const *state_d, //
694
- nk_size_t total_dimensions, nk_u32_t a_sum, nk_b128_vec_t b_sums, nk_b128_vec_t *result) {
694
+ nk_size_t total_dimensions, nk_u32_t a_sum, nk_b128_vec_t const *b_sums_vec, nk_b128_vec_t *result_vec) {
695
+ nk_unused_(total_dimensions);
695
696
  nk_unused_(a_sum);
696
697
  // Σ a·b = reduce(lo) + 128·reduce(hi) + 128·Σb
697
- result->u32s[0] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_a->product_low_i32x4) +
698
- 128 * nk_reduce_add_i32x4_v128relaxed_(state_a->product_high_i32x4) +
699
- 128 * (nk_i32_t)b_sums.u32s[0]);
700
- result->u32s[1] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_b->product_low_i32x4) +
701
- 128 * nk_reduce_add_i32x4_v128relaxed_(state_b->product_high_i32x4) +
702
- 128 * (nk_i32_t)b_sums.u32s[1]);
703
- result->u32s[2] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_c->product_low_i32x4) +
704
- 128 * nk_reduce_add_i32x4_v128relaxed_(state_c->product_high_i32x4) +
705
- 128 * (nk_i32_t)b_sums.u32s[2]);
706
- result->u32s[3] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_d->product_low_i32x4) +
707
- 128 * nk_reduce_add_i32x4_v128relaxed_(state_d->product_high_i32x4) +
708
- 128 * (nk_i32_t)b_sums.u32s[3]);
698
+ result_vec->u32s[0] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_a->product_low_i32x4) +
699
+ 128 * nk_reduce_add_i32x4_v128relaxed_(state_a->product_high_i32x4) +
700
+ 128 * (nk_i32_t)b_sums_vec->u32s[0]);
701
+ result_vec->u32s[1] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_b->product_low_i32x4) +
702
+ 128 * nk_reduce_add_i32x4_v128relaxed_(state_b->product_high_i32x4) +
703
+ 128 * (nk_i32_t)b_sums_vec->u32s[1]);
704
+ result_vec->u32s[2] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_c->product_low_i32x4) +
705
+ 128 * nk_reduce_add_i32x4_v128relaxed_(state_c->product_high_i32x4) +
706
+ 128 * (nk_i32_t)b_sums_vec->u32s[2]);
707
+ result_vec->u32s[3] = (nk_u32_t)(nk_reduce_add_i32x4_v128relaxed_(state_d->product_low_i32x4) +
708
+ 128 * nk_reduce_add_i32x4_v128relaxed_(state_d->product_high_i32x4) +
709
+ 128 * (nk_i32_t)b_sums_vec->u32s[3]);
709
710
  }
710
711
 
711
712
  typedef struct nk_sum_u8x16_state_v128relaxed_t {
@@ -1099,18 +1100,18 @@ NK_INTERNAL void nk_dot_i4x32_finalize_v128relaxed(
1099
1100
  nk_dot_i4x32_state_v128relaxed_t const *state_c, nk_dot_i4x32_state_v128relaxed_t const *state_d, //
1100
1101
  nk_size_t total_dimensions, //
1101
1102
  nk_i32_t a_sum, /* Row sum of A (signed sum of i4 values) */ //
1102
- nk_b128_vec_t b_sums, /* 4 × i32 column sums of B */ //
1103
- nk_b128_vec_t *result) {
1103
+ nk_b128_vec_t const *b_sums_vec, /* 4 × i32 column sums of B */ //
1104
+ nk_b128_vec_t *result_vec) {
1104
1105
  // Match x86 compensated i4 finalizers: result = biased_dot - 8*(a_sum + b_sum) - 64*depth_padded
1105
1106
  nk_i64_t depth_padded = (nk_i64_t)nk_size_round_up_to_multiple_(total_dimensions, 32);
1106
- result->i32s[0] = nk_reduce_add_i32x4_v128relaxed_(state_a->biased_product_sum_i32x4) -
1107
- 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums.i32s[0]) - 64 * depth_padded;
1108
- result->i32s[1] = nk_reduce_add_i32x4_v128relaxed_(state_b->biased_product_sum_i32x4) -
1109
- 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums.i32s[1]) - 64 * depth_padded;
1110
- result->i32s[2] = nk_reduce_add_i32x4_v128relaxed_(state_c->biased_product_sum_i32x4) -
1111
- 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums.i32s[2]) - 64 * depth_padded;
1112
- result->i32s[3] = nk_reduce_add_i32x4_v128relaxed_(state_d->biased_product_sum_i32x4) -
1113
- 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums.i32s[3]) - 64 * depth_padded;
1107
+ result_vec->i32s[0] = nk_reduce_add_i32x4_v128relaxed_(state_a->biased_product_sum_i32x4) -
1108
+ 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums_vec->i32s[0]) - 64 * depth_padded;
1109
+ result_vec->i32s[1] = nk_reduce_add_i32x4_v128relaxed_(state_b->biased_product_sum_i32x4) -
1110
+ 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums_vec->i32s[1]) - 64 * depth_padded;
1111
+ result_vec->i32s[2] = nk_reduce_add_i32x4_v128relaxed_(state_c->biased_product_sum_i32x4) -
1112
+ 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums_vec->i32s[2]) - 64 * depth_padded;
1113
+ result_vec->i32s[3] = nk_reduce_add_i32x4_v128relaxed_(state_d->biased_product_sum_i32x4) -
1114
+ 8 * ((nk_i64_t)a_sum + (nk_i64_t)b_sums_vec->i32s[3]) - 64 * depth_padded;
1114
1115
  }
1115
1116
 
1116
1117
  typedef struct nk_sum_i4x32_state_v128relaxed_t {