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,453 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @brief Comprehensive dtype tests for NumKong JavaScript API
4
+ * @file test/test-dtypes.mjs
5
+ * @author Claude & Ash Vardanian
6
+ * @date February 3, 2026
7
+ *
8
+ * Tests all functions with all compatible data types across multiple dimensions.
9
+ */
10
+
11
+ import { test } from "node:test";
12
+ import assert from "node:assert";
13
+ import build from "node-gyp-build";
14
+ import * as path from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = path.dirname(__filename);
19
+ const builddir = path.join(__dirname, ".."); // Root directory where binding.gyp is
20
+
21
+ // Load NumKong native addon
22
+ const numkong = build(builddir);
23
+
24
+ // Dtypes that require explicit dtype argument (not auto-detected from TypedArray type)
25
+ const CUSTOM_DTYPES = new Set(["f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2"]);
26
+
27
+ // Configuration from environment variables
28
+ const CONFIG = {
29
+ seed: parseInt(process.env.NK_SEED || "42"),
30
+ dimensions: process.env.NK_DENSE_DIMENSIONS
31
+ ? process.env.NK_DENSE_DIMENSIONS.split(",").map(Number)
32
+ : [3, 16, 128, 1536],
33
+ };
34
+
35
+ // Test matrix configuration
36
+ const TEST_MATRIX = {
37
+ functions: {
38
+ dot: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
39
+ inner: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
40
+ angular: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8"],
41
+ sqeuclidean: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
42
+ euclidean: ["f64", "f32", "f16", "bf16", "e4m3", "e5m2", "e2m3", "e3m2", "i8", "u8"],
43
+ hamming: ["u1"],
44
+ jaccard: ["u1"],
45
+ kullbackleibler: ["f64", "f32", "f16", "bf16"],
46
+ jensenshannon: ["f64", "f32", "f16", "bf16"],
47
+ },
48
+ dimensions: CONFIG.dimensions,
49
+ };
50
+
51
+ // Sub-byte packing ratio — mirrors nk_dimensions_per_value in types.h.
52
+ // A single storage byte holds this many logical elements for the given dtype.
53
+ function dimensionsPerValue(dtype) {
54
+ switch (dtype) {
55
+ case "u1":
56
+ return 8;
57
+ case "i4":
58
+ case "u4":
59
+ return 2;
60
+ default:
61
+ return 1;
62
+ }
63
+ }
64
+
65
+ // Round a logical dimension up to the nearest packed-value boundary.
66
+ function alignDimension(dimension, dtype) {
67
+ const dpv = dimensionsPerValue(dtype);
68
+ return Math.ceil(dimension / dpv) * dpv;
69
+ }
70
+
71
+ // Simple PRNG for reproducible tests
72
+ class Random {
73
+ constructor(seed) {
74
+ this.seed = seed;
75
+ }
76
+
77
+ next() {
78
+ this.seed = (this.seed * 1103515245 + 12345) & 0x7fffffff;
79
+ return this.seed / 0x7fffffff;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * @brief Generate test data for a specific dtype.
85
+ * For custom dtypes (f16, bf16, e4m3, e5m2, e2m3, e3m2), generates f32 source data
86
+ * and uses numkong.cast() to convert to the proper backing array type.
87
+ */
88
+ function generateTestData(dtype, length, seed = CONFIG.seed) {
89
+ const rng = new Random(seed);
90
+
91
+ switch (dtype) {
92
+ case "f64":
93
+ return Float64Array.from({ length }, () => rng.next() * 2 - 1);
94
+
95
+ case "f32":
96
+ return Float32Array.from({ length }, () => rng.next() * 2 - 1);
97
+
98
+ case "f16":
99
+ case "bf16": {
100
+ // 16-bit types: backing array is Uint16Array, convert from f32 via cast()
101
+ const src = Float32Array.from({ length }, () => rng.next() * 2 - 1);
102
+ const dst = new Uint16Array(length);
103
+ numkong.cast(src, "f32", dst, dtype);
104
+ return dst;
105
+ }
106
+
107
+ case "e4m3":
108
+ case "e5m2":
109
+ case "e2m3":
110
+ case "e3m2": {
111
+ // 8-bit types: backing array is Uint8Array, convert from f32 via cast()
112
+ const src = Float32Array.from({ length }, () => rng.next() * 2 - 1);
113
+ const dst = new Uint8Array(length);
114
+ numkong.cast(src, "f32", dst, dtype);
115
+ return dst;
116
+ }
117
+
118
+ case "i8":
119
+ return Int8Array.from({ length }, () => Math.floor(rng.next() * 256) - 128);
120
+
121
+ case "u8":
122
+ return Uint8Array.from({ length }, () => Math.floor(rng.next() * 256));
123
+
124
+ case "u1": {
125
+ const byteLength = Math.ceil(length / 8);
126
+ return Uint8Array.from({ length: byteLength }, () => Math.floor(rng.next() * 256));
127
+ }
128
+
129
+ default:
130
+ throw new Error(`Unknown dtype: ${dtype}`);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * @brief Generate positive probability-like data suitable for KLD/JSD.
136
+ * Values are in [0.1, 1.0] range to avoid precision issues with narrow types.
137
+ */
138
+ function generateProbabilityData(dtype, length, seed = CONFIG.seed) {
139
+ const rng = new Random(seed);
140
+
141
+ switch (dtype) {
142
+ case "f64":
143
+ return Float64Array.from({ length }, () => rng.next() * 0.9 + 0.1);
144
+
145
+ case "f32":
146
+ return Float32Array.from({ length }, () => rng.next() * 0.9 + 0.1);
147
+
148
+ case "f16":
149
+ case "bf16": {
150
+ const src = Float32Array.from({ length }, () => rng.next() * 0.9 + 0.1);
151
+ const dst = new Uint16Array(length);
152
+ numkong.cast(src, "f32", dst, dtype);
153
+ return dst;
154
+ }
155
+
156
+ default:
157
+ throw new Error(`Unsupported dtype for probability data: ${dtype}`);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * @brief Validate result is a valid number
163
+ */
164
+ function validateResult(result, funcName, dtype) {
165
+ assert.strictEqual(typeof result, "number", `${funcName}(${dtype}) should return a number`);
166
+ assert.ok(!isNaN(result), `${funcName}(${dtype}) should not return NaN`);
167
+ assert.ok(isFinite(result), `${funcName}(${dtype}) should return finite value`);
168
+ }
169
+
170
+ /**
171
+ * @brief Expected result ranges for different functions
172
+ */
173
+ function validateResultRange(result, funcName, dtype, dimension) {
174
+ switch (funcName) {
175
+ case "dot":
176
+ case "inner":
177
+ // Dot product range depends on dtype: i8 values go up to 127, u8 up to 255
178
+ const maxElement = dtype === "i8" ? 128 : dtype === "u8" ? 255 : 10;
179
+ assert.ok(
180
+ Math.abs(result) < dimension * maxElement * maxElement,
181
+ `${funcName}(${dtype}) result ${result} out of expected range`,
182
+ );
183
+ break;
184
+
185
+ case "angular":
186
+ // Cosine distance is in [0, π]
187
+ assert.ok(result >= 0 && result <= Math.PI, `${funcName}(${dtype}) should be in [0, π], got ${result}`);
188
+ break;
189
+
190
+ case "sqeuclidean":
191
+ // Squared Euclidean distance is non-negative
192
+ assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
193
+ break;
194
+
195
+ case "euclidean":
196
+ // Euclidean distance is non-negative
197
+ assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
198
+ break;
199
+
200
+ case "hamming":
201
+ // Hamming distance for binary vectors (in bits)
202
+ assert.ok(
203
+ result >= 0 && result <= dimension,
204
+ `${funcName}(${dtype}) should be in [0, ${dimension}], got ${result}`,
205
+ );
206
+ break;
207
+
208
+ case "jaccard":
209
+ // Jaccard distance is in [0, 1]
210
+ assert.ok(result >= 0 && result <= 1, `${funcName}(${dtype}) should be in [0, 1], got ${result}`);
211
+ break;
212
+
213
+ case "kullbackleibler":
214
+ // KL divergence is non-negative
215
+ assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
216
+ break;
217
+
218
+ case "jensenshannon":
219
+ // JS divergence is in [0, 1] for probability distributions
220
+ // For arbitrary vectors, just check non-negative and finite
221
+ assert.ok(result >= 0, `${funcName}(${dtype}) should be non-negative, got ${result}`);
222
+ assert.ok(isFinite(result), `${funcName}(${dtype}) should be finite, got ${result}`);
223
+ break;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * @brief Call a distance function, passing dtype as 3rd arg for custom types.
229
+ */
230
+ function callFunc(funcName, a, b, dtype) {
231
+ return CUSTOM_DTYPES.has(dtype) ? numkong[funcName](a, b, dtype) : numkong[funcName](a, b);
232
+ }
233
+
234
+ /**
235
+ * @brief Test determinism - same inputs should produce same output
236
+ */
237
+ function testDeterminism(funcName, dtype, dimension) {
238
+ const a = genData(funcName, dtype, dimension, 123);
239
+ const b = genData(funcName, dtype, dimension, 456);
240
+
241
+ const result1 = callFunc(funcName, a, b, dtype);
242
+ const result2 = callFunc(funcName, a, b, dtype);
243
+
244
+ assert.strictEqual(result1, result2, `${funcName}(${dtype}, dim=${dimension}) should be deterministic`);
245
+ }
246
+
247
+ /**
248
+ * @brief Test commutativity for symmetric functions
249
+ */
250
+ function testCommutativity(funcName, dtype, dimension) {
251
+ // Only symmetric functions
252
+ const symmetric = ["dot", "inner", "sqeuclidean", "euclidean", "hamming", "jaccard"];
253
+ if (!symmetric.includes(funcName)) {
254
+ return;
255
+ }
256
+
257
+ const a = genData(funcName, dtype, dimension, 789);
258
+ const b = genData(funcName, dtype, dimension, 101);
259
+
260
+ const result1 = callFunc(funcName, a, b, dtype);
261
+ const result2 = callFunc(funcName, b, a, dtype);
262
+
263
+ // For floating point, allow small tolerance
264
+ const tolerance = dtype.startsWith("f") ? 1e-6 : 0;
265
+ assert.ok(
266
+ Math.abs(result1 - result2) <= tolerance,
267
+ `${funcName}(${dtype}) should be commutative: ${result1} vs ${result2}`,
268
+ );
269
+ }
270
+
271
+ /**
272
+ * @brief Test self-distance properties
273
+ */
274
+ function testSelfDistance(funcName, dtype, dimension) {
275
+ const a = genData(funcName, dtype, dimension, 111);
276
+
277
+ const result = callFunc(funcName, a, a, dtype);
278
+
279
+ switch (funcName) {
280
+ case "dot":
281
+ case "inner":
282
+ // dot(a, a) should be positive (sum of squares)
283
+ assert.ok(result >= 0, `${funcName}(${dtype}) with same vector should be non-negative`);
284
+ break;
285
+
286
+ case "angular":
287
+ // angular(a, a) should be ~0 (same direction)
288
+ assert.ok(result < 0.01, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
289
+ break;
290
+
291
+ case "sqeuclidean":
292
+ case "euclidean":
293
+ // distance(a, a) should be 0
294
+ assert.ok(result < 0.01, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
295
+ break;
296
+
297
+ case "hamming":
298
+ // hamming(a, a) should be ~0 (allow floating point tolerance)
299
+ assert.ok(result < 1e-9, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
300
+ break;
301
+
302
+ case "jaccard":
303
+ // jaccard(a, a) should be 0
304
+ assert.ok(result < 0.01, `${funcName}(${dtype}) with same vector should be near 0, got ${result}`);
305
+ break;
306
+ }
307
+ }
308
+
309
+ // #region Main test suite
310
+
311
+ console.log("╔════════════════════════════════════════════════════════════════╗");
312
+ console.log("║ NumKong Comprehensive DType Test Suite ║");
313
+ console.log("╚════════════════════════════════════════════════════════════════╝\n");
314
+
315
+ let totalTests = 0;
316
+ for (const [funcName, dtypes] of Object.entries(TEST_MATRIX.functions)) {
317
+ totalTests += dtypes.length * TEST_MATRIX.dimensions.length * 4; // 4 tests per combo
318
+ }
319
+
320
+ console.log(`Seed: ${CONFIG.seed}, Dimensions: ${CONFIG.dimensions.join(", ")}`);
321
+ console.log(`Running ${totalTests} tests across:`);
322
+ console.log(` - ${Object.keys(TEST_MATRIX.functions).length} functions`);
323
+ console.log(` - ${new Set(Object.values(TEST_MATRIX.functions).flat()).size} data types`);
324
+ console.log(` - ${TEST_MATRIX.dimensions.length} dimension sizes\n`);
325
+
326
+ // Known issues to skip:
327
+ // - sqeuclidean/euclidean e4m3 < 16 dims: SIMD overread crash in kernel
328
+ // - kld/jsd f16: precision loss causes NaN/Infinity with test data
329
+ function isKnownBroken(funcName, dtype, dimension) {
330
+ if ((funcName === "sqeuclidean" || funcName === "euclidean") && dtype === "e4m3" && dimension < 16) return true;
331
+ if ((funcName === "kullbackleibler" || funcName === "jensenshannon") && dtype === "f16") return true;
332
+ return false;
333
+ }
334
+
335
+ // Divergence functions need probability-like (positive) test data
336
+ const DIVERGENCE_FUNCS = new Set(["kullbackleibler", "jensenshannon"]);
337
+ function genData(funcName, dtype, length, seed) {
338
+ return DIVERGENCE_FUNCS.has(funcName)
339
+ ? generateProbabilityData(dtype, length, seed)
340
+ : generateTestData(dtype, length, seed);
341
+ }
342
+
343
+ // Generate tests for each function, dtype, and dimension
344
+ for (const [funcName, supportedDtypes] of Object.entries(TEST_MATRIX.functions)) {
345
+ for (const dtype of supportedDtypes) {
346
+ for (const rawDimension of TEST_MATRIX.dimensions) {
347
+ const dimension = alignDimension(rawDimension, dtype);
348
+ if (isKnownBroken(funcName, dtype, dimension)) continue;
349
+
350
+ // Test 1: Basic functionality
351
+ test(`${funcName}(${dtype}, dim=${dimension}): basic`, () => {
352
+ const a = genData(funcName, dtype, dimension, CONFIG.seed);
353
+ const b = genData(funcName, dtype, dimension, CONFIG.seed + 1);
354
+
355
+ const result = callFunc(funcName, a, b, dtype);
356
+
357
+ validateResult(result, funcName, dtype);
358
+ validateResultRange(result, funcName, dtype, dimension);
359
+ });
360
+
361
+ // Test 2: Determinism
362
+ test(`${funcName}(${dtype}, dim=${dimension}): determinism`, () => {
363
+ testDeterminism(funcName, dtype, dimension);
364
+ });
365
+
366
+ // Test 3: Commutativity (for symmetric functions)
367
+ test(`${funcName}(${dtype}, dim=${dimension}): commutativity`, () => {
368
+ testCommutativity(funcName, dtype, dimension);
369
+ });
370
+
371
+ // Test 4: Self-distance properties
372
+ test(`${funcName}(${dtype}, dim=${dimension}): self-distance`, () => {
373
+ testSelfDistance(funcName, dtype, dimension);
374
+ });
375
+ }
376
+ }
377
+ }
378
+
379
+ // Additional edge case tests
380
+ test("Edge case: empty vectors", () => {
381
+ const a = new Float32Array(0);
382
+ const b = new Float32Array(0);
383
+
384
+ // Should handle gracefully (may throw or return 0)
385
+ try {
386
+ const result = numkong.dot(a, b);
387
+ assert.ok(typeof result === "number");
388
+ } catch (e) {
389
+ // Acceptable to throw on empty vectors
390
+ assert.ok(e.message.includes("length") || e.message.includes("empty"));
391
+ }
392
+ });
393
+
394
+ test("Edge case: mismatched lengths", () => {
395
+ const a = new Float32Array([1, 2, 3]);
396
+ const b = new Float32Array([4, 5]);
397
+
398
+ // Should throw error mentioning length or dimensionality
399
+ assert.throws(() => {
400
+ numkong.dot(a, b);
401
+ }, /(length|dimensionality)/i);
402
+ });
403
+
404
+ test("Edge case: zero vectors", () => {
405
+ const a = new Float32Array(100).fill(0);
406
+ const b = new Float32Array(100).fill(0);
407
+
408
+ const dot_result = numkong.dot(a, b);
409
+ assert.strictEqual(dot_result, 0);
410
+
411
+ const sqeuc_result = numkong.sqeuclidean(a, b);
412
+ assert.strictEqual(sqeuc_result, 0);
413
+ });
414
+
415
+ test("Conversion functions: f16 round-trip", () => {
416
+ const original = 3.14159;
417
+ const f16_bits = numkong.castF32ToF16(original);
418
+ const decoded = numkong.castF16ToF32(f16_bits);
419
+
420
+ // f16 has limited precision, allow some error
421
+ assert.ok(Math.abs(original - decoded) < 0.01);
422
+ });
423
+
424
+ test("Conversion functions: bf16 round-trip", () => {
425
+ const original = 2.71828;
426
+ const bf16_bits = numkong.castF32ToBF16(original);
427
+ const decoded = numkong.castBF16ToF32(bf16_bits);
428
+
429
+ // bf16 has limited precision
430
+ assert.ok(Math.abs(original - decoded) < 0.01);
431
+ });
432
+
433
+ test("Conversion functions: e4m3 round-trip", () => {
434
+ const original = 1.5;
435
+ const e4m3_bits = numkong.castF32ToE4M3(original);
436
+ const decoded = numkong.castE4M3ToF32(e4m3_bits);
437
+
438
+ // FP8 E4M3 has very limited precision
439
+ assert.ok(Math.abs(original - decoded) < 0.1);
440
+ });
441
+
442
+ test("Conversion functions: e5m2 round-trip", () => {
443
+ const original = 1.5;
444
+ const e5m2_bits = numkong.castF32ToE5M2(original);
445
+ const decoded = numkong.castE5M2ToF32(e5m2_bits);
446
+
447
+ // FP8 E5M2 has very limited precision
448
+ assert.ok(Math.abs(original - decoded) < 0.1);
449
+ });
450
+
451
+ // #endregion Main test suite
452
+
453
+ console.log("\n✅ All tests defined. Running with Node.js test runner...\n");