usearch 2.21.4 → 2.25.1

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 (604) hide show
  1. package/README.md +65 -69
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +8 -8
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +124 -1
  7. package/c/usearch.h +24 -3
  8. package/cpp/CMakeLists.txt +4 -0
  9. package/cpp/README.md +5 -5
  10. package/cpp/bench.cpp +97 -116
  11. package/cpp/test.cpp +117 -20
  12. package/include/usearch/index.hpp +224 -48
  13. package/include/usearch/index_dense.hpp +105 -40
  14. package/include/usearch/index_plugins.hpp +1387 -204
  15. package/javascript/README.md +1 -1
  16. package/javascript/dist/cjs/usearch.d.ts +8 -3
  17. package/javascript/dist/cjs/usearch.js +12 -4
  18. package/javascript/dist/esm/usearch.d.ts +8 -3
  19. package/javascript/dist/esm/usearch.js +12 -4
  20. package/javascript/lib.cpp +17 -0
  21. package/javascript/usearch.test.js +117 -94
  22. package/javascript/usearch.ts +14 -6
  23. package/numkong/.clang-tidy +30 -0
  24. package/{simsimd → numkong}/.cmake-format.py +18 -0
  25. package/numkong/.editorconfig +12 -0
  26. package/numkong/.git-blame-ignore-revs +123 -0
  27. package/numkong/.mailmap +15 -0
  28. package/numkong/.spi.yml +11 -0
  29. package/numkong/.swift-format +14 -0
  30. package/numkong/CITATION.cff +81 -0
  31. package/numkong/CONTRIBUTING.md +500 -0
  32. package/numkong/Cargo.toml +54 -0
  33. package/numkong/MANIFEST.in +8 -0
  34. package/numkong/Package.swift +84 -0
  35. package/numkong/README.md +569 -0
  36. package/numkong/bench/README.md +217 -0
  37. package/numkong/bench/bench-browser.html +323 -0
  38. package/numkong/bench/bench.cpp +344 -0
  39. package/numkong/bench/bench.hpp +816 -0
  40. package/numkong/bench/bench.js +148 -0
  41. package/numkong/bench/bench.mjs +616 -0
  42. package/numkong/bench/bench_attention.cpp +113 -0
  43. package/numkong/bench/bench_cast.cpp +264 -0
  44. package/numkong/bench/bench_cross_amx.cpp +62 -0
  45. package/numkong/bench/bench_cross_arm.cpp +245 -0
  46. package/numkong/bench/bench_cross_blas.cpp +309 -0
  47. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  48. package/numkong/bench/bench_cross_power.cpp +84 -0
  49. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  50. package/numkong/bench/bench_cross_serial.cpp +151 -0
  51. package/numkong/bench/bench_cross_sme.cpp +163 -0
  52. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  53. package/numkong/bench/bench_cross_x86.cpp +455 -0
  54. package/numkong/bench/bench_curved.cpp +210 -0
  55. package/numkong/bench/bench_dot.cpp +315 -0
  56. package/numkong/bench/bench_each.cpp +503 -0
  57. package/numkong/bench/bench_geospatial.cpp +112 -0
  58. package/numkong/bench/bench_maxsim.cpp +154 -0
  59. package/numkong/bench/bench_mesh.cpp +148 -0
  60. package/numkong/bench/bench_probability.cpp +60 -0
  61. package/numkong/bench/bench_reduce.cpp +371 -0
  62. package/numkong/bench/bench_set.cpp +73 -0
  63. package/numkong/bench/bench_sparse.cpp +198 -0
  64. package/numkong/bench/bench_spatial.cpp +347 -0
  65. package/numkong/bench/bench_trigonometry.cpp +137 -0
  66. package/numkong/bench/swift/Bench.swift +506 -0
  67. package/numkong/binding.gyp +169 -0
  68. package/numkong/build.rs +484 -0
  69. package/numkong/c/dispatch.h +512 -0
  70. package/numkong/c/dispatch_bf16.c +447 -0
  71. package/numkong/c/dispatch_bf16c.c +52 -0
  72. package/numkong/c/dispatch_e2m3.c +296 -0
  73. package/numkong/c/dispatch_e3m2.c +284 -0
  74. package/numkong/c/dispatch_e4m3.c +318 -0
  75. package/numkong/c/dispatch_e5m2.c +316 -0
  76. package/numkong/c/dispatch_f16.c +452 -0
  77. package/numkong/c/dispatch_f16c.c +58 -0
  78. package/numkong/c/dispatch_f32.c +434 -0
  79. package/numkong/c/dispatch_f32c.c +99 -0
  80. package/numkong/c/dispatch_f64.c +348 -0
  81. package/numkong/c/dispatch_f64c.c +98 -0
  82. package/numkong/c/dispatch_i16.c +96 -0
  83. package/numkong/c/dispatch_i32.c +89 -0
  84. package/numkong/c/dispatch_i4.c +153 -0
  85. package/numkong/c/dispatch_i64.c +86 -0
  86. package/numkong/c/dispatch_i8.c +348 -0
  87. package/numkong/c/dispatch_other.c +348 -0
  88. package/numkong/c/dispatch_u1.c +193 -0
  89. package/numkong/c/dispatch_u16.c +124 -0
  90. package/numkong/c/dispatch_u32.c +118 -0
  91. package/numkong/c/dispatch_u4.c +153 -0
  92. package/numkong/c/dispatch_u64.c +102 -0
  93. package/numkong/c/dispatch_u8.c +364 -0
  94. package/numkong/c/numkong.c +940 -0
  95. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  96. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  97. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_math_lib.cmake +46 -0
  99. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  100. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  101. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  102. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  103. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  104. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  105. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  106. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  107. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  108. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  109. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  110. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  111. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  112. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  113. package/numkong/include/README.md +643 -0
  114. package/numkong/include/module.modulemap +129 -0
  115. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  116. package/numkong/include/numkong/attention/sme.h +2075 -0
  117. package/numkong/include/numkong/attention.h +49 -0
  118. package/numkong/include/numkong/capabilities.h +930 -0
  119. package/numkong/include/numkong/cast/README.md +262 -0
  120. package/numkong/include/numkong/cast/diamond.h +64 -0
  121. package/numkong/include/numkong/cast/haswell.h +823 -0
  122. package/numkong/include/numkong/cast/icelake.h +475 -0
  123. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  124. package/numkong/include/numkong/cast/neon.h +1174 -0
  125. package/numkong/include/numkong/cast/powervsx.h +449 -0
  126. package/numkong/include/numkong/cast/rvv.h +970 -0
  127. package/numkong/include/numkong/cast/sapphire.h +262 -0
  128. package/numkong/include/numkong/cast/serial.h +2336 -0
  129. package/numkong/include/numkong/cast/skylake.h +915 -0
  130. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  131. package/numkong/include/numkong/cast.h +254 -0
  132. package/numkong/include/numkong/cast.hpp +44 -0
  133. package/numkong/include/numkong/curved/README.md +223 -0
  134. package/numkong/include/numkong/curved/genoa.h +182 -0
  135. package/numkong/include/numkong/curved/haswell.h +276 -0
  136. package/numkong/include/numkong/curved/neon.h +329 -0
  137. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  138. package/numkong/include/numkong/curved/rvv.h +305 -0
  139. package/numkong/include/numkong/curved/serial.h +207 -0
  140. package/numkong/include/numkong/curved/skylake.h +457 -0
  141. package/numkong/include/numkong/curved/smef64.h +530 -0
  142. package/numkong/include/numkong/curved.h +513 -0
  143. package/numkong/include/numkong/curved.hpp +144 -0
  144. package/numkong/include/numkong/dot/README.md +442 -0
  145. package/numkong/include/numkong/dot/alder.h +563 -0
  146. package/numkong/include/numkong/dot/diamond.h +158 -0
  147. package/numkong/include/numkong/dot/genoa.h +289 -0
  148. package/numkong/include/numkong/dot/haswell.h +1723 -0
  149. package/numkong/include/numkong/dot/icelake.h +997 -0
  150. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  151. package/numkong/include/numkong/dot/neon.h +869 -0
  152. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  153. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  154. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  155. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  156. package/numkong/include/numkong/dot/powervsx.h +752 -0
  157. package/numkong/include/numkong/dot/rvv.h +722 -0
  158. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  159. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  160. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  161. package/numkong/include/numkong/dot/sapphire.h +141 -0
  162. package/numkong/include/numkong/dot/serial.h +874 -0
  163. package/numkong/include/numkong/dot/sierra.h +405 -0
  164. package/numkong/include/numkong/dot/skylake.h +1116 -0
  165. package/numkong/include/numkong/dot/sve.h +420 -0
  166. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  167. package/numkong/include/numkong/dot/svehalf.h +168 -0
  168. package/numkong/include/numkong/dot/svesdot.h +90 -0
  169. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  170. package/numkong/include/numkong/dot.h +1136 -0
  171. package/numkong/include/numkong/dot.hpp +94 -0
  172. package/numkong/include/numkong/dots/README.md +496 -0
  173. package/numkong/include/numkong/dots/alder.h +117 -0
  174. package/numkong/include/numkong/dots/diamond.h +86 -0
  175. package/numkong/include/numkong/dots/genoa.h +100 -0
  176. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  177. package/numkong/include/numkong/dots/haswell.h +310 -0
  178. package/numkong/include/numkong/dots/icelake.h +180 -0
  179. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  180. package/numkong/include/numkong/dots/neon.h +123 -0
  181. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  182. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  183. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  184. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  185. package/numkong/include/numkong/dots/powervsx.h +194 -0
  186. package/numkong/include/numkong/dots/rvv.h +2593 -0
  187. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  188. package/numkong/include/numkong/dots/serial.h +2867 -0
  189. package/numkong/include/numkong/dots/sierra.h +100 -0
  190. package/numkong/include/numkong/dots/skylake.h +207 -0
  191. package/numkong/include/numkong/dots/sme.h +5041 -0
  192. package/numkong/include/numkong/dots/smebi32.h +477 -0
  193. package/numkong/include/numkong/dots/smef64.h +1328 -0
  194. package/numkong/include/numkong/dots/smehalf.h +47 -0
  195. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  196. package/numkong/include/numkong/dots.h +3110 -0
  197. package/numkong/include/numkong/dots.hpp +641 -0
  198. package/numkong/include/numkong/each/README.md +465 -0
  199. package/numkong/include/numkong/each/haswell.h +1658 -0
  200. package/numkong/include/numkong/each/icelake.h +272 -0
  201. package/numkong/include/numkong/each/neon.h +1138 -0
  202. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  203. package/numkong/include/numkong/each/neonhalf.h +318 -0
  204. package/numkong/include/numkong/each/rvv.h +1121 -0
  205. package/numkong/include/numkong/each/sapphire.h +343 -0
  206. package/numkong/include/numkong/each/serial.h +282 -0
  207. package/numkong/include/numkong/each/skylake.h +1562 -0
  208. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  209. package/numkong/include/numkong/each.h +2232 -0
  210. package/numkong/include/numkong/each.hpp +434 -0
  211. package/numkong/include/numkong/geospatial/README.md +147 -0
  212. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  213. package/numkong/include/numkong/geospatial/neon.h +615 -0
  214. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  215. package/numkong/include/numkong/geospatial/serial.h +309 -0
  216. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  217. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  218. package/numkong/include/numkong/geospatial.h +453 -0
  219. package/numkong/include/numkong/geospatial.hpp +235 -0
  220. package/numkong/include/numkong/matrix.hpp +336 -0
  221. package/numkong/include/numkong/maxsim/README.md +187 -0
  222. package/numkong/include/numkong/maxsim/alder.h +511 -0
  223. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  224. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  225. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  226. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  227. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  228. package/numkong/include/numkong/maxsim/serial.h +490 -0
  229. package/numkong/include/numkong/maxsim/sme.h +993 -0
  230. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  231. package/numkong/include/numkong/maxsim.h +571 -0
  232. package/numkong/include/numkong/maxsim.hpp +133 -0
  233. package/numkong/include/numkong/mesh/README.md +219 -0
  234. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  235. package/numkong/include/numkong/mesh/neon.h +1821 -0
  236. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  237. package/numkong/include/numkong/mesh/rvv.h +936 -0
  238. package/numkong/include/numkong/mesh/serial.h +721 -0
  239. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  240. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  241. package/numkong/include/numkong/mesh.h +666 -0
  242. package/numkong/include/numkong/mesh.hpp +701 -0
  243. package/numkong/include/numkong/numkong.h +78 -0
  244. package/numkong/include/numkong/numkong.hpp +58 -0
  245. package/numkong/include/numkong/probability/README.md +177 -0
  246. package/numkong/include/numkong/probability/haswell.h +267 -0
  247. package/numkong/include/numkong/probability/neon.h +255 -0
  248. package/numkong/include/numkong/probability/rvv.h +414 -0
  249. package/numkong/include/numkong/probability/serial.h +181 -0
  250. package/numkong/include/numkong/probability/skylake.h +324 -0
  251. package/numkong/include/numkong/probability.h +380 -0
  252. package/numkong/include/numkong/probability.hpp +120 -0
  253. package/numkong/include/numkong/random.h +50 -0
  254. package/numkong/include/numkong/random.hpp +285 -0
  255. package/numkong/include/numkong/reduce/README.md +552 -0
  256. package/numkong/include/numkong/reduce/alder.h +636 -0
  257. package/numkong/include/numkong/reduce/genoa.h +201 -0
  258. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  259. package/numkong/include/numkong/reduce/icelake.h +549 -0
  260. package/numkong/include/numkong/reduce/neon.h +3980 -0
  261. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  262. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  263. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  264. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  265. package/numkong/include/numkong/reduce/serial.h +753 -0
  266. package/numkong/include/numkong/reduce/sierra.h +338 -0
  267. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  268. package/numkong/include/numkong/reduce/sve.h +52 -0
  269. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  270. package/numkong/include/numkong/reduce.h +1582 -0
  271. package/numkong/include/numkong/reduce.hpp +778 -0
  272. package/numkong/include/numkong/scalar/README.md +89 -0
  273. package/numkong/include/numkong/scalar/haswell.h +122 -0
  274. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  275. package/numkong/include/numkong/scalar/neon.h +122 -0
  276. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  277. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  278. package/numkong/include/numkong/scalar/rvv.h +211 -0
  279. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  280. package/numkong/include/numkong/scalar/serial.h +332 -0
  281. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  282. package/numkong/include/numkong/scalar.h +696 -0
  283. package/numkong/include/numkong/set/README.md +179 -0
  284. package/numkong/include/numkong/set/haswell.h +334 -0
  285. package/numkong/include/numkong/set/icelake.h +485 -0
  286. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  287. package/numkong/include/numkong/set/neon.h +363 -0
  288. package/numkong/include/numkong/set/powervsx.h +326 -0
  289. package/numkong/include/numkong/set/rvv.h +226 -0
  290. package/numkong/include/numkong/set/rvvbb.h +117 -0
  291. package/numkong/include/numkong/set/serial.h +174 -0
  292. package/numkong/include/numkong/set/sve.h +187 -0
  293. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  294. package/numkong/include/numkong/set.h +471 -0
  295. package/numkong/include/numkong/set.hpp +114 -0
  296. package/numkong/include/numkong/sets/README.md +149 -0
  297. package/numkong/include/numkong/sets/haswell.h +63 -0
  298. package/numkong/include/numkong/sets/icelake.h +66 -0
  299. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  300. package/numkong/include/numkong/sets/neon.h +61 -0
  301. package/numkong/include/numkong/sets/powervsx.h +65 -0
  302. package/numkong/include/numkong/sets/serial.h +43 -0
  303. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  304. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  305. package/numkong/include/numkong/sets.h +382 -0
  306. package/numkong/include/numkong/sparse/README.md +156 -0
  307. package/numkong/include/numkong/sparse/icelake.h +463 -0
  308. package/numkong/include/numkong/sparse/neon.h +288 -0
  309. package/numkong/include/numkong/sparse/serial.h +117 -0
  310. package/numkong/include/numkong/sparse/sve2.h +504 -0
  311. package/numkong/include/numkong/sparse/turin.h +322 -0
  312. package/numkong/include/numkong/sparse.h +363 -0
  313. package/numkong/include/numkong/sparse.hpp +113 -0
  314. package/numkong/include/numkong/spatial/README.md +439 -0
  315. package/numkong/include/numkong/spatial/alder.h +604 -0
  316. package/numkong/include/numkong/spatial/diamond.h +240 -0
  317. package/numkong/include/numkong/spatial/genoa.h +222 -0
  318. package/numkong/include/numkong/spatial/haswell.h +979 -0
  319. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  320. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  321. package/numkong/include/numkong/spatial/neon.h +846 -0
  322. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  323. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  324. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  325. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  326. package/numkong/include/numkong/spatial/rvv.h +991 -0
  327. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  328. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  329. package/numkong/include/numkong/spatial/serial.h +347 -0
  330. package/numkong/include/numkong/spatial/sierra.h +516 -0
  331. package/numkong/include/numkong/spatial/skylake.h +605 -0
  332. package/numkong/include/numkong/spatial/sve.h +246 -0
  333. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  334. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  335. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  336. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  337. package/numkong/include/numkong/spatial.h +1681 -0
  338. package/numkong/include/numkong/spatial.hpp +183 -0
  339. package/numkong/include/numkong/spatials/README.md +580 -0
  340. package/numkong/include/numkong/spatials/alder.h +94 -0
  341. package/numkong/include/numkong/spatials/diamond.h +82 -0
  342. package/numkong/include/numkong/spatials/genoa.h +94 -0
  343. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  344. package/numkong/include/numkong/spatials/haswell.h +219 -0
  345. package/numkong/include/numkong/spatials/icelake.h +113 -0
  346. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  347. package/numkong/include/numkong/spatials/neon.h +109 -0
  348. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  349. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  350. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  351. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  352. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  353. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  354. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  355. package/numkong/include/numkong/spatials/serial.h +248 -0
  356. package/numkong/include/numkong/spatials/sierra.h +96 -0
  357. package/numkong/include/numkong/spatials/skylake.h +184 -0
  358. package/numkong/include/numkong/spatials/sme.h +1927 -0
  359. package/numkong/include/numkong/spatials/smef64.h +483 -0
  360. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  361. package/numkong/include/numkong/spatials.h +3374 -0
  362. package/numkong/include/numkong/spatials.hpp +509 -0
  363. package/numkong/include/numkong/tensor.hpp +1981 -0
  364. package/numkong/include/numkong/trigonometry/README.md +184 -0
  365. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  366. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  367. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  368. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  369. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  370. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  371. package/numkong/include/numkong/trigonometry.h +467 -0
  372. package/numkong/include/numkong/trigonometry.hpp +166 -0
  373. package/numkong/include/numkong/types.h +1695 -0
  374. package/numkong/include/numkong/types.hpp +6027 -0
  375. package/numkong/include/numkong/vector.hpp +766 -0
  376. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  377. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  378. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  380. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  381. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  382. package/numkong/javascript/README.md +254 -0
  383. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  384. package/numkong/javascript/numkong-browser.ts +40 -0
  385. package/numkong/javascript/numkong-wasm.ts +750 -0
  386. package/numkong/javascript/numkong.c +712 -0
  387. package/numkong/javascript/numkong.ts +613 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  389. package/numkong/javascript/tsconfig-cjs.json +13 -0
  390. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  391. package/numkong/javascript/types.ts +784 -0
  392. package/numkong/numkong.gypi +104 -0
  393. package/numkong/package.json +108 -0
  394. package/numkong/probes/arm_neon.c +8 -0
  395. package/numkong/probes/arm_neon_bfdot.c +9 -0
  396. package/numkong/probes/arm_neon_fhm.c +9 -0
  397. package/numkong/probes/arm_neon_half.c +8 -0
  398. package/numkong/probes/arm_neon_sdot.c +9 -0
  399. package/numkong/probes/arm_neonfp8.c +9 -0
  400. package/numkong/probes/arm_sme.c +16 -0
  401. package/numkong/probes/arm_sme2.c +16 -0
  402. package/numkong/probes/arm_sme2p1.c +16 -0
  403. package/numkong/probes/arm_sme_bf16.c +16 -0
  404. package/numkong/probes/arm_sme_bi32.c +16 -0
  405. package/numkong/probes/arm_sme_f64.c +16 -0
  406. package/numkong/probes/arm_sme_fa64.c +14 -0
  407. package/numkong/probes/arm_sme_half.c +16 -0
  408. package/numkong/probes/arm_sme_lut2.c +15 -0
  409. package/numkong/probes/arm_sve.c +18 -0
  410. package/numkong/probes/arm_sve2.c +20 -0
  411. package/numkong/probes/arm_sve2p1.c +18 -0
  412. package/numkong/probes/arm_sve_bfdot.c +20 -0
  413. package/numkong/probes/arm_sve_half.c +18 -0
  414. package/numkong/probes/arm_sve_sdot.c +21 -0
  415. package/numkong/probes/loongarch_lasx.c +12 -0
  416. package/numkong/probes/power_vsx.c +12 -0
  417. package/numkong/probes/probe.js +127 -0
  418. package/numkong/probes/riscv_rvv.c +14 -0
  419. package/numkong/probes/riscv_rvv_bb.c +15 -0
  420. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  421. package/numkong/probes/riscv_rvv_half.c +14 -0
  422. package/numkong/probes/wasm_v128relaxed.c +11 -0
  423. package/numkong/probes/x86_alder.c +17 -0
  424. package/numkong/probes/x86_diamond.c +17 -0
  425. package/numkong/probes/x86_genoa.c +17 -0
  426. package/numkong/probes/x86_graniteamx.c +19 -0
  427. package/numkong/probes/x86_haswell.c +11 -0
  428. package/numkong/probes/x86_icelake.c +17 -0
  429. package/numkong/probes/x86_sapphire.c +16 -0
  430. package/numkong/probes/x86_sapphireamx.c +18 -0
  431. package/numkong/probes/x86_sierra.c +17 -0
  432. package/numkong/probes/x86_skylake.c +15 -0
  433. package/numkong/probes/x86_turin.c +17 -0
  434. package/numkong/rust/README.md +698 -0
  435. package/numkong/rust/capabilities.rs +96 -0
  436. package/numkong/rust/cast.rs +314 -0
  437. package/numkong/rust/curved.rs +391 -0
  438. package/numkong/rust/each.rs +2721 -0
  439. package/numkong/rust/geospatial.rs +343 -0
  440. package/numkong/rust/matrix.rs +5424 -0
  441. package/numkong/rust/maxsim.rs +540 -0
  442. package/numkong/rust/mesh.rs +837 -0
  443. package/numkong/rust/numkong.rs +409 -0
  444. package/numkong/rust/probability.rs +272 -0
  445. package/numkong/rust/reduce.rs +1249 -0
  446. package/numkong/rust/set.rs +194 -0
  447. package/numkong/rust/sparse.rs +513 -0
  448. package/numkong/rust/spatial.rs +1815 -0
  449. package/numkong/rust/tensor.rs +7565 -0
  450. package/numkong/rust/types.rs +3666 -0
  451. package/numkong/rust/vector.rs +1899 -0
  452. package/numkong/rustfmt.toml +2 -0
  453. package/numkong/swift/Matrix.swift +1388 -0
  454. package/numkong/swift/MaxSim.swift +151 -0
  455. package/numkong/swift/NumKong.swift +283 -0
  456. package/numkong/swift/Numerics.swift +329 -0
  457. package/numkong/swift/README.md +433 -0
  458. package/numkong/swift/Scalar.swift +741 -0
  459. package/numkong/swift/Tensor.swift +209 -0
  460. package/numkong/test/README.md +315 -0
  461. package/numkong/test/playwright.config.ts +16 -0
  462. package/numkong/test/swift/Test.swift +534 -0
  463. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  464. package/numkong/test/test-browser-bundle.html +188 -0
  465. package/numkong/test/test-browser-runner.mjs +43 -0
  466. package/numkong/test/test-browser.html +305 -0
  467. package/numkong/test/test-dtypes.mjs +453 -0
  468. package/numkong/test/test-wasm.mjs +267 -0
  469. package/numkong/test/test.cpp +442 -0
  470. package/numkong/test/test.hpp +580 -0
  471. package/numkong/test/test.mjs +363 -0
  472. package/numkong/test/test_base.py +1041 -0
  473. package/numkong/test/test_cast.cpp +242 -0
  474. package/numkong/test/test_cross.hpp +551 -0
  475. package/numkong/test/test_cross.py +467 -0
  476. package/numkong/test/test_cross_amx.cpp +50 -0
  477. package/numkong/test/test_cross_arm.cpp +225 -0
  478. package/numkong/test/test_cross_blas.cpp +354 -0
  479. package/numkong/test/test_cross_loongarch.cpp +90 -0
  480. package/numkong/test/test_cross_power.cpp +73 -0
  481. package/numkong/test/test_cross_rvv.cpp +109 -0
  482. package/numkong/test/test_cross_serial.cpp +181 -0
  483. package/numkong/test/test_cross_sme.cpp +148 -0
  484. package/numkong/test/test_cross_wasm.cpp +141 -0
  485. package/numkong/test/test_cross_x86.cpp +442 -0
  486. package/numkong/test/test_curved.cpp +182 -0
  487. package/numkong/test/test_curved.py +207 -0
  488. package/numkong/test/test_dot.cpp +353 -0
  489. package/numkong/test/test_dot.py +296 -0
  490. package/numkong/test/test_each.cpp +437 -0
  491. package/numkong/test/test_each.py +756 -0
  492. package/numkong/test/test_geospatial.cpp +155 -0
  493. package/numkong/test/test_geospatial.py +241 -0
  494. package/numkong/test/test_maxsim.cpp +138 -0
  495. package/numkong/test/test_maxsim.py +209 -0
  496. package/numkong/test/test_mesh.cpp +203 -0
  497. package/numkong/test/test_mesh.py +394 -0
  498. package/numkong/test/test_probability.cpp +136 -0
  499. package/numkong/test/test_probability.py +166 -0
  500. package/numkong/test/test_reduce.cpp +563 -0
  501. package/numkong/test/test_reduce.py +781 -0
  502. package/numkong/test/test_set.cpp +151 -0
  503. package/numkong/test/test_set.py +120 -0
  504. package/numkong/test/test_similarities.py +579 -0
  505. package/numkong/test/test_sparse.cpp +121 -0
  506. package/numkong/test/test_sparse.py +118 -0
  507. package/numkong/test/test_spatial.cpp +518 -0
  508. package/numkong/test/test_spatial.py +269 -0
  509. package/numkong/test/test_tensor.cpp +884 -0
  510. package/numkong/test/test_tensor.py +1417 -0
  511. package/numkong/test/test_trigonometry.cpp +156 -0
  512. package/numkong/test/test_trigonometry.py +180 -0
  513. package/package.json +7 -8
  514. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  515. package/prebuilds/linux-arm64/usearch.node +0 -0
  516. package/prebuilds/linux-x64/usearch.node +0 -0
  517. package/fp16/CMakeLists.txt +0 -176
  518. package/fp16/LICENSE +0 -11
  519. package/fp16/README.md +0 -20
  520. package/fp16/bench/alt-element.cc +0 -89
  521. package/fp16/bench/from-alt-array.cc +0 -175
  522. package/fp16/bench/from-ieee-array.cc +0 -399
  523. package/fp16/bench/ieee-element.cc +0 -272
  524. package/fp16/bench/to-alt-array.cc +0 -91
  525. package/fp16/bench/to-ieee-array.cc +0 -303
  526. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  527. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  528. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  529. package/fp16/configure.py +0 -65
  530. package/fp16/confu.yaml +0 -8
  531. package/fp16/include/fp16/__init__.py +0 -0
  532. package/fp16/include/fp16/avx.py +0 -50
  533. package/fp16/include/fp16/avx2.py +0 -53
  534. package/fp16/include/fp16/bitcasts.h +0 -92
  535. package/fp16/include/fp16/fp16.h +0 -451
  536. package/fp16/include/fp16/psimd.h +0 -131
  537. package/fp16/include/fp16.h +0 -11
  538. package/fp16/jni/Android.mk +0 -6
  539. package/fp16/jni/Application.mk +0 -4
  540. package/fp16/test/alt-from-fp32-value.cc +0 -498
  541. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  542. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  543. package/fp16/test/alt-to-fp32-value.cc +0 -348
  544. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  545. package/fp16/test/bitcasts.cc +0 -56
  546. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  547. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  548. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  549. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  550. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  551. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  552. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  553. package/fp16/test/peachpy/stubs.py +0 -38
  554. package/fp16/test/tables.cc +0 -530
  555. package/fp16/test/tables.h +0 -13
  556. package/fp16/third-party/THHalf.h +0 -92
  557. package/fp16/third-party/eigen-half.h +0 -170
  558. package/fp16/third-party/float16-compressor.h +0 -80
  559. package/fp16/third-party/half.hpp +0 -2916
  560. package/fp16/third-party/npy-halffloat.h +0 -328
  561. package/simsimd/.git-blame-ignore-revs +0 -2
  562. package/simsimd/CONTRIBUTING.md +0 -321
  563. package/simsimd/Cargo.toml +0 -49
  564. package/simsimd/MANIFEST.in +0 -4
  565. package/simsimd/Package.swift +0 -28
  566. package/simsimd/README.md +0 -1493
  567. package/simsimd/binding.gyp +0 -35
  568. package/simsimd/build.rs +0 -70
  569. package/simsimd/c/lib.c +0 -374
  570. package/simsimd/include/module.modulemap +0 -4
  571. package/simsimd/include/simsimd/binary.h +0 -486
  572. package/simsimd/include/simsimd/curved.h +0 -1541
  573. package/simsimd/include/simsimd/dot.h +0 -1853
  574. package/simsimd/include/simsimd/elementwise.h +0 -2465
  575. package/simsimd/include/simsimd/geospatial.h +0 -43
  576. package/simsimd/include/simsimd/mesh.h +0 -69
  577. package/simsimd/include/simsimd/probability.h +0 -606
  578. package/simsimd/include/simsimd/simsimd.h +0 -2567
  579. package/simsimd/include/simsimd/sparse.h +0 -1384
  580. package/simsimd/include/simsimd/spatial.h +0 -2335
  581. package/simsimd/include/simsimd/types.h +0 -666
  582. package/simsimd/javascript/fallback.ts +0 -233
  583. package/simsimd/javascript/lib.c +0 -125
  584. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  585. package/simsimd/javascript/simsimd.ts +0 -179
  586. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  587. package/simsimd/package-lock.json +0 -1761
  588. package/simsimd/package.json +0 -61
  589. package/simsimd/rust/lib.rs +0 -1821
  590. package/simsimd/scripts/bench.cxx +0 -1170
  591. package/simsimd/scripts/bench.ipynb +0 -187
  592. package/simsimd/scripts/bench.js +0 -127
  593. package/simsimd/scripts/bench.rs +0 -876
  594. package/simsimd/scripts/bench_vectors.py +0 -734
  595. package/simsimd/scripts/bench_vectors_live.py +0 -213
  596. package/simsimd/scripts/test.c +0 -187
  597. package/simsimd/scripts/test.mjs +0 -220
  598. package/simsimd/scripts/test.py +0 -1505
  599. package/simsimd/swift/SimSIMD.swift +0 -149
  600. package/simsimd/swift/Test.swift +0 -128
  601. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  602. /package/{simsimd → numkong}/LICENSE +0 -0
  603. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  604. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,513 @@
1
+ /**
2
+ * @brief SIMD-accelerated Similarity Measures for Curved Spaces.
3
+ * @file include/numkong/curved.h
4
+ * @author Ash Vardanian
5
+ * @date August 27, 2024
6
+ *
7
+ * Contains following similarity measures:
8
+ *
9
+ * - Mahalanobis distance: √((a-b)ᵀ × C × (a-b))
10
+ * - Bilinear form: aᵀ × C × b
11
+ * - Bilinear form over complex numbers
12
+ *
13
+ * For dtypes:
14
+ *
15
+ * - 64-bit floating point numbers → 64-bit floats
16
+ * - 32-bit floating point numbers → 64-bit floats
17
+ * - 16-bit floating point numbers → 32-bit floats
18
+ * - 16-bit brain-floating point numbers → 32-bit floats
19
+ *
20
+ * For hardware architectures:
21
+ *
22
+ * - Arm: NEON, NEON+F16, NEON+BF16, SME+F64
23
+ * - x86: Haswell, Skylake, Genoa
24
+ * - RISC-V: RVV
25
+ *
26
+ * @section numerical_stability Numerical Stability
27
+ *
28
+ * To minimize catastrophic cancellation in large-magnitude sums:
29
+ * - f32 kernels widen public outputs to f64/f64c and accumulate in f64 precision where possible
30
+ * - f64 kernels use Dot2 algorithm (Ogita-Rump-Oishi 2005) in SIMD paths
31
+ * - Serial kernels use Neumaier compensated summation for all types
32
+ *
33
+ * @section usage Usage and Benefits
34
+ *
35
+ * These kernels target BLAS level 2 patterns where vectors are combined with a metric
36
+ * tensor or covariance matrix. Using raw bilinear and Mahalanobis forms avoids constructing
37
+ * intermediates and keeps memory traffic low, which is often faster than a full GEMM path
38
+ * for small and medium sizes. Complex bilinear forms return a complex scalar as two reals,
39
+ * serving complex-valued signals without extra packing or unpacking.
40
+ *
41
+ * @section references References
42
+ *
43
+ * - x86 intrinsics: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
44
+ * - Arm intrinsics: https://developer.arm.com/architectures/instruction-sets/intrinsics/
45
+ * - Neumaier, A. (1974). "Rundungsfehleranalyse einiger Verfahren zur Summation endlicher Summen"
46
+ * - Ogita, T., Rump, S.M., Oishi, S. (2005). "Accurate Sum and Dot Product"
47
+ *
48
+ */
49
+ #ifndef NK_CURVED_H
50
+ #define NK_CURVED_H
51
+
52
+ #include "numkong/types.h"
53
+
54
+ #if defined(__cplusplus)
55
+ extern "C" {
56
+ #endif
57
+
58
+ /**
59
+ * @brief Bilinear form between vectors a and b under metric tensor C.
60
+ *
61
+ * Computes aᵀ × C × b = Σᵢ Σⱼ aᵢ × cᵢⱼ × bⱼ
62
+ *
63
+ * @param[in] a The first vector.
64
+ * @param[in] b The second vector.
65
+ * @param[in] c The metric tensor or covariance matrix, stored row-major as an n×n matrix.
66
+ * @param[in] n The number of dimensions in the vectors.
67
+ * @param[out] result The output bilinear form value.
68
+ *
69
+ * @note The output value can be negative.
70
+ */
71
+ NK_DYNAMIC void nk_bilinear_f64(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n, nk_f64_t *result);
72
+ /** @copydoc nk_bilinear_f64 */
73
+ NK_DYNAMIC void nk_bilinear_f32(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n, nk_f64_t *result);
74
+ /** @copydoc nk_bilinear_f64 */
75
+ NK_DYNAMIC void nk_bilinear_f16(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n, nk_f32_t *result);
76
+ /** @copydoc nk_bilinear_f64 */
77
+ NK_DYNAMIC void nk_bilinear_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
78
+ nk_f32_t *result);
79
+
80
+ /**
81
+ * @brief Mahalanobis distance between vectors a and b under metric tensor C.
82
+ *
83
+ * Computes √((a-b)ᵀ × C × (a-b)) = √(Σᵢ Σⱼ (aᵢ-bᵢ) × cᵢⱼ × (aⱼ-bⱼ))
84
+ *
85
+ * @param[in] a The first vector.
86
+ * @param[in] b The second vector.
87
+ * @param[in] c The Positive Semi-Definite (PSD) matrix, stored row-major as an n×n matrix.
88
+ * @param[in] n The number of dimensions in the vectors.
89
+ * @param[out] result The output distance value.
90
+ *
91
+ * @note The output value is non-negative when C is PSD.
92
+ * @note The output value is zero if and only if the two vectors are identical.
93
+ * @note The matrix C must be positive semi-definite. If C is not PSD, the quadratic form
94
+ * (a-b)ᵀ C (a-b) may be negative, and the square root will produce NaN.
95
+ */
96
+ NK_DYNAMIC void nk_mahalanobis_f64(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
97
+ nk_f64_t *result);
98
+ /** @copydoc nk_mahalanobis_f64 */
99
+ NK_DYNAMIC void nk_mahalanobis_f32(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
100
+ nk_f64_t *result);
101
+ /** @copydoc nk_mahalanobis_f64 */
102
+ NK_DYNAMIC void nk_mahalanobis_f16(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
103
+ nk_f32_t *result);
104
+ /** @copydoc nk_mahalanobis_f64 */
105
+ NK_DYNAMIC void nk_mahalanobis_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
106
+ nk_f32_t *result);
107
+
108
+ /**
109
+ * @brief Complex bilinear form between vectors a and b under metric tensor C.
110
+ *
111
+ * @param[in] a The first complex vector.
112
+ * @param[in] b The second complex vector.
113
+ * @param[in] c The complex metric tensor, stored row-major as an n×n matrix.
114
+ * @param[in] n The number of dimensions in the vectors.
115
+ * @param[out] results The output complex value with real and imaginary parts.
116
+ */
117
+ NK_DYNAMIC void nk_bilinear_f64c(nk_f64c_t const *a, nk_f64c_t const *b, nk_f64c_t const *c, nk_size_t n,
118
+ nk_f64c_t *results);
119
+ /** @copydoc nk_bilinear_f64c */
120
+ NK_DYNAMIC void nk_bilinear_f32c(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
121
+ nk_f64c_t *results);
122
+ /** @copydoc nk_bilinear_f64c */
123
+ NK_DYNAMIC void nk_bilinear_f16c(nk_f16c_t const *a, nk_f16c_t const *b, nk_f16c_t const *c, nk_size_t n,
124
+ nk_f32c_t *results);
125
+ /** @copydoc nk_bilinear_f64c */
126
+ NK_DYNAMIC void nk_bilinear_bf16c(nk_bf16c_t const *a, nk_bf16c_t const *b, nk_bf16c_t const *c, nk_size_t n,
127
+ nk_f32c_t *results);
128
+
129
+ /** @copydoc nk_bilinear_f64 */
130
+ NK_PUBLIC void nk_bilinear_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
131
+ nk_f64_t *result);
132
+ /** @copydoc nk_bilinear_f64c */
133
+ NK_PUBLIC void nk_bilinear_f64c_serial(nk_f64c_t const *a, nk_f64c_t const *b, nk_f64c_t const *c, nk_size_t n,
134
+ nk_f64c_t *results);
135
+ /** @copydoc nk_mahalanobis_f64 */
136
+ NK_PUBLIC void nk_mahalanobis_f64_serial(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
137
+ nk_f64_t *result);
138
+ /** @copydoc nk_bilinear_f32 */
139
+ NK_PUBLIC void nk_bilinear_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
140
+ nk_f64_t *result);
141
+ /** @copydoc nk_bilinear_f32c */
142
+ NK_PUBLIC void nk_bilinear_f32c_serial(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
143
+ nk_f64c_t *results);
144
+ /** @copydoc nk_mahalanobis_f32 */
145
+ NK_PUBLIC void nk_mahalanobis_f32_serial(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
146
+ nk_f64_t *result);
147
+ /** @copydoc nk_bilinear_f16 */
148
+ NK_PUBLIC void nk_bilinear_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
149
+ nk_f32_t *result);
150
+ /** @copydoc nk_bilinear_f16c */
151
+ NK_PUBLIC void nk_bilinear_f16c_serial(nk_f16c_t const *a, nk_f16c_t const *b, nk_f16c_t const *c, nk_size_t n,
152
+ nk_f32c_t *results);
153
+ /** @copydoc nk_mahalanobis_f16 */
154
+ NK_PUBLIC void nk_mahalanobis_f16_serial(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
155
+ nk_f32_t *result);
156
+ /** @copydoc nk_bilinear_bf16 */
157
+ NK_PUBLIC void nk_bilinear_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
158
+ nk_f32_t *result);
159
+ /** @copydoc nk_bilinear_bf16c */
160
+ NK_PUBLIC void nk_bilinear_bf16c_serial(nk_bf16c_t const *a, nk_bf16c_t const *b, nk_bf16c_t const *c, nk_size_t n,
161
+ nk_f32c_t *results);
162
+ /** @copydoc nk_mahalanobis_bf16 */
163
+ NK_PUBLIC void nk_mahalanobis_bf16_serial(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
164
+ nk_f32_t *result);
165
+
166
+ #if NK_TARGET_NEON
167
+ /** @copydoc nk_bilinear_f32 */
168
+ NK_PUBLIC void nk_bilinear_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
169
+ nk_f64_t *result);
170
+ /** @copydoc nk_bilinear_f32c */
171
+ NK_PUBLIC void nk_bilinear_f32c_neon(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
172
+ nk_f64c_t *results);
173
+ /** @copydoc nk_mahalanobis_f32 */
174
+ NK_PUBLIC void nk_mahalanobis_f32_neon(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
175
+ nk_f64_t *result);
176
+ /** @copydoc nk_bilinear_f16 */
177
+ NK_PUBLIC void nk_bilinear_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
178
+ nk_f32_t *result);
179
+ /** @copydoc nk_bilinear_f16c */
180
+ NK_PUBLIC void nk_bilinear_f16c_neon(nk_f16c_t const *a, nk_f16c_t const *b, nk_f16c_t const *c, nk_size_t n,
181
+ nk_f32c_t *results);
182
+ /** @copydoc nk_mahalanobis_f16 */
183
+ NK_PUBLIC void nk_mahalanobis_f16_neon(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
184
+ nk_f32_t *result);
185
+ #endif // NK_TARGET_NEON
186
+
187
+ #if NK_TARGET_NEONBFDOT
188
+ /** @copydoc nk_bilinear_bf16 */
189
+ NK_PUBLIC void nk_bilinear_bf16_neonbfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
190
+ nk_f32_t *result);
191
+ /** @copydoc nk_bilinear_bf16c */
192
+ NK_PUBLIC void nk_bilinear_bf16c_neonbfdot(nk_bf16c_t const *a, nk_bf16c_t const *b, nk_bf16c_t const *c, nk_size_t n,
193
+ nk_f32c_t *results);
194
+ /** @copydoc nk_mahalanobis_bf16 */
195
+ NK_PUBLIC void nk_mahalanobis_bf16_neonbfdot(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
196
+ nk_f32_t *result);
197
+ #endif // NK_TARGET_NEONBFDOT
198
+
199
+ #if NK_TARGET_SMEF64
200
+ /** @copydoc nk_bilinear_f32 */
201
+ NK_PUBLIC void nk_bilinear_f32_smef64(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
202
+ nk_f64_t *result);
203
+ /** @copydoc nk_bilinear_f32c */
204
+ NK_PUBLIC void nk_bilinear_f32c_smef64(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
205
+ nk_f64c_t *result);
206
+ /** @copydoc nk_mahalanobis_f32 */
207
+ NK_PUBLIC void nk_mahalanobis_f32_smef64(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
208
+ nk_f64_t *result);
209
+ /** @copydoc nk_bilinear_f64 */
210
+ NK_PUBLIC void nk_bilinear_f64_smef64(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
211
+ nk_f64_t *result);
212
+ /** @copydoc nk_bilinear_f64c */
213
+ NK_PUBLIC void nk_bilinear_f64c_smef64(nk_f64c_t const *a, nk_f64c_t const *b, nk_f64c_t const *c, nk_size_t n,
214
+ nk_f64c_t *result);
215
+ /** @copydoc nk_mahalanobis_f64 */
216
+ NK_PUBLIC void nk_mahalanobis_f64_smef64(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
217
+ nk_f64_t *result);
218
+ #endif // NK_TARGET_SMEF64
219
+
220
+ #if NK_TARGET_HASWELL
221
+ /** @copydoc nk_bilinear_f32 */
222
+ NK_PUBLIC void nk_bilinear_f32_haswell(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
223
+ nk_f64_t *result);
224
+ /** @copydoc nk_mahalanobis_f32 */
225
+ NK_PUBLIC void nk_mahalanobis_f32_haswell(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
226
+ nk_f64_t *result);
227
+ /** @copydoc nk_bilinear_f16 */
228
+ NK_PUBLIC void nk_bilinear_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
229
+ nk_f32_t *result);
230
+ /** @copydoc nk_mahalanobis_f16 */
231
+ NK_PUBLIC void nk_mahalanobis_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
232
+ nk_f32_t *result);
233
+ /** @copydoc nk_bilinear_bf16 */
234
+ NK_PUBLIC void nk_bilinear_bf16_haswell(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
235
+ nk_f32_t *result);
236
+ /** @copydoc nk_mahalanobis_bf16 */
237
+ NK_PUBLIC void nk_mahalanobis_bf16_haswell(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
238
+ nk_f32_t *result);
239
+ #endif // NK_TARGET_HASWELL
240
+
241
+ #if NK_TARGET_SKYLAKE
242
+ /** @copydoc nk_bilinear_f64 */
243
+ NK_PUBLIC void nk_bilinear_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
244
+ nk_f64_t *result);
245
+ /** @copydoc nk_bilinear_f64c */
246
+ NK_PUBLIC void nk_bilinear_f64c_skylake(nk_f64c_t const *a, nk_f64c_t const *b, nk_f64c_t const *c, nk_size_t n,
247
+ nk_f64c_t *results);
248
+ /** @copydoc nk_mahalanobis_f64 */
249
+ NK_PUBLIC void nk_mahalanobis_f64_skylake(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
250
+ nk_f64_t *result);
251
+ /** @copydoc nk_bilinear_f32 */
252
+ NK_PUBLIC void nk_bilinear_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
253
+ nk_f64_t *result);
254
+ /** @copydoc nk_bilinear_f32c */
255
+ NK_PUBLIC void nk_bilinear_f32c_skylake(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
256
+ nk_f64c_t *results);
257
+ /** @copydoc nk_mahalanobis_f32 */
258
+ NK_PUBLIC void nk_mahalanobis_f32_skylake(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
259
+ nk_f64_t *result);
260
+ #endif // NK_TARGET_SKYLAKE
261
+
262
+ #if NK_TARGET_GENOA
263
+ /** @copydoc nk_bilinear_bf16 */
264
+ NK_PUBLIC void nk_bilinear_bf16_genoa(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
265
+ nk_f32_t *result);
266
+ /** @copydoc nk_bilinear_bf16c */
267
+ NK_PUBLIC void nk_bilinear_bf16c_genoa(nk_bf16c_t const *a, nk_bf16c_t const *b, nk_bf16c_t const *c, nk_size_t n,
268
+ nk_f32c_t *results);
269
+ /** @copydoc nk_mahalanobis_bf16 */
270
+ NK_PUBLIC void nk_mahalanobis_bf16_genoa(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
271
+ nk_f32_t *result);
272
+ #endif // NK_TARGET_GENOA
273
+
274
+ #if NK_TARGET_RVV
275
+ /** @copydoc nk_bilinear_f64 */
276
+ NK_PUBLIC void nk_bilinear_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
277
+ nk_f64_t *result);
278
+ /** @copydoc nk_mahalanobis_f64 */
279
+ NK_PUBLIC void nk_mahalanobis_f64_rvv(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
280
+ nk_f64_t *result);
281
+ /** @copydoc nk_bilinear_f32 */
282
+ NK_PUBLIC void nk_bilinear_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
283
+ nk_f64_t *result);
284
+ /** @copydoc nk_mahalanobis_f32 */
285
+ NK_PUBLIC void nk_mahalanobis_f32_rvv(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
286
+ nk_f64_t *result);
287
+ /** @copydoc nk_bilinear_f16 */
288
+ NK_PUBLIC void nk_bilinear_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
289
+ nk_f32_t *result);
290
+ /** @copydoc nk_mahalanobis_f16 */
291
+ NK_PUBLIC void nk_mahalanobis_f16_rvv(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
292
+ nk_f32_t *result);
293
+ /** @copydoc nk_bilinear_bf16 */
294
+ NK_PUBLIC void nk_bilinear_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
295
+ nk_f32_t *result);
296
+ /** @copydoc nk_mahalanobis_bf16 */
297
+ NK_PUBLIC void nk_mahalanobis_bf16_rvv(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
298
+ nk_f32_t *result);
299
+ #endif // NK_TARGET_RVV
300
+
301
+ /**
302
+ * @brief Returns the output dtype for bilinear forms.
303
+ */
304
+ NK_INTERNAL nk_dtype_t nk_bilinear_output_dtype(nk_dtype_t dtype) {
305
+ switch (dtype) {
306
+ case nk_f64_k: return nk_f64_k;
307
+ case nk_f32_k: return nk_f64_k;
308
+ case nk_f16_k: return nk_f32_k;
309
+ case nk_bf16_k: return nk_f32_k;
310
+ case nk_f64c_k: return nk_f64c_k;
311
+ case nk_f32c_k: return nk_f64c_k;
312
+ case nk_f16c_k: return nk_f32c_k;
313
+ case nk_bf16c_k: return nk_f32c_k;
314
+ default: return nk_dtype_unknown_k;
315
+ }
316
+ }
317
+
318
+ /**
319
+ * @brief Returns the output dtype for Mahalanobis metrics.
320
+ */
321
+ NK_INTERNAL nk_dtype_t nk_mahalanobis_output_dtype(nk_dtype_t dtype) {
322
+ switch (dtype) {
323
+ case nk_f64_k: return nk_f64_k;
324
+ case nk_f32_k: return nk_f64_k;
325
+ case nk_f16_k: return nk_f32_k;
326
+ case nk_bf16_k: return nk_f32_k;
327
+ default: return nk_dtype_unknown_k;
328
+ }
329
+ }
330
+
331
+ #if defined(__cplusplus)
332
+ } // extern "C"
333
+ #endif
334
+
335
+ #include "numkong/curved/serial.h"
336
+ #include "numkong/curved/neon.h"
337
+ #include "numkong/curved/neonbfdot.h"
338
+ #include "numkong/curved/smef64.h"
339
+ #include "numkong/curved/haswell.h"
340
+ #include "numkong/curved/skylake.h"
341
+ #include "numkong/curved/genoa.h"
342
+ #include "numkong/curved/rvv.h"
343
+
344
+ #if defined(__cplusplus)
345
+ extern "C" {
346
+ #endif
347
+
348
+ #if !NK_DYNAMIC_DISPATCH
349
+
350
+ NK_PUBLIC void nk_bilinear_f64(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n, nk_f64_t *result) {
351
+ #if NK_TARGET_SKYLAKE
352
+ nk_bilinear_f64_skylake(a, b, c, n, result);
353
+ #elif NK_TARGET_SMEF64
354
+ nk_bilinear_f64_smef64(a, b, c, n, result);
355
+ #elif NK_TARGET_RVV
356
+ nk_bilinear_f64_rvv(a, b, c, n, result);
357
+ #else
358
+ nk_bilinear_f64_serial(a, b, c, n, result);
359
+ #endif
360
+ }
361
+
362
+ NK_PUBLIC void nk_bilinear_f32(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n, nk_f64_t *result) {
363
+ #if NK_TARGET_SKYLAKE
364
+ nk_bilinear_f32_skylake(a, b, c, n, result);
365
+ #elif NK_TARGET_SMEF64
366
+ nk_bilinear_f32_smef64(a, b, c, n, result);
367
+ #elif NK_TARGET_HASWELL
368
+ nk_bilinear_f32_haswell(a, b, c, n, result);
369
+ #elif NK_TARGET_NEON
370
+ nk_bilinear_f32_neon(a, b, c, n, result);
371
+ #elif NK_TARGET_RVV
372
+ nk_bilinear_f32_rvv(a, b, c, n, result);
373
+ #else
374
+ nk_bilinear_f32_serial(a, b, c, n, result);
375
+ #endif
376
+ }
377
+
378
+ NK_PUBLIC void nk_bilinear_f16(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n, nk_f32_t *result) {
379
+ #if NK_TARGET_HASWELL
380
+ nk_bilinear_f16_haswell(a, b, c, n, result);
381
+ #elif NK_TARGET_NEON
382
+ nk_bilinear_f16_neon(a, b, c, n, result);
383
+ #elif NK_TARGET_RVV
384
+ nk_bilinear_f16_rvv(a, b, c, n, result);
385
+ #else
386
+ nk_bilinear_f16_serial(a, b, c, n, result);
387
+ #endif
388
+ }
389
+
390
+ NK_PUBLIC void nk_bilinear_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
391
+ nk_f32_t *result) {
392
+ #if NK_TARGET_GENOA
393
+ nk_bilinear_bf16_genoa(a, b, c, n, result);
394
+ #elif NK_TARGET_HASWELL
395
+ nk_bilinear_bf16_haswell(a, b, c, n, result);
396
+ #elif NK_TARGET_NEONBFDOT
397
+ nk_bilinear_bf16_neonbfdot(a, b, c, n, result);
398
+ #elif NK_TARGET_RVV
399
+ nk_bilinear_bf16_rvv(a, b, c, n, result);
400
+ #else
401
+ nk_bilinear_bf16_serial(a, b, c, n, result);
402
+ #endif
403
+ }
404
+
405
+ NK_PUBLIC void nk_bilinear_f64c(nk_f64c_t const *a, nk_f64c_t const *b, nk_f64c_t const *c, nk_size_t n,
406
+ nk_f64c_t *results) {
407
+ #if NK_TARGET_SKYLAKE
408
+ nk_bilinear_f64c_skylake(a, b, c, n, results);
409
+ #elif NK_TARGET_SMEF64
410
+ nk_bilinear_f64c_smef64(a, b, c, n, results);
411
+ #else
412
+ nk_bilinear_f64c_serial(a, b, c, n, results);
413
+ #endif
414
+ }
415
+
416
+ NK_PUBLIC void nk_bilinear_f32c(nk_f32c_t const *a, nk_f32c_t const *b, nk_f32c_t const *c, nk_size_t n,
417
+ nk_f64c_t *results) {
418
+ #if NK_TARGET_SKYLAKE
419
+ nk_bilinear_f32c_skylake(a, b, c, n, results);
420
+ #elif NK_TARGET_SMEF64
421
+ nk_bilinear_f32c_smef64(a, b, c, n, results);
422
+ #elif NK_TARGET_NEON
423
+ nk_bilinear_f32c_neon(a, b, c, n, results);
424
+ #else
425
+ nk_bilinear_f32c_serial(a, b, c, n, results);
426
+ #endif
427
+ }
428
+
429
+ NK_PUBLIC void nk_bilinear_f16c(nk_f16c_t const *a, nk_f16c_t const *b, nk_f16c_t const *c, nk_size_t n,
430
+ nk_f32c_t *results) {
431
+ #if NK_TARGET_NEON
432
+ nk_bilinear_f16c_neon(a, b, c, n, results);
433
+ #else
434
+ nk_bilinear_f16c_serial(a, b, c, n, results);
435
+ #endif
436
+ }
437
+
438
+ NK_PUBLIC void nk_bilinear_bf16c(nk_bf16c_t const *a, nk_bf16c_t const *b, nk_bf16c_t const *c, nk_size_t n,
439
+ nk_f32c_t *results) {
440
+ #if NK_TARGET_GENOA
441
+ nk_bilinear_bf16c_genoa(a, b, c, n, results);
442
+ #elif NK_TARGET_NEONBFDOT
443
+ nk_bilinear_bf16c_neonbfdot(a, b, c, n, results);
444
+ #else
445
+ nk_bilinear_bf16c_serial(a, b, c, n, results);
446
+ #endif
447
+ }
448
+
449
+ NK_PUBLIC void nk_mahalanobis_f64(nk_f64_t const *a, nk_f64_t const *b, nk_f64_t const *c, nk_size_t n,
450
+ nk_f64_t *result) {
451
+ #if NK_TARGET_SKYLAKE
452
+ nk_mahalanobis_f64_skylake(a, b, c, n, result);
453
+ #elif NK_TARGET_SMEF64
454
+ nk_mahalanobis_f64_smef64(a, b, c, n, result);
455
+ #elif NK_TARGET_RVV
456
+ nk_mahalanobis_f64_rvv(a, b, c, n, result);
457
+ #else
458
+ nk_mahalanobis_f64_serial(a, b, c, n, result);
459
+ #endif
460
+ }
461
+
462
+ NK_PUBLIC void nk_mahalanobis_f32(nk_f32_t const *a, nk_f32_t const *b, nk_f32_t const *c, nk_size_t n,
463
+ nk_f64_t *result) {
464
+ #if NK_TARGET_SKYLAKE
465
+ nk_mahalanobis_f32_skylake(a, b, c, n, result);
466
+ #elif NK_TARGET_SMEF64
467
+ nk_mahalanobis_f32_smef64(a, b, c, n, result);
468
+ #elif NK_TARGET_HASWELL
469
+ nk_mahalanobis_f32_haswell(a, b, c, n, result);
470
+ #elif NK_TARGET_NEON
471
+ nk_mahalanobis_f32_neon(a, b, c, n, result);
472
+ #elif NK_TARGET_RVV
473
+ nk_mahalanobis_f32_rvv(a, b, c, n, result);
474
+ #else
475
+ nk_mahalanobis_f32_serial(a, b, c, n, result);
476
+ #endif
477
+ }
478
+
479
+ NK_PUBLIC void nk_mahalanobis_f16(nk_f16_t const *a, nk_f16_t const *b, nk_f16_t const *c, nk_size_t n,
480
+ nk_f32_t *result) {
481
+ #if NK_TARGET_HASWELL
482
+ nk_mahalanobis_f16_haswell(a, b, c, n, result);
483
+ #elif NK_TARGET_NEON
484
+ nk_mahalanobis_f16_neon(a, b, c, n, result);
485
+ #elif NK_TARGET_RVV
486
+ nk_mahalanobis_f16_rvv(a, b, c, n, result);
487
+ #else
488
+ nk_mahalanobis_f16_serial(a, b, c, n, result);
489
+ #endif
490
+ }
491
+
492
+ NK_PUBLIC void nk_mahalanobis_bf16(nk_bf16_t const *a, nk_bf16_t const *b, nk_bf16_t const *c, nk_size_t n,
493
+ nk_f32_t *result) {
494
+ #if NK_TARGET_GENOA
495
+ nk_mahalanobis_bf16_genoa(a, b, c, n, result);
496
+ #elif NK_TARGET_HASWELL
497
+ nk_mahalanobis_bf16_haswell(a, b, c, n, result);
498
+ #elif NK_TARGET_NEONBFDOT
499
+ nk_mahalanobis_bf16_neonbfdot(a, b, c, n, result);
500
+ #elif NK_TARGET_RVV
501
+ nk_mahalanobis_bf16_rvv(a, b, c, n, result);
502
+ #else
503
+ nk_mahalanobis_bf16_serial(a, b, c, n, result);
504
+ #endif
505
+ }
506
+
507
+ #endif // !NK_DYNAMIC_DISPATCH
508
+
509
+ #if defined(__cplusplus)
510
+ } // extern "C"
511
+ #endif
512
+
513
+ #endif // NK_CURVED_H
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @brief Curved-space kernels: bilinear, mahalanobis.
3
+ * @file include/numkong/curved.hpp
4
+ * @author Ash Vardanian
5
+ * @date February 5, 2026
6
+ */
7
+ #ifndef NK_CURVED_HPP
8
+ #define NK_CURVED_HPP
9
+
10
+ #include <cstdint> // `std::uint32_t`
11
+ #include <type_traits> // `std::is_same_v`
12
+
13
+ #include "numkong/curved.h"
14
+
15
+ #include "numkong/types.hpp"
16
+
17
+ namespace ashvardanian::numkong {
18
+
19
+ /**
20
+ * @brief Bilinear form: aᵀ × C × b where C is a d×d matrix (row-major)
21
+ * @param[in] a,b Input vectors of length d
22
+ * @param[in] c Matrix of size dxd (row-major)
23
+ * @param[in] d Number of dimensions
24
+ * @param[out] r Pointer to output value
25
+ *
26
+ * @tparam in_type_ Input vector element type (real or complex)
27
+ * @tparam result_type_ Accumulator type, defaults to `in_type_::curved_result_t`
28
+ * @tparam allow_simd_ Enable SIMD kernel dispatch when `prefer_simd_k`
29
+ *
30
+ * @note For weighted inner products, Mahalanobis distance, etc.
31
+ */
32
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::curved_result_t,
33
+ allow_simd_t allow_simd_ = prefer_simd_k>
34
+ void bilinear(in_type_ const *a, in_type_ const *b, in_type_ const *c, std::size_t d, result_type_ *r) noexcept {
35
+ constexpr bool simd = allow_simd_ == prefer_simd_k &&
36
+ std::is_same_v<result_type_, typename in_type_::curved_result_t>;
37
+
38
+ // Real types
39
+ if constexpr (std::is_same_v<in_type_, f64_t> && simd) nk_bilinear_f64(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
40
+ else if constexpr (std::is_same_v<in_type_, f32_t> && simd)
41
+ nk_bilinear_f32(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
42
+ else if constexpr (std::is_same_v<in_type_, f16_t> && simd)
43
+ nk_bilinear_f16(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
44
+ else if constexpr (std::is_same_v<in_type_, bf16_t> && simd)
45
+ nk_bilinear_bf16(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
46
+ // Complex types
47
+ else if constexpr (std::is_same_v<in_type_, f64c_t> && simd)
48
+ nk_bilinear_f64c(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
49
+ else if constexpr (std::is_same_v<in_type_, f32c_t> && simd)
50
+ nk_bilinear_f32c(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
51
+ else if constexpr (std::is_same_v<in_type_, f16c_t> && simd)
52
+ nk_bilinear_f16c(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
53
+ else if constexpr (std::is_same_v<in_type_, bf16c_t> && simd)
54
+ nk_bilinear_bf16c(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
55
+ // Scalar fallback
56
+ else {
57
+ result_type_ sum {};
58
+ for (std::size_t i = 0; i < d; i++) {
59
+ for (std::size_t j = 0; j < d; j++) {
60
+ sum = sum + result_type_(a[i]) * result_type_(c[i * d + j]) * result_type_(b[j]);
61
+ }
62
+ }
63
+ *r = sum;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @brief Mahalanobis distance: √((a−b)ᵀ × C × (a−b)) where C is a d×d matrix (row-major)
69
+ * @param[in] a,b Input vectors of length d
70
+ * @param[in] c Covariance matrix of size dxd (row-major)
71
+ * @param[in] d Number of dimensions
72
+ * @param[out] r Pointer to output distance value
73
+ *
74
+ * @tparam in_type_ Input vector element type
75
+ * @tparam result_type_ Accumulator type, defaults to `in_type_::curved_result_t`
76
+ * @tparam allow_simd_ Enable SIMD kernel dispatch when `prefer_simd_k`
77
+ */
78
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::curved_result_t,
79
+ allow_simd_t allow_simd_ = prefer_simd_k>
80
+ void mahalanobis(in_type_ const *a, in_type_ const *b, in_type_ const *c, std::size_t d, result_type_ *r) noexcept {
81
+ constexpr bool simd = allow_simd_ == prefer_simd_k &&
82
+ std::is_same_v<result_type_, typename in_type_::curved_result_t>;
83
+
84
+ if constexpr (std::is_same_v<in_type_, f64_t> && simd)
85
+ nk_mahalanobis_f64(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
86
+ else if constexpr (std::is_same_v<in_type_, f32_t> && simd)
87
+ nk_mahalanobis_f32(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
88
+ else if constexpr (std::is_same_v<in_type_, f16_t> && simd)
89
+ nk_mahalanobis_f16(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
90
+ else if constexpr (std::is_same_v<in_type_, bf16_t> && simd)
91
+ nk_mahalanobis_bf16(&a->raw_, &b->raw_, &c->raw_, d, &r->raw_);
92
+ // Scalar fallback
93
+ else {
94
+ result_type_ sum {};
95
+ for (std::size_t i = 0; i < d; i++) {
96
+ result_type_ di = result_type_(a[i]) - result_type_(b[i]);
97
+ for (std::size_t j = 0; j < d; j++) {
98
+ result_type_ dj = result_type_(a[j]) - result_type_(b[j]);
99
+ sum = sum + di * result_type_(c[i * d + j]) * dj;
100
+ }
101
+ }
102
+ *r = sum.sqrt();
103
+ }
104
+ }
105
+
106
+ } // namespace ashvardanian::numkong
107
+
108
+ #include "numkong/tensor.hpp"
109
+
110
+ namespace ashvardanian::numkong {
111
+
112
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::curved_result_t,
113
+ allow_simd_t allow_simd_ = prefer_simd_k, std::size_t max_rank_a_, std::size_t max_rank_b_,
114
+ std::size_t max_rank_c_>
115
+ void bilinear(tensor_view<in_type_, max_rank_a_> a, tensor_view<in_type_, max_rank_b_> b,
116
+ tensor_view<in_type_, max_rank_c_> c, std::size_t d, result_type_ *r) noexcept {
117
+ bilinear<in_type_, result_type_, allow_simd_>(a.data(), b.data(), c.data(), d, r);
118
+ }
119
+
120
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::curved_result_t,
121
+ allow_simd_t allow_simd_ = prefer_simd_k>
122
+ void bilinear(vector_view<in_type_> a, vector_view<in_type_> b, vector_view<in_type_> c, std::size_t d,
123
+ result_type_ *r) noexcept {
124
+ bilinear<in_type_, result_type_, allow_simd_>(a.data(), b.data(), c.data(), d, r);
125
+ }
126
+
127
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::curved_result_t,
128
+ allow_simd_t allow_simd_ = prefer_simd_k, std::size_t max_rank_a_, std::size_t max_rank_b_,
129
+ std::size_t max_rank_c_>
130
+ void mahalanobis(tensor_view<in_type_, max_rank_a_> a, tensor_view<in_type_, max_rank_b_> b,
131
+ tensor_view<in_type_, max_rank_c_> c, std::size_t d, result_type_ *r) noexcept {
132
+ mahalanobis<in_type_, result_type_, allow_simd_>(a.data(), b.data(), c.data(), d, r);
133
+ }
134
+
135
+ template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::curved_result_t,
136
+ allow_simd_t allow_simd_ = prefer_simd_k>
137
+ void mahalanobis(vector_view<in_type_> a, vector_view<in_type_> b, vector_view<in_type_> c, std::size_t d,
138
+ result_type_ *r) noexcept {
139
+ mahalanobis<in_type_, result_type_, allow_simd_>(a.data(), b.data(), c.data(), d, r);
140
+ }
141
+
142
+ } // namespace ashvardanian::numkong
143
+
144
+ #endif // NK_CURVED_HPP