1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! wasm-bindgen JS bindings for browser-hosted embedding generation.
//!
//! Exposes a minimal surface: construct a [`LatticeEmbedder`] from in-memory
//! model bytes (no filesystem, no network access: the caller fetches or
//! otherwise holds the bytes on the JS side), then call [`LatticeEmbedder::embed`]
//! to get an L2-normalized embedding vector for a string.
//!
//! This wraps `lattice_inference::BertModel::from_bytes`, which itself avoids
//! `std::fs`/`mmap` entirely. That is required, not incidental:
//! `wasm32-unknown-unknown` has no real filesystem, and `memmap2`'s wasm
//! fallback compiles but every `Mmap::map` call returns
//! `io::ErrorKind::Unsupported` at runtime (see `SafetensorsFile::from_bytes`'s
//! doc comment in `lattice-inference`). Everything in this module runs
//! synchronously in memory: there is no `spawn_blocking`, disk cache, or
//! download path here; those belong to `NativeEmbeddingService` and stay
//! native-only.
use ;
use *;
/// Install a panic hook that forwards Rust panics to the browser console via
/// `console.error`, instead of the opaque default
/// `"unreachable executed"` wasm trap message.
///
/// Call this once, before constructing a [`LatticeEmbedder`], if you want
/// readable panic diagnostics. Safe to call more than once (`set_once` is
/// idempotent) and safe to skip entirely.
/// A loaded BERT-family embedding model, ready to embed text.
///
/// Constructed from in-memory model bytes, see [`LatticeEmbedder::new`].
/// Defaults to mean pooling; call [`LatticeEmbedder::use_cls_pooling`] for
/// BGE-family models, which expect CLS-token pooling instead (see
/// `lattice_inference::BertPooling`'s doc comment for the per-model-family
/// table).
// ---------------------------------------------------------------------------
// Vector-op bindings: expose `simd::*` directly to JS/wasm callers.
//
// Unrelated to `LatticeEmbedder` above (which wraps the BERT-family forward
// pass). These four are the `simd::*` khive ANN consumer contract
// (`dot_product`, `squared_euclidean_distance`, `cosine_similarity`,
// `normalize`; see `lib.rs`'s crate-level doc comment) made callable from JS,
// so a wasm/JS consumer benefits from the same SIMD128 kernels a native
// consumer gets, instead of falling back to a hand-rolled JS loop. Also the
// entry points `scripts/bench_wasm_simd.mjs` calls for its A/B measurement.
// ---------------------------------------------------------------------------
/// Dot product of two equal-length vectors via `simd::dot_product`.
///
/// Dispatches to the wasm32 SIMD128 kernel when this crate is built with
/// `-C target-feature=+simd128`, otherwise falls back to the scalar
/// implementation. Returns `0.0` if `a` and `b` have different lengths.
/// Squared Euclidean (L2) distance between two equal-length vectors via
/// `simd::squared_euclidean_distance`.
///
/// Skips the final square root (see the Rust docs on
/// [`crate::simd::squared_euclidean_distance`] for the ordering invariant
/// this preserves). Returns `f32::MAX` if `a` and `b` have different lengths.
/// Cosine similarity of two equal-length, non-empty vectors via
/// `simd::cosine_similarity`.
///
/// Returns a value in `[-1.0, 1.0]`, or `0.0` for empty or mismatched-length
/// inputs.
/// L2-normalize a vector in place via `simd::normalize`.
///
/// Leaves the vector unchanged if its norm is zero or NaN (matches the
/// scalar reference; see `simd::normalize`'s doc comment).
/// Reports whether the four `simd*` bindings above are dispatching to the
/// wasm32 SIMD128 kernels in *this* build.
///
/// Returns the exact same value the kernels themselves read to choose a
/// codepath (`crate::simd::simd_config().simd128_enabled()`), not a fresh
/// `cfg!(target_feature = "simd128")` re-derived here -- a binding-local
/// re-check could drift from the real dispatch condition without anyone
/// noticing. Exists so a two-build parity harness (one plain
/// `wasm32-unknown-unknown` build, one built with
/// `-C target-feature=+simd128`) can assert the SIMD128 build is actually
/// exercising the SIMD128 kernels instead of a stale or misconfigured
/// artifact silently falling back to scalar; see
/// `crates/embed/tests/wasm/simd128_parity_wasm.mjs`.