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,174 @@
1
+ /**
2
+ * @brief SWAR-accelerated Set Similarity Measures for SIMD-free CPUs.
3
+ * @file include/numkong/set/serial.h
4
+ * @author Ash Vardanian
5
+ * @date December 27, 2025
6
+ *
7
+ * @sa include/numkong/set.h
8
+ *
9
+ * @section set_serial_instructions Key SWAR Set Instructions
10
+ *
11
+ * Serial backend uses lookup-table-based popcount for bit operations.
12
+ * No SIMD instructions required - works on any architecture.
13
+ *
14
+ * @section set_serial_stateful Stateful Streaming Logic
15
+ *
16
+ * To build memory-optimal tiled algorithms, this file defines:
17
+ *
18
+ * - nk_hamming_u1x128_state_serial_t for streaming Hamming distance
19
+ * - nk_jaccard_u1x128_state_serial_t for streaming Jaccard similarity
20
+ *
21
+ * @code{c}
22
+ * nk_jaccard_u1x128_state_serial_t state_first, state_second, state_third, state_fourth;
23
+ * nk_jaccard_u1x128_init_serial(&state_first);
24
+ * // ... stream through packed binary vectors ...
25
+ * nk_jaccard_u1x128_finalize_serial(&state_first, &state_second, &state_third, &state_fourth,
26
+ * query_popcount, target_popcount_a, target_popcount_b, target_popcount_c, target_popcount_d,
27
+ * total_dimensions, &results);
28
+ * @endcode
29
+ */
30
+ #ifndef NK_SET_SERIAL_H
31
+ #define NK_SET_SERIAL_H
32
+ #include "numkong/types.h"
33
+
34
+ #if defined(__cplusplus)
35
+ extern "C" {
36
+ #endif
37
+
38
+ #pragma region Binary Sets
39
+
40
+ NK_PUBLIC void nk_hamming_u1_serial(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result) {
41
+ nk_size_t n_bytes = nk_size_divide_round_up_(n, NK_BITS_PER_BYTE);
42
+ nk_u32_t differences = 0;
43
+ for (nk_size_t i = 0; i != n_bytes; ++i) differences += nk_u1x8_popcount_(a[i] ^ b[i]);
44
+ *result = differences;
45
+ }
46
+
47
+ NK_PUBLIC void nk_jaccard_u1_serial(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result) {
48
+ nk_size_t n_bytes = nk_size_divide_round_up_(n, NK_BITS_PER_BYTE);
49
+ nk_u32_t intersection_count = 0, union_count = 0;
50
+ for (nk_size_t i = 0; i != n_bytes; ++i)
51
+ intersection_count += nk_u1x8_popcount_(a[i] & b[i]), union_count += nk_u1x8_popcount_(a[i] | b[i]);
52
+ *result = (union_count != 0) ? 1.0f - (nk_f32_t)intersection_count / (nk_f32_t)union_count : 0.0f;
53
+ }
54
+
55
+ #pragma endregion Binary Sets
56
+
57
+ #pragma region Integer Sets
58
+
59
+ NK_PUBLIC void nk_jaccard_u32_serial(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result) {
60
+ nk_u32_t intersection_count = 0;
61
+ for (nk_size_t i = 0; i != n; ++i) intersection_count += (a[i] == b[i]);
62
+ *result = (n != 0) ? 1.0f - (nk_f32_t)intersection_count / (nk_f32_t)n : 0.0f;
63
+ }
64
+
65
+ NK_PUBLIC void nk_hamming_u8_serial(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result) {
66
+ nk_u32_t differences = 0;
67
+ for (nk_size_t i = 0; i != n; ++i) differences += (a[i] != b[i]);
68
+ *result = differences;
69
+ }
70
+
71
+ NK_PUBLIC void nk_jaccard_u16_serial(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result) {
72
+ nk_u32_t matches = 0;
73
+ for (nk_size_t i = 0; i != n; ++i) matches += (a[i] == b[i]);
74
+ *result = (n != 0) ? 1.0f - (nk_f32_t)matches / (nk_f32_t)n : 0.0f;
75
+ }
76
+
77
+ #pragma endregion Integer Sets
78
+
79
+ #pragma region Stateful Streaming
80
+
81
+ typedef struct nk_jaccard_u1x128_state_serial_t {
82
+ nk_u64_t intersection_count;
83
+ } nk_jaccard_u1x128_state_serial_t;
84
+
85
+ NK_INTERNAL void nk_jaccard_u1x128_init_serial(nk_jaccard_u1x128_state_serial_t *state) {
86
+ state->intersection_count = 0;
87
+ }
88
+
89
+ NK_INTERNAL void nk_jaccard_u1x128_update_serial(nk_jaccard_u1x128_state_serial_t *state, nk_b128_vec_t a,
90
+ nk_b128_vec_t b, nk_size_t depth_offset, nk_size_t active_dimensions) {
91
+ nk_unused_(depth_offset);
92
+ nk_unused_(active_dimensions);
93
+ nk_u64_t intersection_low = a.u64s[0] & b.u64s[0];
94
+ nk_u64_t intersection_high = a.u64s[1] & b.u64s[1];
95
+ state->intersection_count += nk_u64_popcount_(intersection_low);
96
+ state->intersection_count += nk_u64_popcount_(intersection_high);
97
+ }
98
+
99
+ NK_INTERNAL void nk_jaccard_u1x128_finalize_serial( //
100
+ nk_jaccard_u1x128_state_serial_t const *state_a, nk_jaccard_u1x128_state_serial_t const *state_b,
101
+ nk_jaccard_u1x128_state_serial_t const *state_c, nk_jaccard_u1x128_state_serial_t const *state_d,
102
+ nk_f32_t query_popcount, nk_f32_t target_popcount_a, nk_f32_t target_popcount_b, nk_f32_t target_popcount_c,
103
+ nk_f32_t target_popcount_d, nk_size_t total_dimensions, nk_b128_vec_t *result) {
104
+ nk_unused_(total_dimensions);
105
+
106
+ nk_f32_t intersection_a = (nk_f32_t)state_a->intersection_count;
107
+ nk_f32_t intersection_b = (nk_f32_t)state_b->intersection_count;
108
+ nk_f32_t intersection_c = (nk_f32_t)state_c->intersection_count;
109
+ nk_f32_t intersection_d = (nk_f32_t)state_d->intersection_count;
110
+
111
+ nk_f32_t union_a = query_popcount + target_popcount_a - intersection_a;
112
+ nk_f32_t union_b = query_popcount + target_popcount_b - intersection_b;
113
+ nk_f32_t union_c = query_popcount + target_popcount_c - intersection_c;
114
+ nk_f32_t union_d = query_popcount + target_popcount_d - intersection_d;
115
+
116
+ result->f32s[0] = (union_a != 0) ? 1.0f - intersection_a / union_a : 0.0f;
117
+ result->f32s[1] = (union_b != 0) ? 1.0f - intersection_b / union_b : 0.0f;
118
+ result->f32s[2] = (union_c != 0) ? 1.0f - intersection_c / union_c : 0.0f;
119
+ result->f32s[3] = (union_d != 0) ? 1.0f - intersection_d / union_d : 0.0f;
120
+ }
121
+
122
+ typedef struct nk_hamming_u1x128_state_serial_t {
123
+ nk_u64_t intersection_count;
124
+ } nk_hamming_u1x128_state_serial_t;
125
+
126
+ NK_INTERNAL void nk_hamming_u1x128_init_serial(nk_hamming_u1x128_state_serial_t *state) {
127
+ state->intersection_count = 0;
128
+ }
129
+
130
+ NK_INTERNAL void nk_hamming_u1x128_update_serial(nk_hamming_u1x128_state_serial_t *state, nk_b128_vec_t a,
131
+ nk_b128_vec_t b, nk_size_t depth_offset, nk_size_t active_dimensions) {
132
+ nk_unused_(depth_offset);
133
+ nk_unused_(active_dimensions);
134
+ nk_u64_t intersection_low = a.u64s[0] ^ b.u64s[0];
135
+ nk_u64_t intersection_high = a.u64s[1] ^ b.u64s[1];
136
+ state->intersection_count += nk_u64_popcount_(intersection_low);
137
+ state->intersection_count += nk_u64_popcount_(intersection_high);
138
+ }
139
+
140
+ NK_INTERNAL void nk_hamming_u1x128_finalize_serial( //
141
+ nk_hamming_u1x128_state_serial_t const *state_a, nk_hamming_u1x128_state_serial_t const *state_b,
142
+ nk_hamming_u1x128_state_serial_t const *state_c, nk_hamming_u1x128_state_serial_t const *state_d,
143
+ nk_size_t total_dimensions, nk_b128_vec_t *result) {
144
+ nk_unused_(total_dimensions);
145
+
146
+ result->u32s[0] = (nk_u32_t)state_a->intersection_count;
147
+ result->u32s[1] = (nk_u32_t)state_b->intersection_count;
148
+ result->u32s[2] = (nk_u32_t)state_c->intersection_count;
149
+ result->u32s[3] = (nk_u32_t)state_d->intersection_count;
150
+ }
151
+
152
+ /** @brief Hamming from_dot: computes pop_a + pop_b - 2*dot for 4 pairs (serial). */
153
+ NK_INTERNAL void nk_hamming_u32x4_from_dot_serial_(nk_b128_vec_t dots, nk_u32_t query_pop, nk_b128_vec_t target_pops,
154
+ nk_b128_vec_t *results) {
155
+ for (int i = 0; i < 4; ++i) results->u32s[i] = query_pop + target_pops.u32s[i] - 2 * dots.u32s[i];
156
+ }
157
+
158
+ /** @brief Jaccard from_dot: computes 1 - dot / (pop_a + pop_b - dot) for 4 pairs (serial). */
159
+ NK_INTERNAL void nk_jaccard_f32x4_from_dot_serial_(nk_b128_vec_t dots, nk_u32_t query_pop, nk_b128_vec_t target_pops,
160
+ nk_b128_vec_t *results) {
161
+ for (int i = 0; i < 4; ++i) {
162
+ nk_f32_t dot = (nk_f32_t)dots.u32s[i];
163
+ nk_f32_t union_val = (nk_f32_t)query_pop + (nk_f32_t)target_pops.u32s[i] - dot;
164
+ results->f32s[i] = (union_val != 0) ? 1.0f - dot / union_val : 0.0f;
165
+ }
166
+ }
167
+
168
+ #pragma endregion Stateful Streaming
169
+
170
+ #if defined(__cplusplus)
171
+ } // extern "C"
172
+ #endif
173
+
174
+ #endif // NK_SET_SERIAL_H
@@ -0,0 +1,187 @@
1
+ /**
2
+ * @brief SIMD-accelerated Set Similarity Measures for SVE.
3
+ * @file include/numkong/set/sve.h
4
+ * @author Ash Vardanian
5
+ * @date December 27, 2025
6
+ *
7
+ * @sa include/numkong/set.h
8
+ *
9
+ * @section set_sve_instructions ARM SVE Instructions
10
+ *
11
+ * Intrinsic Instruction V1
12
+ * svld1_u8 LD1B (Z.B, P/Z, [Xn]) 4-6cy @ 2p
13
+ * svld1_u32 LD1W (Z.S, P/Z, [Xn]) 4-6cy @ 2p
14
+ * sveor_u8_m EOR (Z.B, P/M, Z.B, Z.B) 1cy @ 2p
15
+ * svand_u8_m AND (Z.B, P/M, Z.B, Z.B) 1cy @ 2p
16
+ * svorr_u8_m ORR (Z.B, P/M, Z.B, Z.B) 1cy @ 2p
17
+ * svcnt_u8_x CNT (Z.B, P/M, Z.B) 2cy @ 2p
18
+ * svadd_u8_z ADD (Z.B, P/M, Z.B, Z.B) 1cy @ 2p
19
+ * svaddv_u8 UADDV (D, P, Z.B) 6cy @ 1p
20
+ * svcmpeq_u32 CMPEQ (P.S, P/Z, Z.S, Z.S) 2cy @ 1p
21
+ * svcntp_b32 CNTP (Xd, P, P.S) 2cy @ 1p
22
+ * svdup_n_u8 DUP (Z.B, #imm) 1cy @ 2p
23
+ * svwhilelt_b8 WHILELT (P.B, Xn, Xm) 2cy @ 1p
24
+ * svwhilelt_b32 WHILELT (P.S, Xn, Xm) 2cy @ 1p
25
+ * svptrue_b8 PTRUE (P.B, pattern) 1cy @ 2p
26
+ * svcntb CNTB (Xd) 1cy @ 2p
27
+ * svcntw CNTW (Xd) 1cy @ 2p
28
+ */
29
+ #ifndef NK_SET_SVE_H
30
+ #define NK_SET_SVE_H
31
+
32
+ #if NK_TARGET_ARM64_
33
+ #if NK_TARGET_SVE
34
+
35
+ #include "numkong/types.h" // `nk_u1x8_t`
36
+ #include "numkong/reduce/sve.h" // `nk_svaddv_f64_`
37
+ #include "numkong/set/neon.h" // `nk_hamming_u1_neon`
38
+
39
+ #if defined(__cplusplus)
40
+ extern "C" {
41
+ #endif
42
+
43
+ #if defined(__clang__)
44
+ #pragma clang attribute push(__attribute__((target("arch=armv8.2-a+sve"))), apply_to = function)
45
+ #elif defined(__GNUC__)
46
+ #pragma GCC push_options
47
+ #pragma GCC target("arch=armv8.2-a+sve")
48
+ #endif
49
+
50
+ #pragma region Binary Sets
51
+
52
+ NK_PUBLIC void nk_hamming_u1_sve(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result) {
53
+ nk_size_t n_bytes = nk_size_divide_round_up_(n, NK_BITS_PER_BYTE);
54
+
55
+ // On very small register sizes, NEON is at least as fast as SVE.
56
+ nk_size_t const words_per_register = svcntb();
57
+ if (words_per_register <= 32) {
58
+ nk_hamming_u1_neon(a, b, n, result);
59
+ return;
60
+ }
61
+
62
+ // On larger register sizes, SVE is faster.
63
+ nk_size_t i = 0, cycle = 0;
64
+ nk_u32_t differences = 0;
65
+ svuint8_t popcount_u8x = svdup_n_u8(0);
66
+ svbool_t const all_predicate_b8x = svptrue_b8();
67
+ while (i < n_bytes) {
68
+ do {
69
+ svbool_t active_predicate_b8x = svwhilelt_b8_u64(i, n_bytes);
70
+ svuint8_t a_u8x = svld1_u8(active_predicate_b8x, a + i);
71
+ svuint8_t b_u8x = svld1_u8(active_predicate_b8x, b + i);
72
+ popcount_u8x = svadd_u8_z(all_predicate_b8x, popcount_u8x,
73
+ svcnt_u8_x(all_predicate_b8x, sveor_u8_m(all_predicate_b8x, a_u8x, b_u8x)));
74
+ i += words_per_register;
75
+ ++cycle;
76
+ } while (i < n_bytes && cycle < 31);
77
+ differences += nk_svaddv_u8_(all_predicate_b8x, popcount_u8x);
78
+ popcount_u8x = svdup_n_u8(0);
79
+ cycle = 0; // Reset the cycle counter.
80
+ }
81
+
82
+ *result = differences;
83
+ }
84
+
85
+ NK_PUBLIC void nk_jaccard_u1_sve(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result) {
86
+ nk_size_t n_bytes = nk_size_divide_round_up_(n, NK_BITS_PER_BYTE);
87
+
88
+ // On very small register sizes, NEON is at least as fast as SVE.
89
+ nk_size_t const words_per_register = svcntb();
90
+ if (words_per_register <= 32) {
91
+ nk_jaccard_u1_neon(a, b, n, result);
92
+ return;
93
+ }
94
+
95
+ // On larger register sizes, SVE is faster.
96
+ nk_size_t i = 0, cycle = 0;
97
+ nk_u32_t intersection_count = 0, union_count = 0;
98
+ svuint8_t intersection_popcount_u8x = svdup_n_u8(0);
99
+ svuint8_t union_popcount_u8x = svdup_n_u8(0);
100
+ svbool_t const all_predicate_b8x = svptrue_b8();
101
+ while (i < n_bytes) {
102
+ do {
103
+ svbool_t active_predicate_b8x = svwhilelt_b8_u64(i, n_bytes);
104
+ svuint8_t a_u8x = svld1_u8(active_predicate_b8x, a + i);
105
+ svuint8_t b_u8x = svld1_u8(active_predicate_b8x, b + i);
106
+ intersection_popcount_u8x = svadd_u8_z(
107
+ all_predicate_b8x, intersection_popcount_u8x,
108
+ svcnt_u8_x(all_predicate_b8x, svand_u8_m(all_predicate_b8x, a_u8x, b_u8x)));
109
+ union_popcount_u8x = svadd_u8_z(all_predicate_b8x, union_popcount_u8x,
110
+ svcnt_u8_x(all_predicate_b8x, svorr_u8_m(all_predicate_b8x, a_u8x, b_u8x)));
111
+ i += words_per_register;
112
+ ++cycle;
113
+ } while (i < n_bytes && cycle < 31);
114
+ intersection_count += nk_svaddv_u8_(all_predicate_b8x, intersection_popcount_u8x);
115
+ intersection_popcount_u8x = svdup_n_u8(0);
116
+ union_count += nk_svaddv_u8_(all_predicate_b8x, union_popcount_u8x);
117
+ union_popcount_u8x = svdup_n_u8(0);
118
+ cycle = 0; // Reset the cycle counter.
119
+ }
120
+
121
+ *result = (union_count != 0) ? 1.0f - (nk_f32_t)intersection_count / (nk_f32_t)union_count : 0.0f;
122
+ }
123
+
124
+ #pragma endregion Binary Sets
125
+
126
+ #pragma region Integer Sets
127
+
128
+ NK_PUBLIC void nk_jaccard_u32_sve(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result) {
129
+ nk_size_t const words_per_register = svcntw();
130
+ nk_size_t i = 0;
131
+ nk_u32_t intersection_count = 0;
132
+ while (i < n) {
133
+ svbool_t active_predicate_b32x = svwhilelt_b32_u64(i, n);
134
+ svuint32_t a_u32x = svld1_u32(active_predicate_b32x, a + i);
135
+ svuint32_t b_u32x = svld1_u32(active_predicate_b32x, b + i);
136
+ svbool_t equality_predicate_b32x = svcmpeq_u32(active_predicate_b32x, a_u32x, b_u32x);
137
+ intersection_count += svcntp_b32(active_predicate_b32x, equality_predicate_b32x);
138
+ i += words_per_register;
139
+ }
140
+ *result = (n != 0) ? 1.0f - (nk_f32_t)intersection_count / (nk_f32_t)n : 0.0f;
141
+ }
142
+
143
+ NK_PUBLIC void nk_hamming_u8_sve(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result) {
144
+ nk_size_t const bytes_per_register = svcntb();
145
+ nk_size_t i = 0;
146
+ nk_u32_t differences = 0;
147
+ while (i < n) {
148
+ svbool_t active_predicate_b8x = svwhilelt_b8_u64(i, n);
149
+ svuint8_t a_u8x = svld1_u8(active_predicate_b8x, a + i);
150
+ svuint8_t b_u8x = svld1_u8(active_predicate_b8x, b + i);
151
+ svbool_t neq_predicate_b8x = svcmpne_u8(active_predicate_b8x, a_u8x, b_u8x);
152
+ differences += svcntp_b8(active_predicate_b8x, neq_predicate_b8x);
153
+ i += bytes_per_register;
154
+ }
155
+ *result = differences;
156
+ }
157
+
158
+ NK_PUBLIC void nk_jaccard_u16_sve(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result) {
159
+ nk_size_t const halfwords_per_register = svcnth();
160
+ nk_size_t i = 0;
161
+ nk_u32_t intersection_count = 0;
162
+ while (i < n) {
163
+ svbool_t active_predicate_b16x = svwhilelt_b16_u64(i, n);
164
+ svuint16_t a_u16x = svld1_u16(active_predicate_b16x, a + i);
165
+ svuint16_t b_u16x = svld1_u16(active_predicate_b16x, b + i);
166
+ svbool_t equality_predicate_b16x = svcmpeq_u16(active_predicate_b16x, a_u16x, b_u16x);
167
+ intersection_count += svcntp_b16(active_predicate_b16x, equality_predicate_b16x);
168
+ i += halfwords_per_register;
169
+ }
170
+ *result = (n != 0) ? 1.0f - (nk_f32_t)intersection_count / (nk_f32_t)n : 0.0f;
171
+ }
172
+
173
+ #pragma endregion Integer Sets
174
+
175
+ #if defined(__clang__)
176
+ #pragma clang attribute pop
177
+ #elif defined(__GNUC__)
178
+ #pragma GCC pop_options
179
+ #endif
180
+
181
+ #if defined(__cplusplus)
182
+ } // extern "C"
183
+ #endif
184
+
185
+ #endif // NK_TARGET_SVE
186
+ #endif // NK_TARGET_ARM64_
187
+ #endif // NK_SET_SVE_H
@@ -0,0 +1,240 @@
1
+ /**
2
+ * @brief SIMD-accelerated Set Similarity Measures for WASM.
3
+ * @file include/numkong/set/v128relaxed.h
4
+ * @author Ash Vardanian
5
+ * @date February 1, 2026
6
+ *
7
+ * This file contains windowed implementations of Hamming and Jaccard distance
8
+ * for bit-level operations (u1 packed bits). The windowing optimization reduces
9
+ * widening overhead by 96.7%, providing 5-10× speedup over naive implementations.
10
+ *
11
+ * Algorithm: Accumulate popcount results in u8 for 31 iterations, then widen
12
+ * to u16 → u32 once. Since max(popcount(u8)) = 8, we can safely accumulate
13
+ * 31 × 8 = 248 < 255 (u8 max) without overflow.
14
+ */
15
+
16
+ #ifndef NK_SET_V128RELAXED_H
17
+ #define NK_SET_V128RELAXED_H
18
+
19
+ #if NK_TARGET_V128RELAXED
20
+
21
+ #include "numkong/types.h"
22
+ #include "numkong/reduce/v128relaxed.h"
23
+ #include "numkong/set/serial.h"
24
+
25
+ #if defined(__cplusplus)
26
+ extern "C" {
27
+ #endif
28
+
29
+ #if defined(__clang__)
30
+ #pragma clang attribute push(__attribute__((target("relaxed-simd"))), apply_to = function)
31
+ #endif
32
+
33
+ #pragma region Binary Sets
34
+
35
+ NK_PUBLIC void nk_hamming_u1_v128relaxed(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_u32_t *result) {
36
+ nk_u8_t const *a_bytes = (nk_u8_t const *)a;
37
+ nk_u8_t const *b_bytes = (nk_u8_t const *)b;
38
+ nk_size_t n_bytes = nk_size_divide_round_up_(n, NK_BITS_PER_BYTE);
39
+
40
+ nk_u32_t differences = 0;
41
+ nk_size_t i = 0;
42
+
43
+ // Windowed accumulation loop
44
+ while (i + 16 <= n_bytes) {
45
+ v128_t popcount_u8x16 = wasm_i8x16_splat(0);
46
+
47
+ // Inner loop: accumulate 31 iterations in u8 before widening
48
+ nk_size_t cycle = 0;
49
+ for (; cycle < 31 && i + 16 <= n_bytes; ++cycle, i += 16) {
50
+ v128_t a_u8x16 = wasm_v128_load(a_bytes + i);
51
+ v128_t b_u8x16 = wasm_v128_load(b_bytes + i);
52
+
53
+ // XOR to find differing bits
54
+ v128_t xor_u8x16 = wasm_v128_xor(a_u8x16, b_u8x16);
55
+
56
+ // Popcount each byte
57
+ v128_t popcnt_u8x16 = wasm_i8x16_popcnt(xor_u8x16);
58
+
59
+ // Accumulate in u8 (safe: 31 × 8 = 248 < 255)
60
+ popcount_u8x16 = wasm_i8x16_add(popcount_u8x16, popcnt_u8x16);
61
+ }
62
+
63
+ // Widen once per window: u8 → u16 → u32
64
+ differences += nk_reduce_add_u8x16_v128relaxed_(popcount_u8x16);
65
+ }
66
+
67
+ // Handle tail bytes
68
+ for (; i < n_bytes; i++) {
69
+ nk_u8_t xor_byte = a_bytes[i] ^ b_bytes[i];
70
+ differences += nk_u1x8_popcount_(xor_byte);
71
+ }
72
+
73
+ *result = differences;
74
+ }
75
+
76
+ NK_PUBLIC void nk_jaccard_u1_v128relaxed(nk_u1x8_t const *a, nk_u1x8_t const *b, nk_size_t n, nk_f32_t *result) {
77
+ nk_u8_t const *a_bytes = (nk_u8_t const *)a;
78
+ nk_u8_t const *b_bytes = (nk_u8_t const *)b;
79
+ nk_size_t n_bytes = nk_size_divide_round_up_(n, NK_BITS_PER_BYTE);
80
+
81
+ nk_u32_t intersection = 0;
82
+ nk_u32_t union_count = 0;
83
+ nk_size_t i = 0;
84
+
85
+ // Windowed accumulation loop
86
+ while (i + 16 <= n_bytes) {
87
+ v128_t popcount_and_u8x16 = wasm_i8x16_splat(0);
88
+ v128_t popcount_or_u8x16 = wasm_i8x16_splat(0);
89
+
90
+ // Inner loop: accumulate 31 iterations in u8 before widening
91
+ nk_size_t cycle = 0;
92
+ for (; cycle < 31 && i + 16 <= n_bytes; ++cycle, i += 16) {
93
+ v128_t a_u8x16 = wasm_v128_load(a_bytes + i);
94
+ v128_t b_u8x16 = wasm_v128_load(b_bytes + i);
95
+
96
+ // Intersection: a AND b
97
+ v128_t and_u8x16 = wasm_v128_and(a_u8x16, b_u8x16);
98
+ v128_t popcnt_and_u8x16 = wasm_i8x16_popcnt(and_u8x16);
99
+ popcount_and_u8x16 = wasm_i8x16_add(popcount_and_u8x16, popcnt_and_u8x16);
100
+
101
+ // Union: a OR b
102
+ v128_t or_u8x16 = wasm_v128_or(a_u8x16, b_u8x16);
103
+ v128_t popcnt_or_u8x16 = wasm_i8x16_popcnt(or_u8x16);
104
+ popcount_or_u8x16 = wasm_i8x16_add(popcount_or_u8x16, popcnt_or_u8x16);
105
+ }
106
+
107
+ // Widen once per window
108
+ intersection += nk_reduce_add_u8x16_v128relaxed_(popcount_and_u8x16);
109
+ union_count += nk_reduce_add_u8x16_v128relaxed_(popcount_or_u8x16);
110
+ }
111
+
112
+ // Handle tail bytes
113
+ for (; i < n_bytes; i++) {
114
+ nk_u8_t a_byte = a_bytes[i];
115
+ nk_u8_t b_byte = b_bytes[i];
116
+ intersection += nk_u1x8_popcount_(a_byte & b_byte);
117
+ union_count += nk_u1x8_popcount_(a_byte | b_byte);
118
+ }
119
+
120
+ // Jaccard distance = 1 - (intersection / union)
121
+ *result = union_count > 0 ? 1.0f - ((nk_f32_t)intersection / (nk_f32_t)union_count) : 0.0f;
122
+ }
123
+
124
+ #pragma endregion Binary Sets
125
+
126
+ #pragma region Integer Sets
127
+
128
+ NK_PUBLIC void nk_hamming_u8_v128relaxed(nk_u8_t const *a, nk_u8_t const *b, nk_size_t n, nk_u32_t *result) {
129
+ nk_u32_t sum_total = 0;
130
+ nk_size_t i = 0;
131
+
132
+ // Windowed accumulation: outer loop for windows, inner loop for iterations within window
133
+ while (i + 16 <= n) {
134
+ v128_t sum_u8x16 = wasm_i8x16_splat(0);
135
+
136
+ // Inner loop: accumulate up to 31 iterations in u8 (safe: 31 × 1 = 31 < 255)
137
+ nk_size_t cycle = 0;
138
+ for (; cycle < 31 && i + 16 <= n; ++cycle, i += 16) {
139
+ v128_t a_u8x16 = wasm_v128_load(a + i);
140
+ v128_t b_u8x16 = wasm_v128_load(b + i);
141
+
142
+ // Compare for inequality: 0xFF where different, 0x00 where same
143
+ v128_t neq_mask_u8x16 = wasm_i8x16_ne(a_u8x16, b_u8x16);
144
+
145
+ // Convert mask to count: 0xFF → 1, 0x00 → 0
146
+ v128_t neq_count_u8x16 = wasm_v128_and(neq_mask_u8x16, wasm_i8x16_splat(1));
147
+
148
+ // Accumulate counts
149
+ sum_u8x16 = wasm_i8x16_add(sum_u8x16, neq_count_u8x16);
150
+ }
151
+
152
+ // Widen and reduce once per window
153
+ sum_total += nk_reduce_add_u8x16_v128relaxed_(sum_u8x16);
154
+ }
155
+
156
+ // Traditional tail loop: handle remaining bytes (0-15) scalar-style
157
+ for (; i < n; i++) { sum_total += (a[i] != b[i]); }
158
+
159
+ *result = sum_total;
160
+ }
161
+
162
+ NK_PUBLIC void nk_jaccard_u32_v128relaxed(nk_u32_t const *a, nk_u32_t const *b, nk_size_t n, nk_f32_t *result) {
163
+ nk_u32_t matches = 0;
164
+ nk_size_t i = 0;
165
+ v128_t matches_u32x4 = wasm_i32x4_splat(0);
166
+
167
+ for (; i + 4 <= n; i += 4) {
168
+ v128_t a_u32x4 = wasm_v128_load(a + i);
169
+ v128_t b_u32x4 = wasm_v128_load(b + i);
170
+ v128_t eq_mask_u32x4 = wasm_i32x4_eq(a_u32x4, b_u32x4);
171
+ v128_t match_bits_u32x4 = wasm_u32x4_shr(eq_mask_u32x4, 31);
172
+ matches_u32x4 = wasm_i32x4_add(matches_u32x4, match_bits_u32x4);
173
+ }
174
+
175
+ matches += nk_reduce_add_u32x4_v128relaxed_(matches_u32x4);
176
+ for (; i < n; ++i) matches += (a[i] == b[i]);
177
+
178
+ *result = (n != 0) ? 1.0f - (nk_f32_t)matches / (nk_f32_t)n : 0.0f;
179
+ }
180
+
181
+ NK_PUBLIC void nk_jaccard_u16_v128relaxed(nk_u16_t const *a, nk_u16_t const *b, nk_size_t n, nk_f32_t *result) {
182
+ nk_u32_t matches = 0;
183
+ nk_size_t i = 0;
184
+ v128_t matches_u32x4 = wasm_i32x4_splat(0);
185
+
186
+ for (; i + 8 <= n; i += 8) {
187
+ v128_t a_u16x8 = wasm_v128_load(a + i);
188
+ v128_t b_u16x8 = wasm_v128_load(b + i);
189
+ v128_t eq_mask_u16x8 = wasm_i16x8_eq(a_u16x8, b_u16x8);
190
+ v128_t match_bits_u16x8 = wasm_u16x8_shr(eq_mask_u16x8, 15);
191
+ matches_u32x4 = wasm_i32x4_add(matches_u32x4, wasm_u32x4_extadd_pairwise_u16x8(match_bits_u16x8));
192
+ }
193
+
194
+ matches += nk_reduce_add_u32x4_v128relaxed_(matches_u32x4);
195
+ for (; i < n; ++i) matches += (a[i] == b[i]);
196
+
197
+ *result = (n != 0) ? 1.0f - (nk_f32_t)matches / (nk_f32_t)n : 0.0f;
198
+ }
199
+
200
+ #pragma endregion Integer Sets
201
+
202
+ #pragma region Binary Sets from Dot
203
+
204
+ NK_INTERNAL void nk_hamming_u32x4_from_dot_v128relaxed_( //
205
+ nk_b128_vec_t dots, nk_u32_t query_pop, nk_b128_vec_t target_pops, nk_b128_vec_t *results) {
206
+ v128_t dots_u32x4 = dots.v128;
207
+ v128_t query_u32x4 = wasm_u32x4_splat(query_pop);
208
+ v128_t target_u32x4 = target_pops.v128;
209
+ results->v128 = wasm_i32x4_sub(wasm_i32x4_add(query_u32x4, target_u32x4), wasm_i32x4_shl(dots_u32x4, 1));
210
+ }
211
+
212
+ NK_INTERNAL void nk_jaccard_f32x4_from_dot_v128relaxed_( //
213
+ nk_b128_vec_t dots, nk_u32_t query_pop, nk_b128_vec_t target_pops, nk_b128_vec_t *results) {
214
+ v128_t dot_f32x4 = wasm_f32x4_convert_u32x4(dots.v128);
215
+ v128_t query_f32x4 = wasm_f32x4_splat((nk_f32_t)query_pop);
216
+ v128_t target_f32x4 = wasm_f32x4_convert_u32x4(target_pops.v128);
217
+ v128_t union_f32x4 = wasm_f32x4_sub(wasm_f32x4_add(query_f32x4, target_f32x4), dot_f32x4);
218
+
219
+ v128_t zero_f32x4 = wasm_f32x4_splat(0.0f);
220
+ v128_t one_f32x4 = wasm_f32x4_splat(1.0f);
221
+ v128_t zero_mask_u32x4 = wasm_f32x4_eq(union_f32x4, zero_f32x4);
222
+ v128_t safe_union_f32x4 = wasm_i32x4_relaxed_laneselect(one_f32x4, union_f32x4, zero_mask_u32x4);
223
+
224
+ v128_t ratio_f32x4 = wasm_f32x4_div(dot_f32x4, safe_union_f32x4);
225
+ v128_t jaccard_f32x4 = wasm_f32x4_sub(one_f32x4, ratio_f32x4);
226
+ results->v128 = wasm_i32x4_relaxed_laneselect(zero_f32x4, jaccard_f32x4, zero_mask_u32x4);
227
+ }
228
+
229
+ #pragma endregion Binary Sets from Dot
230
+
231
+ #if defined(__clang__)
232
+ #pragma clang attribute pop
233
+ #endif
234
+
235
+ #if defined(__cplusplus)
236
+ } // extern "C"
237
+ #endif
238
+
239
+ #endif // NK_TARGET_V128RELAXED
240
+ #endif // NK_SET_V128RELAXED_H