usearch 2.21.3 → 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 +235 -52
  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,712 @@
1
+ /**
2
+ * @brief JavaScript bindings for NumKong.
3
+ * @file javascript/numkong.c
4
+ * @author Ash Vardanian
5
+ * @date October 18, 2023
6
+ *
7
+ * @see NodeJS docs: https://nodejs.org/api/n-api.html
8
+ */
9
+
10
+ #include <string.h> // `strcmp` function
11
+
12
+ #if defined(NK_USE_OPENMP)
13
+ #include <omp.h>
14
+ #endif
15
+
16
+ #include <node_api.h> // `napi_*` functions — N-API v6+ for BigInt (Node ≥ 10.20)
17
+
18
+ #include <numkong/numkong.h> // `nk_*` functions — must be first to bring `_GNU_SOURCE`
19
+
20
+ #define NK_PARALLEL_PACKED_TILE 64
21
+ #define NK_PARALLEL_SYMMETRIC_TILE 32
22
+
23
+ /** @brief Global variable that caches the CPU capabilities, and is computed just once, when the module is loaded. */
24
+ nk_capability_t static_capabilities = nk_cap_serial_k;
25
+
26
+ #pragma region Helpers
27
+
28
+ /** @brief Parses a dtype string (e.g. "f32", "f16", "bf16") into a nk_dtype_t enum value. */
29
+ static nk_dtype_t parse_dtype_string(const char *str) {
30
+ if (strcmp(str, "f64") == 0) return nk_f64_k;
31
+ else if (strcmp(str, "f32") == 0) return nk_f32_k;
32
+ else if (strcmp(str, "f16") == 0) return nk_f16_k;
33
+ else if (strcmp(str, "bf16") == 0) return nk_bf16_k;
34
+ else if (strcmp(str, "e4m3") == 0) return nk_e4m3_k;
35
+ else if (strcmp(str, "e5m2") == 0) return nk_e5m2_k;
36
+ else if (strcmp(str, "e2m3") == 0) return nk_e2m3_k;
37
+ else if (strcmp(str, "e3m2") == 0) return nk_e3m2_k;
38
+ else if (strcmp(str, "i8") == 0) return nk_i8_k;
39
+ else if (strcmp(str, "u8") == 0) return nk_u8_k;
40
+ else if (strcmp(str, "i16") == 0) return nk_i16_k;
41
+ else if (strcmp(str, "u16") == 0) return nk_u16_k;
42
+ else if (strcmp(str, "i64") == 0) return nk_i64_k;
43
+ else if (strcmp(str, "u64") == 0) return nk_u64_k;
44
+ else if (strcmp(str, "u1") == 0) return nk_u1_k;
45
+ return nk_dtype_unknown_k;
46
+ }
47
+
48
+ /** @brief Validates that the N-API TypedArray type is compatible with the claimed dtype. */
49
+ static int is_compatible_napi_type(napi_typedarray_type napi_type, nk_dtype_t dtype) {
50
+ switch (dtype) {
51
+ case nk_f64_k: return napi_type == napi_float64_array;
52
+ case nk_f32_k: return napi_type == napi_float32_array;
53
+ case nk_f16_k:
54
+ case nk_bf16_k: return napi_type == napi_uint16_array;
55
+ case nk_e4m3_k:
56
+ case nk_e5m2_k:
57
+ case nk_e2m3_k:
58
+ case nk_e3m2_k:
59
+ case nk_u8_k:
60
+ case nk_u1_k: return napi_type == napi_uint8_array;
61
+ case nk_i8_k: return napi_type == napi_int8_array;
62
+ case nk_i16_k: return napi_type == napi_int16_array;
63
+ case nk_u16_k: return napi_type == napi_uint16_array;
64
+ default: return 0;
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @brief Converts an nk_scalar_buffer_t result to a JavaScript number.
70
+ * @param env N-API environment.
71
+ * @param result The scalar buffer containing the result.
72
+ * @param out_dtype The dtype of the value stored in the buffer.
73
+ * @return napi_value containing the result as a JavaScript Number, or NULL on error.
74
+ */
75
+ static napi_value nk_scalar_buffer_to_js_number(napi_env env, nk_scalar_buffer_t const *result, nk_dtype_t out_dtype) {
76
+ // i64/u64 must return BigInt since they may exceed Number.MAX_SAFE_INTEGER
77
+ if (out_dtype == nk_i64_k) {
78
+ napi_value js_result;
79
+ if (napi_create_bigint_int64(env, result->i64, &js_result) != napi_ok) return NULL;
80
+ return js_result;
81
+ }
82
+ if (out_dtype == nk_u64_k) {
83
+ napi_value js_result;
84
+ if (napi_create_bigint_uint64(env, result->u64, &js_result) != napi_ok) return NULL;
85
+ return js_result;
86
+ }
87
+ nk_f64c_t result_c;
88
+ nk_scalar_buffer_to_f64c(result, out_dtype, &result_c);
89
+ double result_f64 = result_c.real;
90
+ napi_value js_result;
91
+ if (napi_create_double(env, result_f64, &js_result) != napi_ok) return NULL;
92
+ return js_result;
93
+ }
94
+
95
+ /** @brief Returns the byte width for a given dtype. */
96
+ static inline size_t dtype_byte_width(nk_dtype_t dtype) { return nk_dtype_bits(dtype) / NK_BITS_PER_BYTE; }
97
+
98
+ /** @brief Returns the N-API typed array type for a given output dtype. */
99
+ static inline napi_typedarray_type napi_type_for_dtype(nk_dtype_t dtype) {
100
+ switch (dtype) {
101
+ case nk_f64_k: return napi_float64_array;
102
+ case nk_f32_k: return napi_float32_array;
103
+ case nk_i32_k: return napi_int32_array;
104
+ case nk_u32_k: return napi_uint32_array;
105
+ default: return napi_float32_array;
106
+ }
107
+ }
108
+
109
+ #pragma endregion Helpers
110
+
111
+ #pragma region Distance API
112
+
113
+ /** @brief Core distance computation — resolves dtype, dispatches kernel, converts result. */
114
+ static napi_value dense(napi_env env, napi_callback_info info, nk_kernel_kind_t kernel_kind, nk_dtype_t dtype) {
115
+ size_t argc = 3;
116
+ napi_value args[3];
117
+ napi_status status;
118
+
119
+ // Get callback info and ensure the argument count is correct (2 or 3 args)
120
+ status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
121
+ if (status != napi_ok || argc < 2 || argc > 3) {
122
+ napi_throw_error(env, NULL, "Expected 2 or 3 arguments: (a, b[, dtype])");
123
+ return NULL;
124
+ }
125
+
126
+ // Obtain the typed arrays from the arguments
127
+ void *data_a, *data_b;
128
+ size_t length_a, length_b;
129
+ napi_typedarray_type type_a, type_b;
130
+ napi_status status_a, status_b;
131
+ status_a = napi_get_typedarray_info(env, args[0], &type_a, &length_a, &data_a, NULL, NULL);
132
+ status_b = napi_get_typedarray_info(env, args[1], &type_b, &length_b, &data_b, NULL, NULL);
133
+ if (status_a != napi_ok || status_b != napi_ok || type_a != type_b || length_a != length_b) {
134
+ napi_throw_error(env, NULL, "Both arguments must be typed arrays of matching types and dimensionality");
135
+ return NULL;
136
+ }
137
+
138
+ // When dtype is unknown, try to resolve from optional 3rd argument or auto-detect
139
+ if (dtype == nk_dtype_unknown_k) {
140
+ if (argc == 3) {
141
+ // Parse explicit dtype string from 3rd argument
142
+ char dtype_str[16];
143
+ size_t str_len;
144
+ if (napi_get_value_string_utf8(env, args[2], dtype_str, sizeof(dtype_str), &str_len) != napi_ok) {
145
+ napi_throw_error(env, NULL, "Third argument must be a dtype string");
146
+ return NULL;
147
+ }
148
+ dtype = parse_dtype_string(dtype_str);
149
+ if (dtype == nk_dtype_unknown_k) {
150
+ napi_throw_error(env, NULL, "Unsupported dtype string");
151
+ return NULL;
152
+ }
153
+ if (!is_compatible_napi_type(type_a, dtype)) {
154
+ napi_throw_error(env, NULL, "TypedArray type is not compatible with the specified dtype");
155
+ return NULL;
156
+ }
157
+ }
158
+ else {
159
+ // Auto-detect from N-API TypedArray type (backward-compatible 4-type whitelist)
160
+ if (type_a != napi_float64_array && type_a != napi_float32_array && type_a != napi_int8_array &&
161
+ type_a != napi_uint8_array) {
162
+ napi_throw_error(
163
+ env, NULL,
164
+ "Only f64, f32, i8, u8 arrays are auto-detected; pass dtype string as 3rd argument " "for other " "types");
165
+ return NULL;
166
+ }
167
+ switch (type_a) {
168
+ case napi_float64_array: dtype = nk_f64_k; break;
169
+ case napi_float32_array: dtype = nk_f32_k; break;
170
+ case napi_int8_array: dtype = nk_i8_k; break;
171
+ case napi_uint8_array: dtype = nk_u8_k; break;
172
+ default: break;
173
+ }
174
+ }
175
+ }
176
+
177
+ nk_metric_dense_punned_t metric = NULL;
178
+ nk_capability_t capability = nk_cap_serial_k;
179
+ nk_find_kernel_punned(kernel_kind, dtype, static_capabilities, (nk_kernel_punned_t *)&metric, &capability);
180
+ if (!metric || !capability) {
181
+ napi_throw_error(env, NULL, "Unsupported dtype for given metric");
182
+ return NULL;
183
+ }
184
+
185
+ nk_dtype_t out_dtype = nk_kernel_output_dtype(kernel_kind, dtype);
186
+ if (out_dtype == nk_dtype_unknown_k) {
187
+ napi_throw_error(env, NULL, "Unsupported output dtype for given metric/input combination");
188
+ return NULL;
189
+ }
190
+
191
+ // Adjust dimensions for sub-byte packed types (e.g. Uint8Array with u1 dtype → bits)
192
+ nk_size_t to_bits = nk_dtype_bits(dtype);
193
+ size_t dimensions = (to_bits && to_bits < NK_BITS_PER_BYTE) ? length_a * NK_BITS_PER_BYTE / to_bits : length_a;
194
+
195
+ nk_scalar_buffer_t result;
196
+ metric(data_a, data_b, dimensions, &result);
197
+
198
+ return nk_scalar_buffer_to_js_number(env, &result, out_dtype);
199
+ }
200
+
201
+ /** @brief N-API entry for inner product (dot). */
202
+ napi_value api_ip(napi_env env, napi_callback_info info) {
203
+ return dense(env, info, nk_kernel_dot_k, nk_dtype_unknown_k);
204
+ }
205
+ /** @brief N-API entry for angular distance. */
206
+ napi_value api_angular(napi_env env, napi_callback_info info) {
207
+ return dense(env, info, nk_kernel_angular_k, nk_dtype_unknown_k);
208
+ }
209
+ /** @brief N-API entry for squared Euclidean distance. */
210
+ napi_value api_sqeuclidean(napi_env env, napi_callback_info info) {
211
+ return dense(env, info, nk_kernel_sqeuclidean_k, nk_dtype_unknown_k);
212
+ }
213
+ /** @brief N-API entry for Euclidean distance. */
214
+ napi_value api_euclidean(napi_env env, napi_callback_info info) {
215
+ return dense(env, info, nk_kernel_euclidean_k, nk_dtype_unknown_k);
216
+ }
217
+ /** @brief N-API entry for Kullback-Leibler divergence. */
218
+ napi_value api_kld(napi_env env, napi_callback_info info) {
219
+ return dense(env, info, nk_kernel_kld_k, nk_dtype_unknown_k);
220
+ }
221
+ /** @brief N-API entry for Jensen-Shannon distance. */
222
+ napi_value api_jsd(napi_env env, napi_callback_info info) {
223
+ return dense(env, info, nk_kernel_jsd_k, nk_dtype_unknown_k);
224
+ }
225
+ /** @brief N-API entry for Hamming distance. */
226
+ napi_value api_hamming(napi_env env, napi_callback_info info) { return dense(env, info, nk_kernel_hamming_k, nk_u1_k); }
227
+ /** @brief N-API entry for Jaccard distance. */
228
+ napi_value api_jaccard(napi_env env, napi_callback_info info) { return dense(env, info, nk_kernel_jaccard_k, nk_u1_k); }
229
+
230
+ #pragma endregion Distance API
231
+
232
+ #pragma region Capabilities API
233
+
234
+ /**
235
+ * @brief Returns the runtime-detected SIMD capabilities as a bitmask.
236
+ * @return BigInt bitmask of nk_capability_t flags (33 flags from NEON to SME2P1)
237
+ *
238
+ * This function exposes the cached capability bitmask to JavaScript users,
239
+ * allowing them to query what SIMD extensions are available at runtime.
240
+ * The capabilities are detected once at module load time and cached in static_capabilities.
241
+ */
242
+ napi_value api_get_capabilities(napi_env env, napi_callback_info info) {
243
+ napi_value result;
244
+ // Use cached capabilities from module load (static_capabilities set in Init())
245
+ napi_create_bigint_uint64(env, (uint64_t)static_capabilities, &result);
246
+ return result;
247
+ }
248
+
249
+ #pragma endregion Capabilities API
250
+
251
+ #pragma region Cast API
252
+
253
+ /** @brief Converts a single value from a narrow type to f32. Reads uint32 bits, returns double. */
254
+ static napi_value cast_to_f32(napi_env env, napi_callback_info info, nk_dtype_t src_dtype) {
255
+ size_t argc = 1;
256
+ napi_value args[1];
257
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
258
+ if (argc != 1) {
259
+ napi_throw_error(env, NULL, "Expected 1 argument");
260
+ return NULL;
261
+ }
262
+
263
+ uint32_t bits;
264
+ if (napi_get_value_uint32(env, args[0], &bits) != napi_ok) {
265
+ napi_throw_error(env, NULL, "Argument must be a number");
266
+ return NULL;
267
+ }
268
+
269
+ nk_f32_t f32_val;
270
+ nk_cast(&bits, src_dtype, 1, &f32_val, nk_f32_k);
271
+
272
+ napi_value result;
273
+ napi_create_double(env, (double)f32_val, &result);
274
+ return result;
275
+ }
276
+
277
+ /** @brief Converts a single f32 value to a narrow type. Reads double, returns uint32 bits. */
278
+ static napi_value cast_from_f32(napi_env env, napi_callback_info info, nk_dtype_t dst_dtype) {
279
+ size_t argc = 1;
280
+ napi_value args[1];
281
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
282
+ if (argc != 1) {
283
+ napi_throw_error(env, NULL, "Expected 1 argument");
284
+ return NULL;
285
+ }
286
+
287
+ double f32_dbl;
288
+ if (napi_get_value_double(env, args[0], &f32_dbl) != napi_ok) {
289
+ napi_throw_error(env, NULL, "Argument must be a number");
290
+ return NULL;
291
+ }
292
+
293
+ nk_f32_t f32_val = (nk_f32_t)f32_dbl;
294
+ uint32_t bits = 0;
295
+ nk_cast(&f32_val, nk_f32_k, 1, &bits, dst_dtype);
296
+
297
+ napi_value result;
298
+ napi_create_uint32(env, bits, &result);
299
+ return result;
300
+ }
301
+
302
+ /** @brief N-API entry for scalar f16-to-f32 conversion. */
303
+ napi_value api_cast_f16_to_f32(napi_env env, napi_callback_info info) { return cast_to_f32(env, info, nk_f16_k); }
304
+ /** @brief N-API entry for scalar f32-to-f16 conversion. */
305
+ napi_value api_cast_f32_to_f16(napi_env env, napi_callback_info info) { return cast_from_f32(env, info, nk_f16_k); }
306
+ /** @brief N-API entry for scalar bf16-to-f32 conversion. */
307
+ napi_value api_cast_bf16_to_f32(napi_env env, napi_callback_info info) { return cast_to_f32(env, info, nk_bf16_k); }
308
+ /** @brief N-API entry for scalar f32-to-bf16 conversion. */
309
+ napi_value api_cast_f32_to_bf16(napi_env env, napi_callback_info info) { return cast_from_f32(env, info, nk_bf16_k); }
310
+ /** @brief N-API entry for scalar e4m3-to-f32 conversion. */
311
+ napi_value api_cast_e4m3_to_f32(napi_env env, napi_callback_info info) { return cast_to_f32(env, info, nk_e4m3_k); }
312
+ /** @brief N-API entry for scalar f32-to-e4m3 conversion. */
313
+ napi_value api_cast_f32_to_e4m3(napi_env env, napi_callback_info info) { return cast_from_f32(env, info, nk_e4m3_k); }
314
+ /** @brief N-API entry for scalar e5m2-to-f32 conversion. */
315
+ napi_value api_cast_e5m2_to_f32(napi_env env, napi_callback_info info) { return cast_to_f32(env, info, nk_e5m2_k); }
316
+ /** @brief N-API entry for scalar f32-to-e5m2 conversion. */
317
+ napi_value api_cast_f32_to_e5m2(napi_env env, napi_callback_info info) { return cast_from_f32(env, info, nk_e5m2_k); }
318
+
319
+ /**
320
+ * @brief Buffer casting function using nk_cast.
321
+ * @param env N-API environment
322
+ * @param info Callback info containing 4 arguments:
323
+ * - src: source TypedArray
324
+ * - srcType: source dtype string
325
+ * - dst: destination TypedArray
326
+ * - dstType: destination dtype string
327
+ * @return null (modifies dst in place)
328
+ */
329
+ napi_value api_cast(napi_env env, napi_callback_info info) {
330
+ size_t argc = 4;
331
+ napi_value args[4];
332
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
333
+
334
+ if (argc != 4) {
335
+ napi_throw_error(env, NULL, "cast requires 4 arguments: (src, srcType, dst, dstType)");
336
+ return NULL;
337
+ }
338
+
339
+ // Get source and destination arrays
340
+ void *src_data, *dst_data;
341
+ size_t src_len, dst_len;
342
+ napi_typedarray_type src_type, dst_type;
343
+
344
+ napi_get_typedarray_info(env, args[0], &src_type, &src_len, &src_data, NULL, NULL);
345
+ napi_get_typedarray_info(env, args[2], &dst_type, &dst_len, &dst_data, NULL, NULL);
346
+
347
+ // Get dtype strings
348
+ char src_dtype_str[16], dst_dtype_str[16];
349
+ size_t str_len;
350
+ napi_get_value_string_utf8(env, args[1], src_dtype_str, sizeof(src_dtype_str), &str_len);
351
+ napi_get_value_string_utf8(env, args[3], dst_dtype_str, sizeof(dst_dtype_str), &str_len);
352
+
353
+ // Map dtype strings to nk_dtype_t
354
+ nk_dtype_t src_dtype = parse_dtype_string(src_dtype_str);
355
+ nk_dtype_t dst_dtype = parse_dtype_string(dst_dtype_str);
356
+
357
+ if (src_dtype == nk_dtype_unknown_k || dst_dtype == nk_dtype_unknown_k) {
358
+ napi_throw_error(env, NULL, "Unsupported dtype string");
359
+ return NULL;
360
+ }
361
+
362
+ // Perform conversion using nk_cast
363
+ nk_cast(src_data, src_dtype, src_len, dst_data, dst_dtype);
364
+
365
+ return NULL; // Modifies dst_data in place
366
+ }
367
+
368
+ #pragma endregion Cast API
369
+
370
+ #pragma region Packed API
371
+
372
+ /** @brief Query packed buffer byte count: dotsPackedSize(width, depth, dtype) → number */
373
+ static napi_value api_dots_packed_size(napi_env env, napi_callback_info info) {
374
+ size_t argc = 3;
375
+ napi_value args[3];
376
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
377
+ if (argc != 3) {
378
+ napi_throw_error(env, NULL, "dotsPackedSize requires 3 arguments: (width, depth, dtype)");
379
+ return NULL;
380
+ }
381
+
382
+ uint32_t width, depth;
383
+ napi_get_value_uint32(env, args[0], &width);
384
+ napi_get_value_uint32(env, args[1], &depth);
385
+
386
+ char dtype_str[16];
387
+ size_t str_len;
388
+ napi_get_value_string_utf8(env, args[2], dtype_str, sizeof(dtype_str), &str_len);
389
+ nk_dtype_t dtype = parse_dtype_string(dtype_str);
390
+ if (dtype == nk_dtype_unknown_k) {
391
+ napi_throw_error(env, NULL, "Unsupported dtype string");
392
+ return NULL;
393
+ }
394
+
395
+ nk_dots_packed_size_punned_t size_fn = NULL;
396
+ nk_capability_t cap = nk_cap_serial_k;
397
+ nk_find_kernel_punned(nk_kernel_dots_packed_size_k, dtype, static_capabilities, (nk_kernel_punned_t *)&size_fn,
398
+ &cap);
399
+ if (!size_fn) {
400
+ napi_throw_error(env, NULL, "dots_packed_size not available for this dtype");
401
+ return NULL;
402
+ }
403
+
404
+ nk_size_t byte_count = size_fn((nk_size_t)width, (nk_size_t)depth);
405
+
406
+ napi_value result;
407
+ napi_create_double(env, (double)byte_count, &result);
408
+ return result;
409
+ }
410
+
411
+ /** @brief Pack B matrix: dotsPack(data, width, depth, strideBytes, dtype) → { buffer, width, depth, byteLength } */
412
+ static napi_value api_dots_pack(napi_env env, napi_callback_info info) {
413
+ size_t argc = 5;
414
+ napi_value args[5];
415
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
416
+ if (argc != 5) {
417
+ napi_throw_error(env, NULL, "dotsPack requires 5 arguments: (data, width, depth, strideBytes, dtype)");
418
+ return NULL;
419
+ }
420
+
421
+ void *data;
422
+ size_t data_len;
423
+ napi_typedarray_type arr_type;
424
+ napi_get_typedarray_info(env, args[0], &arr_type, &data_len, &data, NULL, NULL);
425
+
426
+ uint32_t width, depth, stride_bytes;
427
+ napi_get_value_uint32(env, args[1], &width);
428
+ napi_get_value_uint32(env, args[2], &depth);
429
+ napi_get_value_uint32(env, args[3], &stride_bytes);
430
+
431
+ char dtype_str[16];
432
+ size_t str_len;
433
+ napi_get_value_string_utf8(env, args[4], dtype_str, sizeof(dtype_str), &str_len);
434
+ nk_dtype_t dtype = parse_dtype_string(dtype_str);
435
+ if (dtype == nk_dtype_unknown_k) {
436
+ napi_throw_error(env, NULL, "Unsupported dtype string");
437
+ return NULL;
438
+ }
439
+
440
+ // Get packed size
441
+ nk_dots_packed_size_punned_t size_fn = NULL;
442
+ nk_capability_t cap = nk_cap_serial_k;
443
+ nk_find_kernel_punned(nk_kernel_dots_packed_size_k, dtype, static_capabilities, (nk_kernel_punned_t *)&size_fn,
444
+ &cap);
445
+ if (!size_fn) {
446
+ napi_throw_error(env, NULL, "dots_packed_size not available for this dtype");
447
+ return NULL;
448
+ }
449
+ nk_size_t packed_byte_count = size_fn((nk_size_t)width, (nk_size_t)depth);
450
+
451
+ // Allocate V8-managed ArrayBuffer for packed data
452
+ void *packed_data = NULL;
453
+ napi_value arraybuffer;
454
+ if (napi_create_arraybuffer(env, packed_byte_count, &packed_data, &arraybuffer) != napi_ok) {
455
+ napi_throw_error(env, NULL, "Failed to allocate packed buffer");
456
+ return NULL;
457
+ }
458
+
459
+ // Pack
460
+ nk_dots_pack_punned_t pack_fn = NULL;
461
+ cap = nk_cap_serial_k;
462
+ nk_find_kernel_punned(nk_kernel_dots_pack_k, dtype, static_capabilities, (nk_kernel_punned_t *)&pack_fn, &cap);
463
+ if (!pack_fn) {
464
+ napi_throw_error(env, NULL, "dots_pack not available for this dtype");
465
+ return NULL;
466
+ }
467
+ pack_fn(data, (nk_size_t)width, (nk_size_t)depth, (nk_size_t)stride_bytes, packed_data);
468
+
469
+ // Return object { buffer, width, depth, byteLength }
470
+ napi_value result_obj;
471
+ napi_create_object(env, &result_obj);
472
+
473
+ napi_value js_width, js_depth, js_byte_length;
474
+ napi_create_uint32(env, width, &js_width);
475
+ napi_create_uint32(env, depth, &js_depth);
476
+ napi_create_double(env, (double)packed_byte_count, &js_byte_length);
477
+
478
+ napi_set_named_property(env, result_obj, "buffer", arraybuffer);
479
+ napi_set_named_property(env, result_obj, "width", js_width);
480
+ napi_set_named_property(env, result_obj, "depth", js_depth);
481
+ napi_set_named_property(env, result_obj, "byteLength", js_byte_length);
482
+
483
+ return result_obj;
484
+ }
485
+
486
+ /**
487
+ * @brief Shared dispatcher for packed operations (dots, angulars, euclideans).
488
+ * Args: TypedArray a, ArrayBuffer packed, TypedArray result, numbers height/width/depth/aStride/resultStride, string
489
+ * dtype
490
+ */
491
+ static napi_value api_packed_common(napi_env env, napi_callback_info info, nk_kernel_kind_t kernel_kind) {
492
+ size_t argc = 10;
493
+ napi_value args[10];
494
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
495
+ if (argc < 9 || argc > 10) {
496
+ napi_throw_error(env, NULL, "Packed operation requires 9-10 arguments (last is optional threads)");
497
+ return NULL;
498
+ }
499
+
500
+ // arg[0]: TypedArray a
501
+ void *a_data;
502
+ size_t a_len;
503
+ napi_typedarray_type a_type;
504
+ napi_get_typedarray_info(env, args[0], &a_type, &a_len, &a_data, NULL, NULL);
505
+
506
+ // arg[1]: ArrayBuffer packed
507
+ void *packed_data;
508
+ size_t packed_len;
509
+ napi_get_arraybuffer_info(env, args[1], &packed_data, &packed_len);
510
+
511
+ // arg[2]: TypedArray result
512
+ void *result_data;
513
+ size_t result_len;
514
+ napi_typedarray_type result_type;
515
+ napi_get_typedarray_info(env, args[2], &result_type, &result_len, &result_data, NULL, NULL);
516
+
517
+ // args[3..7]: height, width, depth, aStride, resultStride
518
+ uint32_t height, width, depth, a_stride, result_stride;
519
+ napi_get_value_uint32(env, args[3], &height);
520
+ napi_get_value_uint32(env, args[4], &width);
521
+ napi_get_value_uint32(env, args[5], &depth);
522
+ napi_get_value_uint32(env, args[6], &a_stride);
523
+ napi_get_value_uint32(env, args[7], &result_stride);
524
+
525
+ // arg[8]: dtype string
526
+ char dtype_str[16];
527
+ size_t str_len;
528
+ napi_get_value_string_utf8(env, args[8], dtype_str, sizeof(dtype_str), &str_len);
529
+ nk_dtype_t dtype = parse_dtype_string(dtype_str);
530
+ if (dtype == nk_dtype_unknown_k) {
531
+ napi_throw_error(env, NULL, "Unsupported dtype string");
532
+ return NULL;
533
+ }
534
+
535
+ nk_dots_packed_punned_t kernel = NULL;
536
+ nk_capability_t cap = nk_cap_serial_k;
537
+ nk_find_kernel_punned(kernel_kind, dtype, static_capabilities, (nk_kernel_punned_t *)&kernel, &cap);
538
+ if (!kernel) {
539
+ napi_throw_error(env, NULL, "Packed kernel not available for this dtype");
540
+ return NULL;
541
+ }
542
+
543
+ uint32_t threads = 1;
544
+ if (argc == 10) napi_get_value_uint32(env, args[9], &threads);
545
+
546
+ #if defined(NK_USE_OPENMP)
547
+ if (threads == 0) threads = (uint32_t)omp_get_max_threads();
548
+ omp_set_num_threads((int)threads);
549
+ #endif
550
+
551
+ // `int` loop counter pre-declared: MSVC's OpenMP stays at 2.0 canonical
552
+ // form, which forbids in-init declarations and rejects 64-bit iterators
553
+ // — either would trip C3015.
554
+ int const tile_count = (int)nk_size_divide_round_up_(height, NK_PARALLEL_PACKED_TILE);
555
+ int tile_idx;
556
+ #pragma omp parallel for schedule(dynamic, 1) if (threads > 1)
557
+ for (tile_idx = 0; tile_idx < tile_count; tile_idx++) {
558
+ nk_size_t row = (nk_size_t)tile_idx * NK_PARALLEL_PACKED_TILE;
559
+ nk_size_t chunk = (row + NK_PARALLEL_PACKED_TILE <= height) ? NK_PARALLEL_PACKED_TILE : (height - row);
560
+ kernel((char const *)a_data + row * a_stride, packed_data, (char *)result_data + row * result_stride, chunk,
561
+ (nk_size_t)width, (nk_size_t)depth, (nk_size_t)a_stride, (nk_size_t)result_stride);
562
+ }
563
+ return NULL;
564
+ }
565
+
566
+ static napi_value api_dots_packed(napi_env env, napi_callback_info info) {
567
+ return api_packed_common(env, info, nk_kernel_dots_packed_k);
568
+ }
569
+ static napi_value api_angulars_packed(napi_env env, napi_callback_info info) {
570
+ return api_packed_common(env, info, nk_kernel_angulars_packed_k);
571
+ }
572
+ static napi_value api_euclideans_packed(napi_env env, napi_callback_info info) {
573
+ return api_packed_common(env, info, nk_kernel_euclideans_packed_k);
574
+ }
575
+
576
+ /**
577
+ * @brief Shared dispatcher for symmetric operations (dots, angulars, euclideans).
578
+ * Args: TypedArray vectors, TypedArray result, numbers nVectors/depth/vectorsStride/resultStride/rowStart/rowCount,
579
+ * string dtype
580
+ */
581
+ static napi_value api_symmetric_common(napi_env env, napi_callback_info info, nk_kernel_kind_t kernel_kind) {
582
+ size_t argc = 10;
583
+ napi_value args[10];
584
+ napi_get_cb_info(env, info, &argc, args, NULL, NULL);
585
+ if (argc < 9 || argc > 10) {
586
+ napi_throw_error(env, NULL, "Symmetric operation requires 9-10 arguments (last is optional threads)");
587
+ return NULL;
588
+ }
589
+
590
+ // arg[0]: TypedArray vectors
591
+ void *vectors_data;
592
+ size_t vectors_len;
593
+ napi_typedarray_type vectors_type;
594
+ napi_get_typedarray_info(env, args[0], &vectors_type, &vectors_len, &vectors_data, NULL, NULL);
595
+
596
+ // arg[1]: TypedArray result
597
+ void *result_data;
598
+ size_t result_len;
599
+ napi_typedarray_type result_type;
600
+ napi_get_typedarray_info(env, args[1], &result_type, &result_len, &result_data, NULL, NULL);
601
+
602
+ // args[2..7]: nVectors, depth, vectorsStride, resultStride, rowStart, rowCount
603
+ uint32_t n_vectors, depth, vectors_stride, result_stride, row_start, row_count;
604
+ napi_get_value_uint32(env, args[2], &n_vectors);
605
+ napi_get_value_uint32(env, args[3], &depth);
606
+ napi_get_value_uint32(env, args[4], &vectors_stride);
607
+ napi_get_value_uint32(env, args[5], &result_stride);
608
+ napi_get_value_uint32(env, args[6], &row_start);
609
+ napi_get_value_uint32(env, args[7], &row_count);
610
+
611
+ // arg[8]: dtype string
612
+ char dtype_str[16];
613
+ size_t str_len;
614
+ napi_get_value_string_utf8(env, args[8], dtype_str, sizeof(dtype_str), &str_len);
615
+ nk_dtype_t dtype = parse_dtype_string(dtype_str);
616
+ if (dtype == nk_dtype_unknown_k) {
617
+ napi_throw_error(env, NULL, "Unsupported dtype string");
618
+ return NULL;
619
+ }
620
+
621
+ nk_dots_symmetric_punned_t kernel = NULL;
622
+ nk_capability_t cap = nk_cap_serial_k;
623
+ nk_find_kernel_punned(kernel_kind, dtype, static_capabilities, (nk_kernel_punned_t *)&kernel, &cap);
624
+ if (!kernel) {
625
+ napi_throw_error(env, NULL, "Symmetric kernel not available for this dtype");
626
+ return NULL;
627
+ }
628
+
629
+ uint32_t threads = 1;
630
+ if (argc == 10) napi_get_value_uint32(env, args[9], &threads);
631
+
632
+ #if defined(NK_USE_OPENMP)
633
+ if (threads == 0) threads = (uint32_t)omp_get_max_threads();
634
+ omp_set_num_threads((int)threads);
635
+ #endif
636
+
637
+ // `int` loop counter pre-declared: see note at `api_packed_common`.
638
+ int const tile_count = (int)nk_size_divide_round_up_(row_count, NK_PARALLEL_SYMMETRIC_TILE);
639
+ int tile_idx;
640
+ #pragma omp parallel for schedule(dynamic, 1) if (threads > 1)
641
+ for (tile_idx = 0; tile_idx < tile_count; tile_idx++) {
642
+ nk_size_t tile_start = (nk_size_t)row_start + (nk_size_t)tile_idx * NK_PARALLEL_SYMMETRIC_TILE;
643
+ nk_size_t tile_rows = (tile_start + NK_PARALLEL_SYMMETRIC_TILE <= (nk_size_t)row_start + row_count)
644
+ ? NK_PARALLEL_SYMMETRIC_TILE
645
+ : ((nk_size_t)row_start + row_count - tile_start);
646
+ kernel(vectors_data, (nk_size_t)n_vectors, (nk_size_t)depth, (nk_size_t)vectors_stride, result_data,
647
+ (nk_size_t)result_stride, tile_start, tile_rows);
648
+ }
649
+
650
+ return NULL;
651
+ }
652
+
653
+ static napi_value api_dots_symmetric(napi_env env, napi_callback_info info) {
654
+ return api_symmetric_common(env, info, nk_kernel_dots_symmetric_k);
655
+ }
656
+ static napi_value api_angulars_symmetric(napi_env env, napi_callback_info info) {
657
+ return api_symmetric_common(env, info, nk_kernel_angulars_symmetric_k);
658
+ }
659
+ static napi_value api_euclideans_symmetric(napi_env env, napi_callback_info info) {
660
+ return api_symmetric_common(env, info, nk_kernel_euclideans_symmetric_k);
661
+ }
662
+
663
+ #pragma endregion Packed API
664
+
665
+ #pragma region Module Init
666
+
667
+ /** @brief Registers a C function as a named JavaScript export. */
668
+ static napi_status export_function(napi_env env, napi_value exports, char const *name, napi_callback func) {
669
+ napi_value fn;
670
+ napi_status status = napi_create_function(env, name, NAPI_AUTO_LENGTH, func, NULL, &fn);
671
+ if (status != napi_ok) return status;
672
+ return napi_set_named_property(env, exports, name, fn);
673
+ }
674
+
675
+ /** @brief Module initialization — exports all functions, detects CPU capabilities. */
676
+ napi_value Init(napi_env env, napi_value exports) {
677
+ if (export_function(env, exports, "dot", api_ip) != napi_ok ||
678
+ export_function(env, exports, "inner", api_ip) != napi_ok ||
679
+ export_function(env, exports, "sqeuclidean", api_sqeuclidean) != napi_ok ||
680
+ export_function(env, exports, "euclidean", api_euclidean) != napi_ok ||
681
+ export_function(env, exports, "angular", api_angular) != napi_ok ||
682
+ export_function(env, exports, "hamming", api_hamming) != napi_ok ||
683
+ export_function(env, exports, "jaccard", api_jaccard) != napi_ok ||
684
+ export_function(env, exports, "kullbackleibler", api_kld) != napi_ok ||
685
+ export_function(env, exports, "jensenshannon", api_jsd) != napi_ok ||
686
+ export_function(env, exports, "getCapabilities", api_get_capabilities) != napi_ok ||
687
+ export_function(env, exports, "castF16ToF32", api_cast_f16_to_f32) != napi_ok ||
688
+ export_function(env, exports, "castF32ToF16", api_cast_f32_to_f16) != napi_ok ||
689
+ export_function(env, exports, "castBF16ToF32", api_cast_bf16_to_f32) != napi_ok ||
690
+ export_function(env, exports, "castF32ToBF16", api_cast_f32_to_bf16) != napi_ok ||
691
+ export_function(env, exports, "castE4M3ToF32", api_cast_e4m3_to_f32) != napi_ok ||
692
+ export_function(env, exports, "castF32ToE4M3", api_cast_f32_to_e4m3) != napi_ok ||
693
+ export_function(env, exports, "castE5M2ToF32", api_cast_e5m2_to_f32) != napi_ok ||
694
+ export_function(env, exports, "castF32ToE5M2", api_cast_f32_to_e5m2) != napi_ok ||
695
+ export_function(env, exports, "cast", api_cast) != napi_ok ||
696
+ export_function(env, exports, "dotsPackedSize", api_dots_packed_size) != napi_ok ||
697
+ export_function(env, exports, "dotsPack", api_dots_pack) != napi_ok ||
698
+ export_function(env, exports, "dotsPacked", api_dots_packed) != napi_ok ||
699
+ export_function(env, exports, "angularsPacked", api_angulars_packed) != napi_ok ||
700
+ export_function(env, exports, "euclideansPacked", api_euclideans_packed) != napi_ok ||
701
+ export_function(env, exports, "dotsSymmetric", api_dots_symmetric) != napi_ok ||
702
+ export_function(env, exports, "angularsSymmetric", api_angulars_symmetric) != napi_ok ||
703
+ export_function(env, exports, "euclideansSymmetric", api_euclideans_symmetric) != napi_ok) {
704
+ return NULL;
705
+ }
706
+ static_capabilities = nk_capabilities();
707
+ return exports;
708
+ }
709
+
710
+ #pragma endregion Module Init
711
+
712
+ NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)