usearch 2.21.4 → 2.25.0

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 (602) hide show
  1. package/README.md +24 -24
  2. package/binding.gyp +15 -37
  3. package/c/CMakeLists.txt +4 -5
  4. package/c/README.md +7 -7
  5. package/c/lib.cpp +32 -14
  6. package/c/test.c +83 -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/dist/cjs/usearch.d.ts +8 -3
  16. package/javascript/dist/cjs/usearch.js +12 -4
  17. package/javascript/dist/esm/usearch.d.ts +8 -3
  18. package/javascript/dist/esm/usearch.js +12 -4
  19. package/javascript/lib.cpp +17 -0
  20. package/javascript/usearch.ts +14 -6
  21. package/numkong/.clang-tidy +30 -0
  22. package/{simsimd → numkong}/.cmake-format.py +18 -0
  23. package/numkong/.editorconfig +12 -0
  24. package/numkong/.git-blame-ignore-revs +123 -0
  25. package/numkong/.mailmap +15 -0
  26. package/numkong/.spi.yml +11 -0
  27. package/numkong/.swift-format +14 -0
  28. package/numkong/CITATION.cff +81 -0
  29. package/numkong/CONTRIBUTING.md +500 -0
  30. package/numkong/Cargo.toml +54 -0
  31. package/numkong/MANIFEST.in +8 -0
  32. package/numkong/Package.swift +84 -0
  33. package/numkong/README.md +569 -0
  34. package/numkong/bench/README.md +217 -0
  35. package/numkong/bench/bench-browser.html +323 -0
  36. package/numkong/bench/bench.cpp +344 -0
  37. package/numkong/bench/bench.hpp +816 -0
  38. package/numkong/bench/bench.js +148 -0
  39. package/numkong/bench/bench.mjs +616 -0
  40. package/numkong/bench/bench_attention.cpp +113 -0
  41. package/numkong/bench/bench_cast.cpp +264 -0
  42. package/numkong/bench/bench_cross_amx.cpp +62 -0
  43. package/numkong/bench/bench_cross_arm.cpp +245 -0
  44. package/numkong/bench/bench_cross_blas.cpp +309 -0
  45. package/numkong/bench/bench_cross_loongarch.cpp +106 -0
  46. package/numkong/bench/bench_cross_power.cpp +84 -0
  47. package/numkong/bench/bench_cross_rvv.cpp +121 -0
  48. package/numkong/bench/bench_cross_serial.cpp +151 -0
  49. package/numkong/bench/bench_cross_sme.cpp +163 -0
  50. package/numkong/bench/bench_cross_wasm.cpp +142 -0
  51. package/numkong/bench/bench_cross_x86.cpp +455 -0
  52. package/numkong/bench/bench_curved.cpp +210 -0
  53. package/numkong/bench/bench_dot.cpp +315 -0
  54. package/numkong/bench/bench_each.cpp +503 -0
  55. package/numkong/bench/bench_geospatial.cpp +112 -0
  56. package/numkong/bench/bench_maxsim.cpp +154 -0
  57. package/numkong/bench/bench_mesh.cpp +148 -0
  58. package/numkong/bench/bench_probability.cpp +60 -0
  59. package/numkong/bench/bench_reduce.cpp +371 -0
  60. package/numkong/bench/bench_set.cpp +73 -0
  61. package/numkong/bench/bench_sparse.cpp +198 -0
  62. package/numkong/bench/bench_spatial.cpp +347 -0
  63. package/numkong/bench/bench_trigonometry.cpp +137 -0
  64. package/numkong/bench/swift/Bench.swift +506 -0
  65. package/numkong/binding.gyp +169 -0
  66. package/numkong/build.rs +484 -0
  67. package/numkong/c/dispatch.h +512 -0
  68. package/numkong/c/dispatch_bf16.c +447 -0
  69. package/numkong/c/dispatch_bf16c.c +52 -0
  70. package/numkong/c/dispatch_e2m3.c +296 -0
  71. package/numkong/c/dispatch_e3m2.c +284 -0
  72. package/numkong/c/dispatch_e4m3.c +318 -0
  73. package/numkong/c/dispatch_e5m2.c +316 -0
  74. package/numkong/c/dispatch_f16.c +452 -0
  75. package/numkong/c/dispatch_f16c.c +58 -0
  76. package/numkong/c/dispatch_f32.c +434 -0
  77. package/numkong/c/dispatch_f32c.c +99 -0
  78. package/numkong/c/dispatch_f64.c +348 -0
  79. package/numkong/c/dispatch_f64c.c +98 -0
  80. package/numkong/c/dispatch_i16.c +96 -0
  81. package/numkong/c/dispatch_i32.c +89 -0
  82. package/numkong/c/dispatch_i4.c +153 -0
  83. package/numkong/c/dispatch_i64.c +86 -0
  84. package/numkong/c/dispatch_i8.c +348 -0
  85. package/numkong/c/dispatch_other.c +348 -0
  86. package/numkong/c/dispatch_u1.c +193 -0
  87. package/numkong/c/dispatch_u16.c +124 -0
  88. package/numkong/c/dispatch_u32.c +118 -0
  89. package/numkong/c/dispatch_u4.c +153 -0
  90. package/numkong/c/dispatch_u64.c +102 -0
  91. package/numkong/c/dispatch_u8.c +364 -0
  92. package/numkong/c/numkong.c +940 -0
  93. package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
  94. package/numkong/cmake/nk_isa_probe.cmake +90 -0
  95. package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
  96. package/numkong/cmake/nk_math_lib.cmake +46 -0
  97. package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
  98. package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
  99. package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
  100. package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
  101. package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
  102. package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
  103. package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
  104. package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
  105. package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
  106. package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
  107. package/numkong/cmake/toolchain-wasi.cmake +77 -0
  108. package/numkong/cmake/toolchain-wasm.cmake +70 -0
  109. package/numkong/cmake/toolchain-wasm64.cmake +62 -0
  110. package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
  111. package/numkong/include/README.md +643 -0
  112. package/numkong/include/module.modulemap +129 -0
  113. package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
  114. package/numkong/include/numkong/attention/sme.h +2075 -0
  115. package/numkong/include/numkong/attention.h +49 -0
  116. package/numkong/include/numkong/capabilities.h +930 -0
  117. package/numkong/include/numkong/cast/README.md +262 -0
  118. package/numkong/include/numkong/cast/diamond.h +64 -0
  119. package/numkong/include/numkong/cast/haswell.h +823 -0
  120. package/numkong/include/numkong/cast/icelake.h +475 -0
  121. package/numkong/include/numkong/cast/loongsonasx.h +252 -0
  122. package/numkong/include/numkong/cast/neon.h +1174 -0
  123. package/numkong/include/numkong/cast/powervsx.h +449 -0
  124. package/numkong/include/numkong/cast/rvv.h +970 -0
  125. package/numkong/include/numkong/cast/sapphire.h +262 -0
  126. package/numkong/include/numkong/cast/serial.h +2336 -0
  127. package/numkong/include/numkong/cast/skylake.h +915 -0
  128. package/numkong/include/numkong/cast/v128relaxed.h +537 -0
  129. package/numkong/include/numkong/cast.h +254 -0
  130. package/numkong/include/numkong/cast.hpp +44 -0
  131. package/numkong/include/numkong/curved/README.md +223 -0
  132. package/numkong/include/numkong/curved/genoa.h +182 -0
  133. package/numkong/include/numkong/curved/haswell.h +276 -0
  134. package/numkong/include/numkong/curved/neon.h +329 -0
  135. package/numkong/include/numkong/curved/neonbfdot.h +211 -0
  136. package/numkong/include/numkong/curved/rvv.h +305 -0
  137. package/numkong/include/numkong/curved/serial.h +207 -0
  138. package/numkong/include/numkong/curved/skylake.h +457 -0
  139. package/numkong/include/numkong/curved/smef64.h +530 -0
  140. package/numkong/include/numkong/curved.h +513 -0
  141. package/numkong/include/numkong/curved.hpp +144 -0
  142. package/numkong/include/numkong/dot/README.md +442 -0
  143. package/numkong/include/numkong/dot/alder.h +563 -0
  144. package/numkong/include/numkong/dot/diamond.h +158 -0
  145. package/numkong/include/numkong/dot/genoa.h +289 -0
  146. package/numkong/include/numkong/dot/haswell.h +1723 -0
  147. package/numkong/include/numkong/dot/icelake.h +997 -0
  148. package/numkong/include/numkong/dot/loongsonasx.h +671 -0
  149. package/numkong/include/numkong/dot/neon.h +869 -0
  150. package/numkong/include/numkong/dot/neonbfdot.h +243 -0
  151. package/numkong/include/numkong/dot/neonfhm.h +358 -0
  152. package/numkong/include/numkong/dot/neonfp8.h +323 -0
  153. package/numkong/include/numkong/dot/neonsdot.h +622 -0
  154. package/numkong/include/numkong/dot/powervsx.h +752 -0
  155. package/numkong/include/numkong/dot/rvv.h +722 -0
  156. package/numkong/include/numkong/dot/rvvbb.h +72 -0
  157. package/numkong/include/numkong/dot/rvvbf16.h +123 -0
  158. package/numkong/include/numkong/dot/rvvhalf.h +129 -0
  159. package/numkong/include/numkong/dot/sapphire.h +141 -0
  160. package/numkong/include/numkong/dot/serial.h +874 -0
  161. package/numkong/include/numkong/dot/sierra.h +405 -0
  162. package/numkong/include/numkong/dot/skylake.h +1116 -0
  163. package/numkong/include/numkong/dot/sve.h +420 -0
  164. package/numkong/include/numkong/dot/svebfdot.h +75 -0
  165. package/numkong/include/numkong/dot/svehalf.h +168 -0
  166. package/numkong/include/numkong/dot/svesdot.h +90 -0
  167. package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
  168. package/numkong/include/numkong/dot.h +1136 -0
  169. package/numkong/include/numkong/dot.hpp +94 -0
  170. package/numkong/include/numkong/dots/README.md +496 -0
  171. package/numkong/include/numkong/dots/alder.h +117 -0
  172. package/numkong/include/numkong/dots/diamond.h +86 -0
  173. package/numkong/include/numkong/dots/genoa.h +100 -0
  174. package/numkong/include/numkong/dots/graniteamx.h +733 -0
  175. package/numkong/include/numkong/dots/haswell.h +310 -0
  176. package/numkong/include/numkong/dots/icelake.h +180 -0
  177. package/numkong/include/numkong/dots/loongsonasx.h +176 -0
  178. package/numkong/include/numkong/dots/neon.h +123 -0
  179. package/numkong/include/numkong/dots/neonbfdot.h +59 -0
  180. package/numkong/include/numkong/dots/neonfhm.h +96 -0
  181. package/numkong/include/numkong/dots/neonfp8.h +99 -0
  182. package/numkong/include/numkong/dots/neonsdot.h +144 -0
  183. package/numkong/include/numkong/dots/powervsx.h +194 -0
  184. package/numkong/include/numkong/dots/rvv.h +2593 -0
  185. package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
  186. package/numkong/include/numkong/dots/serial.h +2867 -0
  187. package/numkong/include/numkong/dots/sierra.h +100 -0
  188. package/numkong/include/numkong/dots/skylake.h +207 -0
  189. package/numkong/include/numkong/dots/sme.h +5041 -0
  190. package/numkong/include/numkong/dots/smebi32.h +477 -0
  191. package/numkong/include/numkong/dots/smef64.h +1328 -0
  192. package/numkong/include/numkong/dots/smehalf.h +47 -0
  193. package/numkong/include/numkong/dots/v128relaxed.h +317 -0
  194. package/numkong/include/numkong/dots.h +3110 -0
  195. package/numkong/include/numkong/dots.hpp +641 -0
  196. package/numkong/include/numkong/each/README.md +465 -0
  197. package/numkong/include/numkong/each/haswell.h +1658 -0
  198. package/numkong/include/numkong/each/icelake.h +272 -0
  199. package/numkong/include/numkong/each/neon.h +1138 -0
  200. package/numkong/include/numkong/each/neonbfdot.h +211 -0
  201. package/numkong/include/numkong/each/neonhalf.h +318 -0
  202. package/numkong/include/numkong/each/rvv.h +1121 -0
  203. package/numkong/include/numkong/each/sapphire.h +343 -0
  204. package/numkong/include/numkong/each/serial.h +282 -0
  205. package/numkong/include/numkong/each/skylake.h +1562 -0
  206. package/numkong/include/numkong/each/v128relaxed.h +562 -0
  207. package/numkong/include/numkong/each.h +2232 -0
  208. package/numkong/include/numkong/each.hpp +434 -0
  209. package/numkong/include/numkong/geospatial/README.md +147 -0
  210. package/numkong/include/numkong/geospatial/haswell.h +633 -0
  211. package/numkong/include/numkong/geospatial/neon.h +615 -0
  212. package/numkong/include/numkong/geospatial/rvv.h +701 -0
  213. package/numkong/include/numkong/geospatial/serial.h +309 -0
  214. package/numkong/include/numkong/geospatial/skylake.h +613 -0
  215. package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
  216. package/numkong/include/numkong/geospatial.h +453 -0
  217. package/numkong/include/numkong/geospatial.hpp +235 -0
  218. package/numkong/include/numkong/matrix.hpp +336 -0
  219. package/numkong/include/numkong/maxsim/README.md +187 -0
  220. package/numkong/include/numkong/maxsim/alder.h +511 -0
  221. package/numkong/include/numkong/maxsim/genoa.h +115 -0
  222. package/numkong/include/numkong/maxsim/haswell.h +553 -0
  223. package/numkong/include/numkong/maxsim/icelake.h +480 -0
  224. package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
  225. package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
  226. package/numkong/include/numkong/maxsim/serial.h +490 -0
  227. package/numkong/include/numkong/maxsim/sme.h +993 -0
  228. package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
  229. package/numkong/include/numkong/maxsim.h +571 -0
  230. package/numkong/include/numkong/maxsim.hpp +133 -0
  231. package/numkong/include/numkong/mesh/README.md +219 -0
  232. package/numkong/include/numkong/mesh/haswell.h +2013 -0
  233. package/numkong/include/numkong/mesh/neon.h +1821 -0
  234. package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
  235. package/numkong/include/numkong/mesh/rvv.h +936 -0
  236. package/numkong/include/numkong/mesh/serial.h +721 -0
  237. package/numkong/include/numkong/mesh/skylake.h +2344 -0
  238. package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
  239. package/numkong/include/numkong/mesh.h +666 -0
  240. package/numkong/include/numkong/mesh.hpp +701 -0
  241. package/numkong/include/numkong/numkong.h +78 -0
  242. package/numkong/include/numkong/numkong.hpp +58 -0
  243. package/numkong/include/numkong/probability/README.md +177 -0
  244. package/numkong/include/numkong/probability/haswell.h +267 -0
  245. package/numkong/include/numkong/probability/neon.h +255 -0
  246. package/numkong/include/numkong/probability/rvv.h +414 -0
  247. package/numkong/include/numkong/probability/serial.h +181 -0
  248. package/numkong/include/numkong/probability/skylake.h +324 -0
  249. package/numkong/include/numkong/probability.h +380 -0
  250. package/numkong/include/numkong/probability.hpp +120 -0
  251. package/numkong/include/numkong/random.h +50 -0
  252. package/numkong/include/numkong/random.hpp +285 -0
  253. package/numkong/include/numkong/reduce/README.md +552 -0
  254. package/numkong/include/numkong/reduce/alder.h +636 -0
  255. package/numkong/include/numkong/reduce/genoa.h +201 -0
  256. package/numkong/include/numkong/reduce/haswell.h +3785 -0
  257. package/numkong/include/numkong/reduce/icelake.h +549 -0
  258. package/numkong/include/numkong/reduce/neon.h +3980 -0
  259. package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
  260. package/numkong/include/numkong/reduce/neonfhm.h +293 -0
  261. package/numkong/include/numkong/reduce/neonsdot.h +357 -0
  262. package/numkong/include/numkong/reduce/rvv.h +3533 -0
  263. package/numkong/include/numkong/reduce/serial.h +753 -0
  264. package/numkong/include/numkong/reduce/sierra.h +338 -0
  265. package/numkong/include/numkong/reduce/skylake.h +3794 -0
  266. package/numkong/include/numkong/reduce/sve.h +52 -0
  267. package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
  268. package/numkong/include/numkong/reduce.h +1582 -0
  269. package/numkong/include/numkong/reduce.hpp +778 -0
  270. package/numkong/include/numkong/scalar/README.md +89 -0
  271. package/numkong/include/numkong/scalar/haswell.h +122 -0
  272. package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
  273. package/numkong/include/numkong/scalar/neon.h +122 -0
  274. package/numkong/include/numkong/scalar/neonhalf.h +70 -0
  275. package/numkong/include/numkong/scalar/powervsx.h +96 -0
  276. package/numkong/include/numkong/scalar/rvv.h +211 -0
  277. package/numkong/include/numkong/scalar/sapphire.h +74 -0
  278. package/numkong/include/numkong/scalar/serial.h +332 -0
  279. package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
  280. package/numkong/include/numkong/scalar.h +696 -0
  281. package/numkong/include/numkong/set/README.md +179 -0
  282. package/numkong/include/numkong/set/haswell.h +334 -0
  283. package/numkong/include/numkong/set/icelake.h +485 -0
  284. package/numkong/include/numkong/set/loongsonasx.h +181 -0
  285. package/numkong/include/numkong/set/neon.h +363 -0
  286. package/numkong/include/numkong/set/powervsx.h +326 -0
  287. package/numkong/include/numkong/set/rvv.h +226 -0
  288. package/numkong/include/numkong/set/rvvbb.h +117 -0
  289. package/numkong/include/numkong/set/serial.h +174 -0
  290. package/numkong/include/numkong/set/sve.h +187 -0
  291. package/numkong/include/numkong/set/v128relaxed.h +240 -0
  292. package/numkong/include/numkong/set.h +471 -0
  293. package/numkong/include/numkong/set.hpp +114 -0
  294. package/numkong/include/numkong/sets/README.md +149 -0
  295. package/numkong/include/numkong/sets/haswell.h +63 -0
  296. package/numkong/include/numkong/sets/icelake.h +66 -0
  297. package/numkong/include/numkong/sets/loongsonasx.h +52 -0
  298. package/numkong/include/numkong/sets/neon.h +61 -0
  299. package/numkong/include/numkong/sets/powervsx.h +65 -0
  300. package/numkong/include/numkong/sets/serial.h +43 -0
  301. package/numkong/include/numkong/sets/smebi32.h +1135 -0
  302. package/numkong/include/numkong/sets/v128relaxed.h +58 -0
  303. package/numkong/include/numkong/sets.h +382 -0
  304. package/numkong/include/numkong/sparse/README.md +156 -0
  305. package/numkong/include/numkong/sparse/icelake.h +463 -0
  306. package/numkong/include/numkong/sparse/neon.h +288 -0
  307. package/numkong/include/numkong/sparse/serial.h +117 -0
  308. package/numkong/include/numkong/sparse/sve2.h +504 -0
  309. package/numkong/include/numkong/sparse/turin.h +322 -0
  310. package/numkong/include/numkong/sparse.h +363 -0
  311. package/numkong/include/numkong/sparse.hpp +113 -0
  312. package/numkong/include/numkong/spatial/README.md +439 -0
  313. package/numkong/include/numkong/spatial/alder.h +604 -0
  314. package/numkong/include/numkong/spatial/diamond.h +240 -0
  315. package/numkong/include/numkong/spatial/genoa.h +222 -0
  316. package/numkong/include/numkong/spatial/haswell.h +979 -0
  317. package/numkong/include/numkong/spatial/icelake.h +1067 -0
  318. package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
  319. package/numkong/include/numkong/spatial/neon.h +846 -0
  320. package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
  321. package/numkong/include/numkong/spatial/neonfp8.h +258 -0
  322. package/numkong/include/numkong/spatial/neonsdot.h +429 -0
  323. package/numkong/include/numkong/spatial/powervsx.h +738 -0
  324. package/numkong/include/numkong/spatial/rvv.h +991 -0
  325. package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
  326. package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
  327. package/numkong/include/numkong/spatial/serial.h +347 -0
  328. package/numkong/include/numkong/spatial/sierra.h +516 -0
  329. package/numkong/include/numkong/spatial/skylake.h +605 -0
  330. package/numkong/include/numkong/spatial/sve.h +246 -0
  331. package/numkong/include/numkong/spatial/svebfdot.h +125 -0
  332. package/numkong/include/numkong/spatial/svehalf.h +136 -0
  333. package/numkong/include/numkong/spatial/svesdot.h +143 -0
  334. package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
  335. package/numkong/include/numkong/spatial.h +1681 -0
  336. package/numkong/include/numkong/spatial.hpp +183 -0
  337. package/numkong/include/numkong/spatials/README.md +580 -0
  338. package/numkong/include/numkong/spatials/alder.h +94 -0
  339. package/numkong/include/numkong/spatials/diamond.h +82 -0
  340. package/numkong/include/numkong/spatials/genoa.h +94 -0
  341. package/numkong/include/numkong/spatials/graniteamx.h +173 -0
  342. package/numkong/include/numkong/spatials/haswell.h +219 -0
  343. package/numkong/include/numkong/spatials/icelake.h +113 -0
  344. package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
  345. package/numkong/include/numkong/spatials/neon.h +109 -0
  346. package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
  347. package/numkong/include/numkong/spatials/neonfhm.h +92 -0
  348. package/numkong/include/numkong/spatials/neonfp8.h +111 -0
  349. package/numkong/include/numkong/spatials/neonsdot.h +143 -0
  350. package/numkong/include/numkong/spatials/powervsx.h +153 -0
  351. package/numkong/include/numkong/spatials/rvv.h +1976 -0
  352. package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
  353. package/numkong/include/numkong/spatials/serial.h +248 -0
  354. package/numkong/include/numkong/spatials/sierra.h +96 -0
  355. package/numkong/include/numkong/spatials/skylake.h +184 -0
  356. package/numkong/include/numkong/spatials/sme.h +1927 -0
  357. package/numkong/include/numkong/spatials/smef64.h +483 -0
  358. package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
  359. package/numkong/include/numkong/spatials.h +3374 -0
  360. package/numkong/include/numkong/spatials.hpp +509 -0
  361. package/numkong/include/numkong/tensor.hpp +1981 -0
  362. package/numkong/include/numkong/trigonometry/README.md +184 -0
  363. package/numkong/include/numkong/trigonometry/haswell.h +653 -0
  364. package/numkong/include/numkong/trigonometry/neon.h +638 -0
  365. package/numkong/include/numkong/trigonometry/rvv.h +700 -0
  366. package/numkong/include/numkong/trigonometry/serial.h +703 -0
  367. package/numkong/include/numkong/trigonometry/skylake.h +725 -0
  368. package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
  369. package/numkong/include/numkong/trigonometry.h +467 -0
  370. package/numkong/include/numkong/trigonometry.hpp +166 -0
  371. package/numkong/include/numkong/types.h +1695 -0
  372. package/numkong/include/numkong/types.hpp +6027 -0
  373. package/numkong/include/numkong/vector.hpp +766 -0
  374. package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
  375. package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
  376. package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
  377. package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
  378. package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
  379. package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
  380. package/numkong/javascript/README.md +254 -0
  381. package/numkong/javascript/node-gyp-build.d.ts +4 -0
  382. package/numkong/javascript/numkong-browser.ts +40 -0
  383. package/numkong/javascript/numkong-wasm.ts +750 -0
  384. package/numkong/javascript/numkong.c +712 -0
  385. package/numkong/javascript/numkong.ts +613 -0
  386. package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
  387. package/numkong/javascript/tsconfig-cjs.json +13 -0
  388. package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
  389. package/numkong/javascript/types.ts +784 -0
  390. package/numkong/numkong.gypi +104 -0
  391. package/numkong/package.json +108 -0
  392. package/numkong/probes/arm_neon.c +8 -0
  393. package/numkong/probes/arm_neon_bfdot.c +9 -0
  394. package/numkong/probes/arm_neon_fhm.c +9 -0
  395. package/numkong/probes/arm_neon_half.c +8 -0
  396. package/numkong/probes/arm_neon_sdot.c +9 -0
  397. package/numkong/probes/arm_neonfp8.c +9 -0
  398. package/numkong/probes/arm_sme.c +16 -0
  399. package/numkong/probes/arm_sme2.c +16 -0
  400. package/numkong/probes/arm_sme2p1.c +16 -0
  401. package/numkong/probes/arm_sme_bf16.c +16 -0
  402. package/numkong/probes/arm_sme_bi32.c +16 -0
  403. package/numkong/probes/arm_sme_f64.c +16 -0
  404. package/numkong/probes/arm_sme_fa64.c +14 -0
  405. package/numkong/probes/arm_sme_half.c +16 -0
  406. package/numkong/probes/arm_sme_lut2.c +15 -0
  407. package/numkong/probes/arm_sve.c +18 -0
  408. package/numkong/probes/arm_sve2.c +20 -0
  409. package/numkong/probes/arm_sve2p1.c +18 -0
  410. package/numkong/probes/arm_sve_bfdot.c +20 -0
  411. package/numkong/probes/arm_sve_half.c +18 -0
  412. package/numkong/probes/arm_sve_sdot.c +21 -0
  413. package/numkong/probes/loongarch_lasx.c +12 -0
  414. package/numkong/probes/power_vsx.c +12 -0
  415. package/numkong/probes/probe.js +127 -0
  416. package/numkong/probes/riscv_rvv.c +14 -0
  417. package/numkong/probes/riscv_rvv_bb.c +15 -0
  418. package/numkong/probes/riscv_rvv_bf16.c +17 -0
  419. package/numkong/probes/riscv_rvv_half.c +14 -0
  420. package/numkong/probes/wasm_v128relaxed.c +11 -0
  421. package/numkong/probes/x86_alder.c +17 -0
  422. package/numkong/probes/x86_diamond.c +17 -0
  423. package/numkong/probes/x86_genoa.c +17 -0
  424. package/numkong/probes/x86_graniteamx.c +19 -0
  425. package/numkong/probes/x86_haswell.c +11 -0
  426. package/numkong/probes/x86_icelake.c +17 -0
  427. package/numkong/probes/x86_sapphire.c +16 -0
  428. package/numkong/probes/x86_sapphireamx.c +18 -0
  429. package/numkong/probes/x86_sierra.c +17 -0
  430. package/numkong/probes/x86_skylake.c +15 -0
  431. package/numkong/probes/x86_turin.c +17 -0
  432. package/numkong/rust/README.md +698 -0
  433. package/numkong/rust/capabilities.rs +96 -0
  434. package/numkong/rust/cast.rs +314 -0
  435. package/numkong/rust/curved.rs +391 -0
  436. package/numkong/rust/each.rs +2721 -0
  437. package/numkong/rust/geospatial.rs +343 -0
  438. package/numkong/rust/matrix.rs +5424 -0
  439. package/numkong/rust/maxsim.rs +540 -0
  440. package/numkong/rust/mesh.rs +837 -0
  441. package/numkong/rust/numkong.rs +409 -0
  442. package/numkong/rust/probability.rs +272 -0
  443. package/numkong/rust/reduce.rs +1249 -0
  444. package/numkong/rust/set.rs +194 -0
  445. package/numkong/rust/sparse.rs +513 -0
  446. package/numkong/rust/spatial.rs +1815 -0
  447. package/numkong/rust/tensor.rs +7565 -0
  448. package/numkong/rust/types.rs +3666 -0
  449. package/numkong/rust/vector.rs +1899 -0
  450. package/numkong/rustfmt.toml +2 -0
  451. package/numkong/swift/Matrix.swift +1388 -0
  452. package/numkong/swift/MaxSim.swift +151 -0
  453. package/numkong/swift/NumKong.swift +283 -0
  454. package/numkong/swift/Numerics.swift +329 -0
  455. package/numkong/swift/README.md +433 -0
  456. package/numkong/swift/Scalar.swift +741 -0
  457. package/numkong/swift/Tensor.swift +209 -0
  458. package/numkong/test/README.md +315 -0
  459. package/numkong/test/playwright.config.ts +16 -0
  460. package/numkong/test/swift/Test.swift +534 -0
  461. package/numkong/test/test-browser-bundle-runner.mjs +36 -0
  462. package/numkong/test/test-browser-bundle.html +188 -0
  463. package/numkong/test/test-browser-runner.mjs +43 -0
  464. package/numkong/test/test-browser.html +305 -0
  465. package/numkong/test/test-dtypes.mjs +453 -0
  466. package/numkong/test/test-wasm.mjs +267 -0
  467. package/numkong/test/test.cpp +442 -0
  468. package/numkong/test/test.hpp +580 -0
  469. package/numkong/test/test.mjs +363 -0
  470. package/numkong/test/test_base.py +1041 -0
  471. package/numkong/test/test_cast.cpp +242 -0
  472. package/numkong/test/test_cross.hpp +551 -0
  473. package/numkong/test/test_cross.py +467 -0
  474. package/numkong/test/test_cross_amx.cpp +50 -0
  475. package/numkong/test/test_cross_arm.cpp +225 -0
  476. package/numkong/test/test_cross_blas.cpp +354 -0
  477. package/numkong/test/test_cross_loongarch.cpp +90 -0
  478. package/numkong/test/test_cross_power.cpp +73 -0
  479. package/numkong/test/test_cross_rvv.cpp +109 -0
  480. package/numkong/test/test_cross_serial.cpp +181 -0
  481. package/numkong/test/test_cross_sme.cpp +148 -0
  482. package/numkong/test/test_cross_wasm.cpp +141 -0
  483. package/numkong/test/test_cross_x86.cpp +442 -0
  484. package/numkong/test/test_curved.cpp +182 -0
  485. package/numkong/test/test_curved.py +207 -0
  486. package/numkong/test/test_dot.cpp +353 -0
  487. package/numkong/test/test_dot.py +296 -0
  488. package/numkong/test/test_each.cpp +437 -0
  489. package/numkong/test/test_each.py +756 -0
  490. package/numkong/test/test_geospatial.cpp +155 -0
  491. package/numkong/test/test_geospatial.py +241 -0
  492. package/numkong/test/test_maxsim.cpp +138 -0
  493. package/numkong/test/test_maxsim.py +209 -0
  494. package/numkong/test/test_mesh.cpp +203 -0
  495. package/numkong/test/test_mesh.py +394 -0
  496. package/numkong/test/test_probability.cpp +136 -0
  497. package/numkong/test/test_probability.py +166 -0
  498. package/numkong/test/test_reduce.cpp +563 -0
  499. package/numkong/test/test_reduce.py +781 -0
  500. package/numkong/test/test_set.cpp +151 -0
  501. package/numkong/test/test_set.py +120 -0
  502. package/numkong/test/test_similarities.py +579 -0
  503. package/numkong/test/test_sparse.cpp +121 -0
  504. package/numkong/test/test_sparse.py +118 -0
  505. package/numkong/test/test_spatial.cpp +518 -0
  506. package/numkong/test/test_spatial.py +269 -0
  507. package/numkong/test/test_tensor.cpp +884 -0
  508. package/numkong/test/test_tensor.py +1417 -0
  509. package/numkong/test/test_trigonometry.cpp +156 -0
  510. package/numkong/test/test_trigonometry.py +180 -0
  511. package/package.json +7 -8
  512. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  513. package/prebuilds/linux-arm64/usearch.node +0 -0
  514. package/prebuilds/linux-x64/usearch.node +0 -0
  515. package/fp16/CMakeLists.txt +0 -176
  516. package/fp16/LICENSE +0 -11
  517. package/fp16/README.md +0 -20
  518. package/fp16/bench/alt-element.cc +0 -89
  519. package/fp16/bench/from-alt-array.cc +0 -175
  520. package/fp16/bench/from-ieee-array.cc +0 -399
  521. package/fp16/bench/ieee-element.cc +0 -272
  522. package/fp16/bench/to-alt-array.cc +0 -91
  523. package/fp16/bench/to-ieee-array.cc +0 -303
  524. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  525. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  526. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  527. package/fp16/configure.py +0 -65
  528. package/fp16/confu.yaml +0 -8
  529. package/fp16/include/fp16/__init__.py +0 -0
  530. package/fp16/include/fp16/avx.py +0 -50
  531. package/fp16/include/fp16/avx2.py +0 -53
  532. package/fp16/include/fp16/bitcasts.h +0 -92
  533. package/fp16/include/fp16/fp16.h +0 -451
  534. package/fp16/include/fp16/psimd.h +0 -131
  535. package/fp16/include/fp16.h +0 -11
  536. package/fp16/jni/Android.mk +0 -6
  537. package/fp16/jni/Application.mk +0 -4
  538. package/fp16/test/alt-from-fp32-value.cc +0 -498
  539. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  540. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  541. package/fp16/test/alt-to-fp32-value.cc +0 -348
  542. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  543. package/fp16/test/bitcasts.cc +0 -56
  544. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  545. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  546. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  547. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  548. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  549. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  550. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  551. package/fp16/test/peachpy/stubs.py +0 -38
  552. package/fp16/test/tables.cc +0 -530
  553. package/fp16/test/tables.h +0 -13
  554. package/fp16/third-party/THHalf.h +0 -92
  555. package/fp16/third-party/eigen-half.h +0 -170
  556. package/fp16/third-party/float16-compressor.h +0 -80
  557. package/fp16/third-party/half.hpp +0 -2916
  558. package/fp16/third-party/npy-halffloat.h +0 -328
  559. package/simsimd/.git-blame-ignore-revs +0 -2
  560. package/simsimd/CONTRIBUTING.md +0 -321
  561. package/simsimd/Cargo.toml +0 -49
  562. package/simsimd/MANIFEST.in +0 -4
  563. package/simsimd/Package.swift +0 -28
  564. package/simsimd/README.md +0 -1493
  565. package/simsimd/binding.gyp +0 -35
  566. package/simsimd/build.rs +0 -70
  567. package/simsimd/c/lib.c +0 -374
  568. package/simsimd/include/module.modulemap +0 -4
  569. package/simsimd/include/simsimd/binary.h +0 -486
  570. package/simsimd/include/simsimd/curved.h +0 -1541
  571. package/simsimd/include/simsimd/dot.h +0 -1853
  572. package/simsimd/include/simsimd/elementwise.h +0 -2465
  573. package/simsimd/include/simsimd/geospatial.h +0 -43
  574. package/simsimd/include/simsimd/mesh.h +0 -69
  575. package/simsimd/include/simsimd/probability.h +0 -606
  576. package/simsimd/include/simsimd/simsimd.h +0 -2567
  577. package/simsimd/include/simsimd/sparse.h +0 -1384
  578. package/simsimd/include/simsimd/spatial.h +0 -2335
  579. package/simsimd/include/simsimd/types.h +0 -666
  580. package/simsimd/javascript/fallback.ts +0 -233
  581. package/simsimd/javascript/lib.c +0 -125
  582. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  583. package/simsimd/javascript/simsimd.ts +0 -179
  584. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  585. package/simsimd/package-lock.json +0 -1761
  586. package/simsimd/package.json +0 -61
  587. package/simsimd/rust/lib.rs +0 -1821
  588. package/simsimd/scripts/bench.cxx +0 -1170
  589. package/simsimd/scripts/bench.ipynb +0 -187
  590. package/simsimd/scripts/bench.js +0 -127
  591. package/simsimd/scripts/bench.rs +0 -876
  592. package/simsimd/scripts/bench_vectors.py +0 -734
  593. package/simsimd/scripts/bench_vectors_live.py +0 -213
  594. package/simsimd/scripts/test.c +0 -187
  595. package/simsimd/scripts/test.mjs +0 -220
  596. package/simsimd/scripts/test.py +0 -1505
  597. package/simsimd/swift/SimSIMD.swift +0 -149
  598. package/simsimd/swift/Test.swift +0 -128
  599. /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
  600. /package/{simsimd → numkong}/LICENSE +0 -0
  601. /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
  602. /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
@@ -0,0 +1,209 @@
1
+ // Tensor.swift
2
+ // NumKong
3
+ //
4
+ // Created by Ash Vardanian on March 14, 2026.
5
+ //
6
+
7
+ import CNumKong
8
+
9
+ // MARK: - Owning Tensor
10
+
11
+ /// Owning, row-major dense matrix that deallocates its memory on `deinit`.
12
+ public final class Tensor<Element>: @unchecked Sendable {
13
+ @usableFromInline
14
+ let rawPointer: UnsafeMutablePointer<Element>
15
+ public let rows: Int
16
+ public let cols: Int
17
+ public var count: Int { rows * cols }
18
+ public var shape: (rows: Int, cols: Int) { (rows, cols) }
19
+
20
+ @usableFromInline
21
+ init(rawPointer: UnsafeMutablePointer<Element>, rows: Int, cols: Int) {
22
+ self.rawPointer = rawPointer
23
+ self.rows = rows
24
+ self.cols = cols
25
+ }
26
+
27
+ deinit {
28
+ rawPointer.deallocate()
29
+ }
30
+
31
+ /// Creates a tensor by copying elements from a flat array into owned memory.
32
+ public static func fromArray(_ data: [Element], rows: Int, cols: Int) throws -> Tensor {
33
+ guard rows > 0 && cols > 0 else { throw NumKongMatrixError.invalidDimensions }
34
+ guard data.count == rows * cols else { throw NumKongMatrixError.outputShapeMismatch }
35
+ let ptr = UnsafeMutablePointer<Element>.allocate(capacity: rows * cols)
36
+ data.withUnsafeBufferPointer { src in
37
+ ptr.initialize(from: src.baseAddress!, count: rows * cols)
38
+ }
39
+ return Tensor(rawPointer: ptr, rows: rows, cols: cols)
40
+ }
41
+
42
+ /// Creates a tensor filled with a repeating value.
43
+ public static func full(rows: Int, cols: Int, value: Element) throws -> Tensor {
44
+ guard rows > 0 && cols > 0 else { throw NumKongMatrixError.invalidDimensions }
45
+ let ptr = UnsafeMutablePointer<Element>.allocate(capacity: rows * cols)
46
+ ptr.initialize(repeating: value, count: rows * cols)
47
+ return Tensor(rawPointer: ptr, rows: rows, cols: cols)
48
+ }
49
+
50
+ @inlinable
51
+ /// Returns a non-owning immutable view of this tensor's storage.
52
+ public func view() -> MatrixView<Element> {
53
+ MatrixView(baseAddress: UnsafePointer(rawPointer), rows: rows, cols: cols)
54
+ }
55
+
56
+ @inlinable
57
+ /// Returns a non-owning mutable view of this tensor's storage.
58
+ public func span() -> MatrixSpan<Element> {
59
+ MatrixSpan(baseAddress: rawPointer, rows: rows, cols: cols)
60
+ }
61
+
62
+ @inlinable
63
+ public subscript(row: Int, col: Int) -> Element {
64
+ get { rawPointer[row * cols + col] }
65
+ set { rawPointer[row * cols + col] = newValue }
66
+ }
67
+
68
+ @inlinable
69
+ /// Returns a buffer pointer to the elements of row `i`.
70
+ public func row(_ i: Int) -> UnsafeBufferPointer<Element> {
71
+ UnsafeBufferPointer(start: UnsafePointer(rawPointer) + i * cols, count: cols)
72
+ }
73
+ }
74
+
75
+ // MARK: - Zero-initialized Tensor
76
+
77
+ extension Tensor {
78
+ @usableFromInline
79
+ static func _zeroInitialized(rows: Int, cols: Int) throws -> Tensor {
80
+ guard rows > 0 && cols > 0 else { throw NumKongMatrixError.invalidDimensions }
81
+ let count = rows * cols
82
+ let ptr = UnsafeMutablePointer<Element>.allocate(capacity: count)
83
+ let raw = UnsafeMutableRawPointer(ptr)
84
+ raw.initializeMemory(as: UInt8.self, repeating: 0, count: count * MemoryLayout<Element>.stride)
85
+ return Tensor(rawPointer: ptr, rows: rows, cols: cols)
86
+ }
87
+ }
88
+
89
+ extension Tensor where Element: ExpressibleByIntegerLiteral {
90
+ /// Creates a zero-filled tensor.
91
+ public static func zeros(rows: Int, cols: Int) throws -> Tensor {
92
+ try full(rows: rows, cols: cols, value: 0)
93
+ }
94
+ }
95
+
96
+ // MARK: - Dots Extensions
97
+
98
+ extension Tensor where Element: NumKongDotsMatrixElement {
99
+ /// Packs this tensor into a kernel-optimized layout for batch dot products.
100
+ public func packForDots() throws -> PackedMatrix<Element> {
101
+ try PackedMatrix<Element>(packing: view())
102
+ }
103
+
104
+ /// Computes dot products between this tensor's rows and a packed matrix, returning an owned result.
105
+ public func dotsPacked(_ packed: PackedMatrix<Element>) throws -> Tensor<Element.DotsOutput> {
106
+ let result = try Tensor<Element.DotsOutput>._zeroInitialized(rows: rows, cols: packed.rows)
107
+ var rSpan = result.span()
108
+ try dots_packed(view(), packed, &rSpan)
109
+ return result
110
+ }
111
+
112
+ /// Computes the symmetric dot-product matrix for all row pairs, returning an owned result.
113
+ public func dotsSymmetric(rowStart: Int = 0, rowCount: Int? = nil) throws -> Tensor<Element.DotsOutput> {
114
+ let result = try Tensor<Element.DotsOutput>._zeroInitialized(rows: rows, cols: rows)
115
+ var rSpan = result.span()
116
+ try dots_symmetric(view(), &rSpan, rowStart: rowStart, rowCount: rowCount)
117
+ return result
118
+ }
119
+ }
120
+
121
+ // MARK: - Spatials Extensions
122
+
123
+ extension Tensor where Element: NumKongSpatialsMatrixElement {
124
+ /// Computes angular distances between this tensor's rows and a packed matrix.
125
+ public func angularsPacked(_ packed: PackedMatrix<Element>) throws -> Tensor<Element.SpatialOutput> {
126
+ let result = try Tensor<Element.SpatialOutput>._zeroInitialized(rows: rows, cols: packed.rows)
127
+ var rSpan = result.span()
128
+ try angulars_packed(view(), packed, &rSpan)
129
+ return result
130
+ }
131
+
132
+ /// Computes Euclidean distances between this tensor's rows and a packed matrix.
133
+ public func euclideansPacked(_ packed: PackedMatrix<Element>) throws -> Tensor<Element.SpatialOutput> {
134
+ let result = try Tensor<Element.SpatialOutput>._zeroInitialized(rows: rows, cols: packed.rows)
135
+ var rSpan = result.span()
136
+ try euclideans_packed(view(), packed, &rSpan)
137
+ return result
138
+ }
139
+
140
+ /// Computes the symmetric angular-distance matrix for all row pairs.
141
+ public func angularsSymmetric(rowStart: Int = 0, rowCount: Int? = nil) throws -> Tensor<Element.SpatialOutput> {
142
+ let result = try Tensor<Element.SpatialOutput>._zeroInitialized(rows: rows, cols: rows)
143
+ var rSpan = result.span()
144
+ try angulars_symmetric(view(), &rSpan, rowStart: rowStart, rowCount: rowCount)
145
+ return result
146
+ }
147
+
148
+ /// Computes the symmetric Euclidean-distance matrix for all row pairs.
149
+ public func euclideansSymmetric(rowStart: Int = 0, rowCount: Int? = nil) throws -> Tensor<Element.SpatialOutput> {
150
+ let result = try Tensor<Element.SpatialOutput>._zeroInitialized(rows: rows, cols: rows)
151
+ var rSpan = result.span()
152
+ try euclideans_symmetric(view(), &rSpan, rowStart: rowStart, rowCount: rowCount)
153
+ return result
154
+ }
155
+ }
156
+
157
+ // MARK: - Sets Extensions
158
+
159
+ extension Tensor where Element: NumKongSetsMatrixElement {
160
+ /// Computes Hamming distances between this tensor's rows and a packed matrix.
161
+ public func hammingsPacked(_ packed: PackedMatrix<Element>) throws -> Tensor<Element.HammingOutput> {
162
+ let result = try Tensor<Element.HammingOutput>._zeroInitialized(rows: rows, cols: packed.rows)
163
+ var rSpan = result.span()
164
+ try NumKong.hammings_packed(view(), packed, &rSpan)
165
+ return result
166
+ }
167
+
168
+ /// Computes the symmetric Hamming-distance matrix for all row pairs.
169
+ public func hammingsSymmetric(rowStart: Int = 0, rowCount: Int? = nil) throws -> Tensor<Element.HammingOutput> {
170
+ let result = try Tensor<Element.HammingOutput>._zeroInitialized(rows: rows, cols: rows)
171
+ var rSpan = result.span()
172
+ try NumKong.hammings_symmetric(view(), &rSpan, rowStart: rowStart, rowCount: rowCount)
173
+ return result
174
+ }
175
+
176
+ /// Computes Jaccard distances between this tensor's rows and a packed matrix.
177
+ public func jaccardsPacked(_ packed: PackedMatrix<Element>) throws -> Tensor<Element.JaccardOutput> {
178
+ let result = try Tensor<Element.JaccardOutput>._zeroInitialized(rows: rows, cols: packed.rows)
179
+ var rSpan = result.span()
180
+ try NumKong.jaccards_packed(view(), packed, &rSpan)
181
+ return result
182
+ }
183
+
184
+ /// Computes the symmetric Jaccard-distance matrix for all row pairs.
185
+ public func jaccardsSymmetric(rowStart: Int = 0, rowCount: Int? = nil) throws -> Tensor<Element.JaccardOutput> {
186
+ let result = try Tensor<Element.JaccardOutput>._zeroInitialized(rows: rows, cols: rows)
187
+ var rSpan = result.span()
188
+ try NumKong.jaccards_symmetric(view(), &rSpan, rowStart: rowStart, rowCount: rowCount)
189
+ return result
190
+ }
191
+ }
192
+
193
+ // MARK: - MaxSim Extensions
194
+
195
+ extension Tensor where Element: NumKongMaxSimElement {
196
+ /// Packs this tensor into a MaxSim-optimized layout for late-interaction scoring.
197
+ public func maxSimPack() throws -> MaxSimPackedMatrix<Element> {
198
+ try MaxSimPackedMatrix<Element>(packing: view())
199
+ }
200
+ }
201
+
202
+ // MARK: - PackedMatrix convenience from Tensor
203
+
204
+ extension PackedMatrix where Element: NumKongDotsMatrixElement {
205
+ /// Packs a tensor's storage into a kernel-optimized layout for batch dot products.
206
+ public convenience init(packing tensor: Tensor<Element>) throws {
207
+ try self.init(packing: tensor.view())
208
+ }
209
+ }
@@ -0,0 +1,315 @@
1
+ # NumKong Precision Tests
2
+
3
+ Custom test framework comparing NumKong kernels against high-precision `f118_t` double-double references.
4
+ Every kernel family has its own precision model with ULP-based error analysis.
5
+
6
+ ## C++
7
+
8
+ No GTest dependency — the framework is self-contained in `test.hpp`.
9
+
10
+ ### Building
11
+
12
+ ```sh
13
+ cmake -B build_release -D CMAKE_BUILD_TYPE=Release -D NK_BUILD_TEST=1
14
+ cmake --build build_release --config Release --parallel
15
+ build_release/nk_test
16
+ ```
17
+
18
+ To compile with BLAS cross-validation:
19
+
20
+ ```sh
21
+ cmake -B build_release -D CMAKE_BUILD_TYPE=Release -D NK_BUILD_TEST=1 -D NK_COMPARE_TO_BLAS=1
22
+ ```
23
+
24
+ Compiler requirements vary by ISA target — see [CONTRIBUTING.md](../CONTRIBUTING.md#compiler-requirements) for the full table.
25
+
26
+ ### Running
27
+
28
+ ```sh
29
+ build_release/nk_test --filter=dot # run only tests matching "dot"
30
+ build_release/nk_test --filter="dot|spatial" # regex filter
31
+ build_release/nk_test --assert # abort on first accuracy failure
32
+ build_release/nk_test --verbose # per-dimension ULP breakdown
33
+ build_release/nk_test --time-budget=5000 # 5 seconds per kernel (milliseconds)
34
+ ```
35
+
36
+ Foreign flag mapping for muscle-memory compatibility:
37
+
38
+ | Foreign Flag | Maps To |
39
+ | ---------------------------- | ------------------------------------------- |
40
+ | `--gtest_filter=<regex>` | forwards to `--filter=<regex>` with warning |
41
+ | `--benchmark_filter=<regex>` | forwards to `--filter=<regex>` with warning |
42
+ | `--benchmark_min_time=<N>s` | converts to ms and maps to `--time-budget` |
43
+
44
+ ### Environment Variables
45
+
46
+ | Variable | Default | Description |
47
+ | ------------------------ | ------------- | ---------------------------------------------------- |
48
+ | `NK_FILTER` | `.*` | Regex to filter tests by name |
49
+ | `NK_SEED` | `42` | RNG seed for reproducible inputs |
50
+ | `NK_BUDGET_SECS` | `1` | Time budget per kernel in seconds |
51
+ | `NK_DENSE_DIMENSIONS` | `1536` | Vector dimension for dot/spatial tests |
52
+ | `NK_CURVED_DIMENSIONS` | `64` | Vector dimension for curved tests |
53
+ | `NK_SPARSE_DIMENSIONS` | `256` | Vector dimension for sparse tests |
54
+ | `NK_MESH_POINTS` | `1000` | Point count for mesh tests |
55
+ | `NK_MATRIX_HEIGHT` | `1024` | GEMM M dimension |
56
+ | `NK_MATRIX_WIDTH` | `128` | GEMM N dimension |
57
+ | `NK_MATRIX_DEPTH` | `1536` | GEMM K dimension |
58
+ | `NK_MAX_COORD_ANGLE` | `180` | Maximum angle in degrees for geospatial tests |
59
+ | `NK_IN_QEMU` | unset | Relax accuracy thresholds for QEMU emulation |
60
+ | `NK_TEST_ASSERT` | `0` | Assert (abort) on failed accuracy checks |
61
+ | `NK_TEST_VERBOSE` | `0` | Show per-dimension ULP breakdown |
62
+ | `NK_ULP_THRESHOLD_F32` | `4` | Max allowed ULP distance for f32 |
63
+ | `NK_ULP_THRESHOLD_F16` | `32` | Max allowed ULP distance for f16 |
64
+ | `NK_ULP_THRESHOLD_BF16` | `256` | Max allowed ULP distance for bf16 |
65
+ | `NK_RANDOM_DISTRIBUTION` | `lognormal_k` | Distribution: `uniform_k`, `lognormal_k`, `cauchy_k` |
66
+ | `NO_COLOR` | unset | Disable colored output |
67
+ | `FORCE_COLOR` | unset | Force colored output even without TTY |
68
+
69
+ ### Precision Families
70
+
71
+ Each kernel is assigned a __comparison family__ that determines which error metrics are reported and what constitutes failure.
72
+ Families are defined in `test.hpp` as `comparison_family_t`.
73
+ All floating-point families report `max_abs`, `max_rel`, `mean_ulp`, `max_ulp`, and `exact` match counts; some also add `mean_abs` or `mean_rel`.
74
+
75
+ - __`exact_k`__ — integer and binary metrics: Hamming, Jaccard, set intersections, integer min/max.
76
+ Reports `max_dist`, `mean_dist`, `mismatch`, `exact`.
77
+ Fails on any `max_dist > 0`.
78
+ - __`narrow_arithmetic_k`__ — elementwise float ops: sum, scale, blend, fma, sin, cos, atan, cast.
79
+ Fails on `max_ulp > NK_ULP_THRESHOLD_{F32,F16,BF16}`.
80
+ - __`mixed_precision_reduction_k`__ — reductions and dot products: dot, angular, euclidean, sqeuclidean, reduce_moments, reduce_minmax.
81
+ Wider tolerance than `narrow_arithmetic_k` due to accumulation error.
82
+ - __`probability_k`__ — probability divergences: KL, Jensen-Shannon.
83
+ Also reports `mean_abs` and `mean_rel`.
84
+ - __`geospatial_k`__ — geographic distances: Haversine, Vincenty.
85
+ Also reports `mean_abs`.
86
+ - __`external_baseline_k`__ — cross-backend comparison against system BLAS — OpenBLAS, MKL, Accelerate.
87
+
88
+ ### Reference Baselines
89
+
90
+ C++ tests compare SIMD kernels against high-precision serial references.
91
+ The baseline type depends on the input dtype, selected by the `reference_for<input, result>` template in `test.hpp`.
92
+
93
+ - __f32 and f64 inputs__ use `f118_t` — a double-double type with ~103-bit mantissa, defined in `types.hpp`.
94
+ Two `double` values track a high and low component, capturing rounding errors that a single `double` would lose.
95
+ This is critical because f32 kernels use f64 accumulators internally — testing against plain f64 would not catch accumulation drift.
96
+ - __Complex f32c and f64c inputs__ use `f118c_t` — a pair of `f118_t` for real and imaginary parts.
97
+ - __Half-precision, mini-floats, and integers__ — f16, bf16, e4m3, e5m2, i8, u8, etc. — use plain `f64_t`.
98
+ These types have at most 10-bit mantissas, so f64's 52-bit mantissa already provides >40 bits of headroom.
99
+ - __Complex halfs__ — f16c, bf16c — use `f64c_t` for the same reason.
100
+
101
+ ### WASM
102
+
103
+ __Emscripten__
104
+
105
+ ```sh
106
+ source ~/emsdk/emsdk_env.sh
107
+ cmake -B build-wasm -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasm.cmake -DNK_BUILD_TEST=1
108
+ cmake --build build-wasm --parallel
109
+ ```
110
+
111
+ For wasm64 — Memory64:
112
+
113
+ ```sh
114
+ cmake -B build-wasm64 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasm64.cmake -DNK_BUILD_TEST=1
115
+ cmake --build build-wasm64 --parallel
116
+ ```
117
+
118
+ __WASI__
119
+
120
+ ```sh
121
+ export WASI_SDK_PATH=~/wasi-sdk-24.0-x86_64-linux
122
+ cmake -B build-wasi -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-wasi.cmake -DNK_BUILD_TEST=1
123
+ cmake --build build-wasi --parallel
124
+ ```
125
+
126
+ __Running WASM Tests__
127
+
128
+ ```sh
129
+ wasmtime run -W simd=y,relaxed-simd=y,threads=y,shared-memory=y -S threads=y,inherit-env=y ./build-wasi/nk_test.wasm
130
+ wasmer run --enable-simd --enable-relaxed-simd ./build-wasi/nk_test.wasm
131
+ node ./build-wasm/nk_test.js
132
+ ```
133
+
134
+ __Memory Model__
135
+
136
+ The toolchain files configure memory limits appropriate for each target:
137
+
138
+ | Target | Initial Memory | Max Memory | Pointer Width | Emscripten Version |
139
+ | ------ | -------------- | ---------- | ------------- | ------------------ |
140
+ | wasm32 | 64 MB | 2 GB | 32-bit | 3.1.27+ |
141
+ | wasm64 | 256 MB | 16 GB | 64-bit | 3.1.35+ |
142
+ | WASI | — | 256 MB | 32-bit | — |
143
+
144
+ All three targets enable `-msimd128` and `-mrelaxed-simd` automatically.
145
+ Stack size is 5 MB across all Emscripten targets.
146
+ WASI builds use `wasm32-wasip1-threads` with shared memory and `-pthread` for threading support.
147
+
148
+ __SIMD and Relaxed SIMD Support__
149
+
150
+ All WASM builds require fixed-width SIMD — 128-bit `v128`.
151
+ Relaxed SIMD instructions like `f32x4.relaxed_madd` and fused dot-product are used when available — the toolchain enables them unconditionally and the WASI test runner probes for support at startup via `WebAssembly.validate()`.
152
+
153
+ Known-good minimum versions: Chrome 114+, Firefox 120+, Node.js 20+, Wasmtime 14+.
154
+ Safari supports `v128` SIMD from 16.4 but has incomplete Relaxed SIMD coverage; Memory64 is not yet available in Safari or Wasmer.
155
+ For up-to-date engine support, see [WebAssembly Roadmap](https://webassembly.org/features/) and [caniuse Relaxed SIMD](https://caniuse.com/wasm-relaxed-simd).
156
+
157
+ ### Cross-Compilation
158
+
159
+ NumKong ships 8 toolchain files in `cmake/` for cross-compiling to non-native targets.
160
+ Tests run transparently under QEMU via `CMAKE_CROSSCOMPILING_EMULATOR`.
161
+ Set `NK_IN_QEMU=1` to relax half-precision accuracy thresholds under emulation.
162
+
163
+ __ARM64 Linux__
164
+
165
+ ```sh
166
+ cmake -B build_arm64 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64-gnu.cmake \
167
+ -DNK_BUILD_TEST=1
168
+ cmake --build build_arm64 --parallel
169
+ NK_IN_QEMU=1 ctest --test-dir build_arm64 # runs under qemu-aarch64 -cpu max
170
+ ```
171
+
172
+ Default arch: `armv9-a+sve2+fp16+bf16+i8mm+dotprod+fp16fml`.
173
+
174
+ __RISC-V 64 with GCC__
175
+
176
+ ```sh
177
+ export RISCV_TOOLCHAIN_PATH=/path/to/riscv-gnu-toolchain # optional
178
+ # export RISCV_SYSROOT=/path/to/riscv-sysroot # optional override
179
+ cmake -B build_riscv -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-riscv64-gnu.cmake \
180
+ -DNK_BUILD_TEST=1
181
+ cmake --build build_riscv --parallel
182
+ NK_IN_QEMU=1 ctest --test-dir build_riscv # runs under qemu-riscv64 -cpu max
183
+ ```
184
+
185
+ Default arch: `rv64gcv_zvfh_zvfbfwma_zvbb`.
186
+
187
+ __RISC-V 64 with LLVM__
188
+
189
+ ```sh
190
+ export RISCV_SYSROOT=/path/to/riscv-sysroot
191
+ export LLVM_ROOT=/path/to/llvm # optional
192
+ cmake -B build_riscv_llvm -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-riscv64-llvm.cmake \
193
+ -DNK_BUILD_TEST=1
194
+ cmake --build build_riscv_llvm --parallel
195
+ NK_IN_QEMU=1 ctest --test-dir build_riscv_llvm
196
+ ```
197
+
198
+ __Android ARM64__
199
+
200
+ ```sh
201
+ cmake -B build_android -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-android-arm64.cmake \
202
+ -DNK_BUILD_TEST=1
203
+ cmake --build build_android --parallel
204
+ adb push build_android/nk_test /data/local/tmp/
205
+ adb shell /data/local/tmp/nk_test
206
+ ```
207
+
208
+ ## Rust
209
+
210
+ ```sh
211
+ cargo test -p numkong
212
+ cargo test -p numkong -- --nocapture # with output
213
+ cargo test -p numkong --all-features # all optional features
214
+ cargo check -p numkong --no-default-features # no-std compatibility
215
+ ```
216
+
217
+ ### WASM via Wasmtime
218
+
219
+ The `wasm-runtime` feature embeds a Wasmtime runtime to test WASM modules from within `cargo test`.
220
+
221
+ ```sh
222
+ cargo test -p numkong --features wasm-runtime -- wasm_runtime
223
+ ```
224
+
225
+ ## Python
226
+
227
+ ```sh
228
+ pip install -e .
229
+ pip install pytest pytest-repeat pytest-randomly numpy scipy ml_dtypes tabulate
230
+ pytest test/ -s -x -Wd
231
+ ```
232
+
233
+ Optional dependencies for extended test coverage:
234
+
235
+ | Package | What it unlocks |
236
+ | ----------- | ------------------------------------------------------- |
237
+ | `numpy` | Array interop, cdist, custom dtype registration |
238
+ | `scipy` | Cross-validation against `scipy.spatial.distance` |
239
+ | `ml_dtypes` | `__array_interface__` fallback for bfloat16 / fp8 / fp6 |
240
+ | `tabulate` | Formatted precision report tables |
241
+
242
+ Tests that require a missing optional dependency are skipped automatically.
243
+
244
+ ```sh
245
+ pytest test/ -s -x -Wd -k dot # filter by name
246
+ pytest test/ -s -x -Wd -k "dot or spatial"
247
+ ```
248
+
249
+ ### Environment Variables
250
+
251
+ | Variable | Default | Description |
252
+ | ---------------------- | ---------------- | --------------------------------------- |
253
+ | `NK_DENSE_DIMENSIONS` | `1,2,3,...,1536` | Comma-separated vector dimensions |
254
+ | `NK_CURVED_DIMENSIONS` | `11,97` | Dimensions for curved-space tests |
255
+ | `NK_MATRIX_HEIGHT` | `1024` | GEMM M dimension |
256
+ | `NK_MATRIX_WIDTH` | `128` | GEMM N dimension |
257
+ | `NK_MATRIX_DEPTH` | `1536` | GEMM K dimension |
258
+ | `NK_SEED` | OS entropy | Deterministic seed for `np.random` |
259
+ | `NK_REPETITIONS` | `10` | Randomized test repeat count |
260
+ | `NK_IN_QEMU` | unset | Relax accuracy thresholds |
261
+ | `NK_SPARSE_DIMENSIONS` | `256` | Universe size for sparse tests |
262
+ | `NK_MESH_POINTS` | `100` | Point count for mesh alignment tests |
263
+ | `NK_MAX_COORD_ANGLE` | `180` | Maximum angle in degrees for geospatial |
264
+
265
+ The `pytest-repeat` plugin re-runs each test `NK_REPETITIONS` times with auto-seeding — each iteration gets a unique seed derived from the base `NK_SEED`, ensuring broader input coverage without sacrificing reproducibility.
266
+
267
+ ### Reference Baselines
268
+
269
+ Python tests use `decimal.Decimal` at 120-digit precision as ground truth for assertions.
270
+ Functions like `precise_inner()`, `precise_sqeuclidean()`, and `precise_angular()` convert each element to `Decimal` before accumulation, exceeding even `f118_t` accuracy.
271
+ A secondary NumPy baseline at native precision — f64 for floats, i64 for integers — is used for error statistics collection.
272
+
273
+ ## JavaScript
274
+
275
+ ```sh
276
+ npm test # Node.js native addon
277
+ ```
278
+
279
+ ### WASM Runtimes
280
+
281
+ JavaScript tests support multiple WASM runtimes via the `NK_RUNTIME` environment variable.
282
+
283
+ ```sh
284
+ NK_RUNTIME=emscripten node --test test/test-wasm.mjs # Emscripten 32-bit
285
+ NK_RUNTIME=emscripten64 node --test test/test-wasm.mjs # Emscripten 64-bit, Memory64
286
+ NK_RUNTIME=wasi-node node --test test/test-wasm.mjs # WASI via Node.js
287
+ npx playwright test --config test/playwright.config.ts # Browser via Playwright
288
+ ```
289
+
290
+ ### Environment Variables
291
+
292
+ | Variable | Default | Description |
293
+ | --------------------- | --------------- | -------------------------------------------------- |
294
+ | `NK_RUNTIME` | `native` | Runtime: `emscripten`, `emscripten64`, `wasi-node` |
295
+ | `NK_SEED` | `42` | Random seed for reproducible test data |
296
+ | `NK_DENSE_DIMENSIONS` | `3,16,128,1536` | Comma-separated vector dimensions |
297
+
298
+ ## Swift
299
+
300
+ ```sh
301
+ swift build && swift test -v
302
+ ```
303
+
304
+ For iOS simulator testing:
305
+
306
+ ```sh
307
+ xcodebuild test -scheme NumKong -destination 'platform=iOS Simulator,name=iPhone 16'
308
+ ```
309
+
310
+ On Linux without a native Swift installation, use the official Docker image:
311
+
312
+ ```sh
313
+ sudo docker run --rm -v "$PWD:/workspace" -w /workspace swift:5.9 \
314
+ /bin/bash -cl "swift build -c release --static-swift-stdlib && swift test -c release --enable-test-discovery"
315
+ ```
@@ -0,0 +1,16 @@
1
+ import { defineConfig } from '@playwright/test';
2
+
3
+ export default defineConfig({
4
+ testDir: '.',
5
+ testMatch: ['test-browser-runner.mjs', 'test-browser-bundle-runner.mjs'],
6
+ timeout: 120000,
7
+ reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list',
8
+ use: {
9
+ baseURL: 'http://localhost:8888',
10
+ },
11
+ webServer: {
12
+ command: 'npx http-server .. -p 8888 -c-1 --silent',
13
+ port: 8888,
14
+ reuseExistingServer: !process.env.CI,
15
+ },
16
+ });