fuzzgpu 0.1.8__tar.gz → 0.2.0__tar.gz

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 (68) hide show
  1. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/Cargo.lock +2 -2
  2. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/PKG-INFO +14 -7
  3. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/README.md +13 -6
  4. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/Cargo.toml +1 -1
  5. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/benches/bench.rs +60 -16
  6. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/damerau.rs +604 -160
  7. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/fuzz.rs +385 -32
  8. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/gpu.rs +224 -80
  9. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/jaro.rs +925 -251
  10. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/levenshtein.rs +1451 -438
  11. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/lib.rs +23 -16
  12. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/needleman.rs +731 -190
  13. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/simd.rs +451 -132
  14. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/tests/differential.rs +130 -58
  15. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/tests/kernel_registration.rs +18 -14
  16. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-python/Cargo.toml +2 -2
  17. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-python/src/lib.rs +269 -48
  18. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-wasm/Cargo.toml +1 -1
  19. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/pyproject.toml +1 -1
  20. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_api_signatures.py +20 -7
  21. fuzzgpu-0.2.0/tests/test_gpu_health.py +102 -0
  22. fuzzgpu-0.2.0/tests/test_gpu_threshold_env.py +159 -0
  23. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/Cargo.toml +0 -0
  24. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/LICENSE +0 -0
  25. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/assets/logo.png +0 -0
  26. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/damerau.wgsl +0 -0
  27. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/damerau_matrix.wgsl +0 -0
  28. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/jaro.wgsl +0 -0
  29. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/jaro_matrix.wgsl +0 -0
  30. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/levenshtein.wgsl +0 -0
  31. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/levenshtein_cdist_myers.wgsl +0 -0
  32. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/levenshtein_matrix.wgsl +0 -0
  33. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/levenshtein_myers.wgsl +0 -0
  34. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/levenshtein_short.wgsl +0 -0
  35. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/needleman_affine.wgsl +0 -0
  36. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/src/shaders/needleman_wavefront.wgsl +0 -0
  37. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/tests/differential.proptest-regressions +0 -0
  38. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-core/tests/fixtures/broken.wgsl +0 -0
  39. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-wasm/src/lib.rs +0 -0
  40. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-wasm/tests/differential_harness.js +0 -0
  41. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/crates/fuzzgpu-wasm/tests/js_api.test.cjs +0 -0
  42. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/__init__.py +0 -0
  43. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/__init__.pyi +0 -0
  44. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/DamerauLevenshtein.py +0 -0
  45. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/Hamming.py +0 -0
  46. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/Indel.py +0 -0
  47. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/Jaro.py +0 -0
  48. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/JaroWinkler.py +0 -0
  49. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/LCSseq.py +0 -0
  50. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/Levenshtein.py +0 -0
  51. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/OSA.py +0 -0
  52. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/Postfix.py +0 -0
  53. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/Prefix.py +0 -0
  54. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/__init__.py +0 -0
  55. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/__init__.pyi +0 -0
  56. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/distance/_common.py +0 -0
  57. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/fuzz.py +0 -0
  58. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/fuzz.pyi +0 -0
  59. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/process.py +0 -0
  60. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/python/fuzzgpu/process.pyi +0 -0
  61. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_basic.py +0 -0
  62. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_concurrency.py +0 -0
  63. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_edge_cases.py +0 -0
  64. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_invariants.py +0 -0
  65. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_out_buffers.py +0 -0
  66. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_rapidfuzz_compat.py +0 -0
  67. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/test_stress.py +0 -0
  68. {fuzzgpu-0.1.8 → fuzzgpu-0.2.0}/tests/wasm_python_differential.py +0 -0
@@ -372,7 +372,7 @@ dependencies = [
372
372
 
373
373
  [[package]]
374
374
  name = "fuzzgpu-core"
375
- version = "0.1.8"
375
+ version = "0.2.0"
376
376
  dependencies = [
377
377
  "bytemuck",
378
378
  "criterion",
@@ -386,7 +386,7 @@ dependencies = [
386
386
 
387
387
  [[package]]
388
388
  name = "fuzzgpu-python"
389
- version = "0.1.8"
389
+ version = "0.2.0"
390
390
  dependencies = [
391
391
  "fuzzgpu-core",
392
392
  "log",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fuzzgpu
3
- Version: 0.1.8
3
+ Version: 0.2.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -37,7 +37,7 @@ Project-URL: Repository, https://github.com/kuntal-devrat/fuzzgpu
37
37
 
38
38
  *Cross-platform GPU compute via WebGPU (`wgpu`) & Multi-Core CPU parallelism with Rayon. Zero CUDA dependencies.*
39
39
 
40
- [![PyPI Version](https://img.shields.io/badge/pypi-v0.1.8-blue.svg?style=flat-square)](https://pypi.org/project/fuzzgpu/)
40
+ [![PyPI Version](https://img.shields.io/badge/pypi-v0.2.0-blue.svg?style=flat-square)](https://pypi.org/project/fuzzgpu/)
41
41
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://opensource.org/licenses/MIT)
42
42
  [![Rust](https://img.shields.io/badge/rust-1.87+-orange.svg?style=flat-square)](https://www.rust-lang.org)
43
43
  [![Cross Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux%20%7C%20WASM-lightgrey.svg?style=flat-square)](https://github.com/kuntal-devrat/fuzzgpu)
@@ -60,7 +60,7 @@ No NVIDIA CUDA drivers or complex toolkits required.
60
60
 
61
61
  ---
62
62
 
63
- ## What's New in v0.1.8
63
+ ## What's New in v0.2.0
64
64
 
65
65
  ### Production hardening
66
66
  - **Kernel `get()` panics eliminated** — all four GPU kernels (`GpuLevenshteinKernel`,
@@ -163,10 +163,17 @@ The full Python layer is now byte-identical to rapidfuzz 3.14.5 over a 169,744-p
163
163
 
164
164
  ## Benchmark Results
165
165
 
166
- *Hardware: Intel(R) Iris(R) Xe Graphics (Vulkan) + Intel Core i7 (Rayon uses all cores)*
167
- *Versions: fuzzgpu 0.1.8 · rapidfuzz 3.14.5 · python-Levenshtein 0.27.4*
166
+ *Hardware: Intel(R) Iris(R) Xe Graphics — integrated GPU (Vulkan) + Intel Core i7 (Rayon, all cores)*
167
+ *Versions: fuzzgpu 0.2.0 · rapidfuzz 3.14.5 · python-Levenshtein 0.27.4*
168
168
  *Median of 7 runs after warmup. Reproduce: `python benchmarks/bench_compare.py`*
169
169
 
170
+ > **GPU class note:** These numbers are from an **integrated GPU** (iGPU), which shares memory
171
+ > bandwidth with the CPU and has a ~1 ms dispatch round-trip. On a **discrete GPU** (dGPU) the
172
+ > GPU columns improve significantly — expect 3–10× better GPU throughput and GPU routing kicking
173
+ > in at much smaller batch sizes (threshold drops from ~500 pairs to ~64 pairs automatically).
174
+ > Concurrency gains (multiple Python threads, after the wgpu fix ships) add a further 2–4×
175
+ > on top for server workloads regardless of GPU class.
176
+
170
177
  ### Levenshtein Batch (1 query × N candidates, 10-char strings)
171
178
  | Batch Size | `fuzzgpu` (GPU) | `fuzzgpu` (CPU) | `rapidfuzz` | vs RF (GPU) | vs RF (CPU) |
172
179
  | :--- | :---: | :---: | :---: | :---: | :---: |
@@ -222,7 +229,7 @@ pip install fuzzgpu
222
229
  ```toml
223
230
  # Rust
224
231
  [dependencies]
225
- fuzzgpu-core = "0.1.8"
232
+ fuzzgpu-core = "0.2.0"
226
233
  ```
227
234
 
228
235
  ---
@@ -318,7 +325,7 @@ fuzzgpu.set_cpu_only(True) # force CPU-only mode
318
325
 
319
326
  ```toml
320
327
  [dependencies]
321
- fuzzgpu-core = "0.1.8" # GPU + CPU fallback
328
+ fuzzgpu-core = "0.2.0" # GPU + CPU fallback
322
329
  # fuzzgpu-core = { version = "0.1.7", default-features = false } # CPU-only
323
330
  ```
324
331
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  *Cross-platform GPU compute via WebGPU (`wgpu`) & Multi-Core CPU parallelism with Rayon. Zero CUDA dependencies.*
10
10
 
11
- [![PyPI Version](https://img.shields.io/badge/pypi-v0.1.8-blue.svg?style=flat-square)](https://pypi.org/project/fuzzgpu/)
11
+ [![PyPI Version](https://img.shields.io/badge/pypi-v0.2.0-blue.svg?style=flat-square)](https://pypi.org/project/fuzzgpu/)
12
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://opensource.org/licenses/MIT)
13
13
  [![Rust](https://img.shields.io/badge/rust-1.87+-orange.svg?style=flat-square)](https://www.rust-lang.org)
14
14
  [![Cross Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux%20%7C%20WASM-lightgrey.svg?style=flat-square)](https://github.com/kuntal-devrat/fuzzgpu)
@@ -31,7 +31,7 @@ No NVIDIA CUDA drivers or complex toolkits required.
31
31
 
32
32
  ---
33
33
 
34
- ## What's New in v0.1.8
34
+ ## What's New in v0.2.0
35
35
 
36
36
  ### Production hardening
37
37
  - **Kernel `get()` panics eliminated** — all four GPU kernels (`GpuLevenshteinKernel`,
@@ -134,10 +134,17 @@ The full Python layer is now byte-identical to rapidfuzz 3.14.5 over a 169,744-p
134
134
 
135
135
  ## Benchmark Results
136
136
 
137
- *Hardware: Intel(R) Iris(R) Xe Graphics (Vulkan) + Intel Core i7 (Rayon uses all cores)*
138
- *Versions: fuzzgpu 0.1.8 · rapidfuzz 3.14.5 · python-Levenshtein 0.27.4*
137
+ *Hardware: Intel(R) Iris(R) Xe Graphics — integrated GPU (Vulkan) + Intel Core i7 (Rayon, all cores)*
138
+ *Versions: fuzzgpu 0.2.0 · rapidfuzz 3.14.5 · python-Levenshtein 0.27.4*
139
139
  *Median of 7 runs after warmup. Reproduce: `python benchmarks/bench_compare.py`*
140
140
 
141
+ > **GPU class note:** These numbers are from an **integrated GPU** (iGPU), which shares memory
142
+ > bandwidth with the CPU and has a ~1 ms dispatch round-trip. On a **discrete GPU** (dGPU) the
143
+ > GPU columns improve significantly — expect 3–10× better GPU throughput and GPU routing kicking
144
+ > in at much smaller batch sizes (threshold drops from ~500 pairs to ~64 pairs automatically).
145
+ > Concurrency gains (multiple Python threads, after the wgpu fix ships) add a further 2–4×
146
+ > on top for server workloads regardless of GPU class.
147
+
141
148
  ### Levenshtein Batch (1 query × N candidates, 10-char strings)
142
149
  | Batch Size | `fuzzgpu` (GPU) | `fuzzgpu` (CPU) | `rapidfuzz` | vs RF (GPU) | vs RF (CPU) |
143
150
  | :--- | :---: | :---: | :---: | :---: | :---: |
@@ -193,7 +200,7 @@ pip install fuzzgpu
193
200
  ```toml
194
201
  # Rust
195
202
  [dependencies]
196
- fuzzgpu-core = "0.1.8"
203
+ fuzzgpu-core = "0.2.0"
197
204
  ```
198
205
 
199
206
  ---
@@ -289,7 +296,7 @@ fuzzgpu.set_cpu_only(True) # force CPU-only mode
289
296
 
290
297
  ```toml
291
298
  [dependencies]
292
- fuzzgpu-core = "0.1.8" # GPU + CPU fallback
299
+ fuzzgpu-core = "0.2.0" # GPU + CPU fallback
293
300
  # fuzzgpu-core = { version = "0.1.7", default-features = false } # CPU-only
294
301
  ```
295
302
 
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "fuzzgpu-core"
3
- version = "0.1.8"
3
+ version = "0.2.0"
4
4
  edition = "2021"
5
5
  description = "GPU-accelerated fuzzy string matching engine"
6
6
  license = "MIT"
@@ -13,7 +13,9 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
13
13
  use fuzzgpu_core::damerau::damerau_levenshtein_batch;
14
14
  use fuzzgpu_core::fuzz::ratio;
15
15
  use fuzzgpu_core::jaro::{jaro_winkler, jaro_winkler_batch};
16
- use fuzzgpu_core::levenshtein::{levenshtein_cdist_cpu, levenshtein_distance_raw, LevenshteinKernel};
16
+ use fuzzgpu_core::levenshtein::{
17
+ levenshtein_cdist_cpu, levenshtein_distance_raw, LevenshteinKernel,
18
+ };
17
19
  use fuzzgpu_core::needleman::{needleman_wunsch_affine, needleman_wunsch_affine_batch};
18
20
  use fuzzgpu_core::simd::levenshtein_myers;
19
21
 
@@ -24,7 +26,9 @@ fn gen_strings(count: usize, len: usize, seed: u64) -> Vec<String> {
24
26
  for _ in 0..count {
25
27
  let mut s = String::with_capacity(len);
26
28
  for _ in 0..len {
27
- state = state.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
29
+ state = state
30
+ .wrapping_mul(6364136223846793005)
31
+ .wrapping_add(1442695040888963407);
28
32
  s.push((b'a' + ((state >> 33) as u8 % 26)) as char);
29
33
  }
30
34
  out.push(s);
@@ -47,7 +51,11 @@ fn cpu_benches(c: &mut Criterion) {
47
51
  let long = gen_strings(2, 256, 3);
48
52
 
49
53
  let mut g = c.benchmark_group("scalar");
50
- for (name, s) in [("short_8", &short), ("medium_64", &medium), ("long_256", &long)] {
54
+ for (name, s) in [
55
+ ("short_8", &short),
56
+ ("medium_64", &medium),
57
+ ("long_256", &long),
58
+ ] {
51
59
  let (s1, s2) = (&s[0], &s[1]);
52
60
  g.bench_function(format!("levenshtein/{name}"), |b| {
53
61
  b.iter(|| black_box(levenshtein_distance_raw(s1, s2)))
@@ -62,7 +70,11 @@ fn cpu_benches(c: &mut Criterion) {
62
70
  b.iter(|| black_box(ratio(s1, s2)))
63
71
  });
64
72
  g.bench_function(format!("needleman_affine/{name}"), |b| {
65
- b.iter(|| black_box(needleman_wunsch_affine(s1, s2, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND)))
73
+ b.iter(|| {
74
+ black_box(needleman_wunsch_affine(
75
+ s1, s2, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND,
76
+ ))
77
+ })
66
78
  });
67
79
  g.bench_function(format!("damerau/{name}"), |b| {
68
80
  b.iter(|| black_box(fuzzgpu_core::damerau::damerau_levenshtein_distance(s1, s2)))
@@ -89,14 +101,27 @@ fn cpu_benches(c: &mut Criterion) {
89
101
  b.iter(|| black_box(jaro_winkler_batch(query, &cand_refs, 0.1)))
90
102
  });
91
103
  g.bench_function("needleman_affine_batch_1000", |b| {
92
- b.iter(|| black_box(needleman_wunsch_affine_batch(query, &cand_refs, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND)))
104
+ b.iter(|| {
105
+ black_box(needleman_wunsch_affine_batch(
106
+ query, &cand_refs, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND,
107
+ ))
108
+ })
93
109
  });
94
110
  // Long-string needleman (80 chars): the anti-diagonal wavefront GPU path's
95
111
  // target workload; Rayon CPU is the comparison baseline.
96
112
  let cands_nw80 = gen_strings(1000, 80, 0xAB);
97
113
  let cand_refs_nw80: Vec<&str> = cands_nw80.iter().map(|s| s.as_str()).collect();
98
114
  g.bench_function("needleman_affine_batch_1000_long80_large", |b| {
99
- b.iter(|| black_box(needleman_wunsch_affine_batch(query, &cand_refs_nw80, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND)))
115
+ b.iter(|| {
116
+ black_box(needleman_wunsch_affine_batch(
117
+ query,
118
+ &cand_refs_nw80,
119
+ MATCH,
120
+ MISMATCH,
121
+ GAP_OPEN,
122
+ GAP_EXTEND,
123
+ ))
124
+ })
100
125
  });
101
126
  g.bench_function("damerau_batch_1000", |b| {
102
127
  b.iter(|| black_box(damerau_levenshtein_batch(query, &cand_refs)))
@@ -128,8 +153,9 @@ fn cpu_benches(c: &mut Criterion) {
128
153
  b.iter(|| black_box(levenshtein_cdist_cpu(&refs_a_1k, &refs_b_1k)))
129
154
  });
130
155
  // Sequential 10 x 1000 pairs: the CPU baseline for the batched-GPU bench.
131
- let cands10: Vec<Vec<String>> =
132
- (0..10).map(|i| gen_strings(1000, 16, 0x100 + i as u64)).collect();
156
+ let cands10: Vec<Vec<String>> = (0..10)
157
+ .map(|i| gen_strings(1000, 16, 0x100 + i as u64))
158
+ .collect();
133
159
  let ops10: Vec<Vec<(&str, &str)>> = cands10.iter().map(|c| make_pairs(query, c)).collect();
134
160
  g.bench_function("levenshtein_10x1000_seq_cpu", |b| {
135
161
  b.iter(|| {
@@ -190,13 +216,23 @@ fn gpu_benches(c: &mut Criterion) {
190
216
  match GpuNeedlemanAffineKernel::get() {
191
217
  Ok(kernel) => {
192
218
  g.bench_function("needleman_affine_batch_1000", |b| {
193
- b.iter(|| black_box(kernel.compute_batch(&pairs, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND)))
219
+ b.iter(|| {
220
+ black_box(kernel.compute_batch(&pairs, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND))
221
+ })
194
222
  });
195
223
  // 80-char pairs: routes to the anti-diagonal wavefront kernel.
196
224
  let cands_nw80 = gen_strings(1000, 80, 0xAB);
197
225
  let pairs_nw80 = make_pairs(query, &cands_nw80);
198
226
  g.bench_function("needleman_affine_batch_1000_long80_large", |b| {
199
- b.iter(|| black_box(kernel.compute_batch(&pairs_nw80, MATCH, MISMATCH, GAP_OPEN, GAP_EXTEND)))
227
+ b.iter(|| {
228
+ black_box(kernel.compute_batch(
229
+ &pairs_nw80,
230
+ MATCH,
231
+ MISMATCH,
232
+ GAP_OPEN,
233
+ GAP_EXTEND,
234
+ ))
235
+ })
200
236
  });
201
237
  }
202
238
  Err(e) => {
@@ -247,9 +283,11 @@ fn gpu_benches(c: &mut Criterion) {
247
283
  });
248
284
  // 10 x 1000 pairs: one batched dispatch+readback vs 10 sequential
249
285
  // sync-round-trips. Same total work as cpu_batch/..._seq_cpu.
250
- let cands10: Vec<Vec<String>> =
251
- (0..10).map(|i| gen_strings(1000, 16, 0x100 + i as u64)).collect();
252
- let ops10: Vec<Vec<(&str, &str)>> = cands10.iter().map(|c| make_pairs(query, c)).collect();
286
+ let cands10: Vec<Vec<String>> = (0..10)
287
+ .map(|i| gen_strings(1000, 16, 0x100 + i as u64))
288
+ .collect();
289
+ let ops10: Vec<Vec<(&str, &str)>> =
290
+ cands10.iter().map(|c| make_pairs(query, c)).collect();
253
291
  g.bench_function("levenshtein_10x1000_seq", |b| {
254
292
  b.iter(|| {
255
293
  for op in &ops10 {
@@ -268,10 +306,16 @@ fn gpu_benches(c: &mut Criterion) {
268
306
  });
269
307
  }
270
308
  Err(e) => {
271
- eprintln!("WARN: no GPU device, skipping large-scale GpuLevenshteinKernel benches: {e}");
309
+ eprintln!(
310
+ "WARN: no GPU device, skipping large-scale GpuLevenshteinKernel benches: {e}"
311
+ );
272
312
  g.bench_function("levenshtein_batch_100k_large", |b| b.iter(|| black_box(0)));
273
- g.bench_function("levenshtein_batch_1000_long256_large", |b| b.iter(|| black_box(0)));
274
- g.bench_function("levenshtein_cdist_1000x1000_large", |b| b.iter(|| black_box(0)));
313
+ g.bench_function("levenshtein_batch_1000_long256_large", |b| {
314
+ b.iter(|| black_box(0))
315
+ });
316
+ g.bench_function("levenshtein_cdist_1000x1000_large", |b| {
317
+ b.iter(|| black_box(0))
318
+ });
275
319
  g.bench_function("levenshtein_10x1000_seq", |b| b.iter(|| black_box(0)));
276
320
  g.bench_function("levenshtein_10x1000_batched", |b| b.iter(|| black_box(0)));
277
321
  }