fuzzgpu 0.1.0__cp39-abi3-win_amd64.whl

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.
LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Flaxmbot
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,225 @@
1
+ <div align="center">
2
+
3
+ <img src="https://raw.githubusercontent.com/kuntal-devrat/fuzzgpu/main/assets/logo.png" alt="fuzzgpu logo" width="140" height="140" />
4
+
5
+ # fuzzgpu
6
+
7
+ **Hardware-Accelerated Fuzzy String Matching & Sequence Alignment**
8
+
9
+ *Cross-platform GPU compute via WebGPU (`wgpu`) & Multi-Core CPU parallelism with Rayon. Zero CUDA dependencies.*
10
+
11
+ [![PyPI Version](https://img.shields.io/badge/pypi-v0.1.0-blue.svg?style=flat-square)](https://pypi.org/project/fuzzgpu/)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://opensource.org/licenses/MIT)
13
+ [![Rust](https://img.shields.io/badge/rust-1.75+-orange.svg?style=flat-square)](https://www.rust-lang.org)
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)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ `fuzzgpu` is a high-throughput string distance and sequence alignment engine written in **Rust** with native **Python** and **WebAssembly** bindings. It leverages GPU compute shaders (`wgpu` / WGSL) and Rayon multi-threading to accelerate large-scale batch queries and distance matrix computations across:
23
+
24
+ - **Apple Silicon (Metal)**
25
+ - **Linux (Vulkan)**
26
+ - **Windows (DirectX 12 / Vulkan)**
27
+ - **Integrated GPUs (Intel Iris Xe, AMD Radeon)**
28
+ - **WebAssembly (In-browser execution)**
29
+
30
+ No NVIDIA CUDA drivers or complex toolkits required.
31
+
32
+ ---
33
+
34
+ ## Benchmark Results
35
+
36
+ *Hardware: Intel(R) Iris(R) Xe Graphics (Vulkan) / Intel Core i7 CPU*
37
+
38
+ ### 1. Damerau-Levenshtein Batch (1 Query × N Candidates)
39
+ | Batch Size | `fuzzgpu` | `rapidfuzz` | `python-Levenshtein` | Speedup vs RapidFuzz |
40
+ | :--- | :---: | :---: | :---: | :---: |
41
+ | **100** | **0.21 ms** | 0.36 ms | N/A | **1.74×** |
42
+ | **1,000** | **0.96 ms** | 3.72 ms | N/A | **3.88×** |
43
+ | **5,000** | **3.67 ms** | 18.44 ms | N/A | **5.02×** |
44
+ | **10,000** | **5.95 ms** | 37.46 ms | N/A | **6.30×** |
45
+ | **50,000** | **31.74 ms** | 85.87 ms | N/A | **2.71×** |
46
+
47
+ ### 2. Levenshtein Cross-Product Matrix (`cdist` $N \times M$)
48
+ *Utilizing dedicated 2D Grid Workgroup Shaders with $O(N + M)$ memory bandwidth:*
49
+ | Matrix Size | Total Pairs | `fuzzgpu` | `rapidfuzz` | `python-Levenshtein` | Speedup vs RF | Speedup vs py-Lev |
50
+ | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
51
+ | **10 × 10** | 100 | **0.04 ms** | 0.04 ms | 0.05 ms | 1.00× | **1.31×** |
52
+ | **50 × 50** | 2,500 | **2.22 ms** | 0.71 ms | 0.99 ms | 0.32× | 0.45× |
53
+ | **100 × 100** | 10,000 | **5.29 ms** | 3.51 ms | 4.03 ms | 0.66× | 0.76× |
54
+ | **200 × 200** | 40,000 | **15.05 ms** | 33.58 ms | 46.82 ms | **2.23×** | **3.11×** |
55
+
56
+ ### 3. Jaro-Winkler Similarity Batch
57
+ | Batch Size | `fuzzgpu` | `rapidfuzz` | `python-Levenshtein` | Speedup vs RapidFuzz |
58
+ | :--- | :---: | :---: | :---: | :---: |
59
+ | **1,000** | **3.10 ms** | 0.81 ms | 1.13 ms | 0.26× |
60
+ | **5,000** | **6.56 ms** | 5.12 ms | 5.78 ms | 0.78× |
61
+ | **10,000** | **8.56 ms** | 7.80 ms | 9.17 ms | 0.91× |
62
+ | **50,000** | **33.24 ms** | 47.11 ms | 24.86 ms | **1.42×** |
63
+
64
+ ---
65
+
66
+ ## Installation
67
+
68
+ ### Python
69
+ ```bash
70
+ pip install fuzzgpu
71
+ ```
72
+
73
+ ### Rust (Cargo.toml)
74
+ ```toml
75
+ [dependencies]
76
+ fuzzgpu-core = "0.1.0"
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Quickstart
82
+
83
+ ```python
84
+ import fuzzgpu
85
+ from fuzzgpu.fuzz import ratio, partial_ratio, token_sort_ratio, token_set_ratio, extract, extractOne
86
+
87
+ # 1. Classical Distance Metrics
88
+ lev = fuzzgpu.levenshtein_distance("kitten", "sitting") # 3
89
+ dam = fuzzgpu.damerau_levenshtein_distance("ab", "ba") # 1 (transposition-aware)
90
+ jw = fuzzgpu.jaro_winkler_similarity("MARTHA", "MARHTA", 0.1) # 0.9611
91
+
92
+ # 2. High-Throughput Batch Processing (Auto-dispatched to GPU/CPU)
93
+ candidates = ["hallo", "hullo", "jello", "yellow", "hello world"] * 10_000
94
+ distances = fuzzgpu.levenshtein_batch("hello", candidates)
95
+ jw_scores = fuzzgpu.jaro_winkler_batch("hello", candidates, prefix_weight=0.1)
96
+
97
+ # 3. 2D Cross-Product Distance Matrix (Dedicated 2D Grid Shader)
98
+ matrix = fuzzgpu.levenshtein_cdist(["abc", "def", "xyz"], ["abd", "axy", "def"])
99
+
100
+ # 4. Global Sequence Alignment (Gotoh 1982 Linear & Affine Gap Penalties)
101
+ score_linear = fuzzgpu.needleman_wunsch_score("AGTACGCA", "TATGC", match=2, mismatch=-1, gap=-2)
102
+ score_affine = fuzzgpu.needleman_wunsch_affine("AGTACGCA", "TATGC", match=2, mismatch=-1, gap_open=-3, gap_extend=-1)
103
+
104
+ # 5. RapidFuzz-Compatible Scorer & Search API
105
+ score = ratio("fuzzy was a bear", "fuzzy was a bear") # 100.0
106
+ part = partial_ratio("hello", "oh hello there") # 100.0
107
+ tsr = token_sort_ratio("new york mets", "mets new york") # 100.0
108
+ tset = token_set_ratio("fuzzy was a bear", "fuzzy bear") # 100.0
109
+
110
+ # 6. Top-K Best Match Search
111
+ best = extractOne("hellp", ["hello", "world", "help"], score_cutoff=50.0)
112
+ # Output: ("hello", 80.0, 0)
113
+
114
+ top_3 = extract("apple", ["apply", "ape", "banana", "applesauce"], score_cutoff=50.0, limit=3)
115
+
116
+ # 7. Hardware Diagnostics
117
+ print(fuzzgpu.gpu_info())
118
+ # Output: Intel(R) Iris(R) Xe Graphics (Vulkan) / Apple M2 (Metal)
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Technical Architecture
124
+
125
+ `fuzzgpu` combines a tiered execution pipeline to balance low-latency single queries and high-throughput batch workloads:
126
+
127
+ ```
128
+ ┌──────────────────────────┐
129
+ │ User Query / API │
130
+ └─────────────┬────────────┘
131
+ │
132
+ Batch Size / Dataset Assessment
133
+ │
134
+ ┌───────────────────────┴───────────────────────┐
135
+ ▼ ▼
136
+ Small Workloads (< 500) Large Batches (≥ 500)
137
+ │ │
138
+ ┌───────────────────────────┐ ┌───────────────────────────┐
139
+ │ Rayon Multi-Threaded │ │ wgpu WebGPU Compute │
140
+ │ CPU Parallelism │ │ Shaders (Metal/Vulkan) │
141
+ │ - Myers 1999 Bit-Vector │ │ - 2D Workgroup Grids │
142
+ │ - Zero PCIe Latency │ │ - Streaming Chunking │
143
+ └───────────────────────────┘ └───────────────────────────┘
144
+ ```
145
+
146
+ ### Key Architectural Optimizations
147
+
148
+ 1. **2D Grid Matrix Shaders (`levenshtein_matrix.wgsl` & `jaro_matrix.wgsl`)**:
149
+ Instead of duplicating string pairs across PCIe ($O(N \cdot M)$ transfers), List A and List B are uploaded once ($O(N + M)$ memory bandwidth). Workgroups execute on a 2D grid (`@workgroup_size(16, 16)`).
150
+ 2. **Myers (1999) Bit-Parallel CPU Engine**:
151
+ For strings $\le 64$ characters, computes Levenshtein edit distance using bit-vector operations with zero inner dynamic programming loops ($O(N)$ execution).
152
+ 3. **Lowrance & Wagner (1975) Unrestricted Damerau-Levenshtein**:
153
+ Full support for character insertions, deletions, substitutions, and arbitrary transpositions.
154
+ 4. **Gotoh (1982) Affine Gap Sequence Alignment**:
155
+ Memory-efficient 3-state recurrence ($O(N)$ auxiliary space) for bioinformatics and long-sequence alignment.
156
+ 5. **Streaming Chunk Partitioner**:
157
+ Datasets exceeding GPU buffer limits (>128MB or >500,000 pairs) are automatically streamed in chunks to prevent VRAM overflow.
158
+
159
+ ---
160
+
161
+ ## Project Structure
162
+
163
+ ```
164
+ fuzzgpu/
165
+ ├── assets/
166
+ │ └── logo.svg # Vector brand asset
167
+ ├── crates/
168
+ │ ├── fuzzgpu-core/ # Core Rust engine & compute shaders
169
+ │ │ ├── src/
170
+ │ │ │ ├── gpu.rs # wgpu instance and device singleton
171
+ │ │ │ ├── levenshtein.rs # Levenshtein kernel & 2D matrix dispatch
172
+ │ │ │ ├── damerau.rs # Lowrance-Wagner Damerau-Levenshtein
173
+ │ │ │ ├── needleman.rs # Needleman-Wunsch (Linear & Affine)
174
+ │ │ │ ├── jaro.rs # Jaro / Jaro-Winkler GPU & CPU kernels
175
+ │ │ │ ├── fuzz.rs # Fuzzy ratio, token sort/set, extract
176
+ │ │ │ ├── simd.rs # Myers bit-vector algorithms
177
+ │ │ │ └── shaders/ # WGSL compute shaders (1D & 2D)
178
+ │ ├── fuzzgpu-python/ # PyO3 CPython C-extension module
179
+ │ └── fuzzgpu-wasm/ # wasm-bindgen WebAssembly module
180
+ ├── python/
181
+ │ └── fuzzgpu/ # Python package wrapper & typing
182
+ ├── tests/
183
+ │ └── test_basic.py # Comprehensive test suite (50 tests)
184
+ └── benchmarks/
185
+ └── bench_compare.py # Comparative benchmarking harness
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Building from Source
191
+
192
+ ### Prerequisites
193
+ - [Rust Toolchain (1.75+)](https://rustup.rs/)
194
+ - Python 3.8+ & `pip install maturin`
195
+
196
+ ### Build Python Extension
197
+ ```bash
198
+ # Clone the repository
199
+ git clone https://github.com/Flaxmbot/fuzzgpu.git
200
+ cd fuzzgpu
201
+
202
+ # Build and install into current virtual environment
203
+ maturin develop --release
204
+ ```
205
+
206
+ ### Run Tests & Benchmarks
207
+ ```bash
208
+ # Run pytest verification suite
209
+ pytest tests/ -v
210
+
211
+ # Run comparative benchmark harness
212
+ python benchmarks/bench_compare.py
213
+ ```
214
+
215
+ ### Build WebAssembly (Browser Target)
216
+ ```bash
217
+ cd crates/fuzzgpu-wasm
218
+ wasm-pack build --target web --release
219
+ ```
220
+
221
+ ---
222
+
223
+ ## License
224
+
225
+ This project is licensed under the [MIT License](LICENSE).
assets/logo.png ADDED
Binary file
assets/logo.svg ADDED
@@ -0,0 +1,46 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="100%" height="100%" fill="none">
2
+ <!-- Background Rounded Canvas -->
3
+ <rect width="256" height="256" rx="56" fill="#F8F9FA"/>
4
+ <rect x="8" y="8" width="240" height="240" rx="48" stroke="#E8EAED" stroke-width="4"/>
5
+
6
+ <!-- GPU Compute Core / String Matrix Geometry -->
7
+ <g transform="translate(48, 48)">
8
+ <!-- Base Silicon Chip Shadow / Accent -->
9
+ <rect x="0" y="0" width="160" height="160" rx="32" fill="#FFFFFF" stroke="#DADCE0" stroke-width="6"/>
10
+
11
+ <!-- Geometric Grid Rays & Hardware Pins -->
12
+ <rect x="36" y="-12" width="12" height="12" rx="4" fill="#1A73E8"/>
13
+ <rect x="74" y="-12" width="12" height="12" rx="4" fill="#1A73E8"/>
14
+ <rect x="112" y="-12" width="12" height="12" rx="4" fill="#1A73E8"/>
15
+
16
+ <rect x="36" y="160" width="12" height="12" rx="4" fill="#34A853"/>
17
+ <rect x="74" y="160" width="12" height="12" rx="4" fill="#34A853"/>
18
+ <rect x="112" y="160" width="12" height="12" rx="4" fill="#34A853"/>
19
+
20
+ <rect x="-12" y="36" width="12" height="12" rx="4" fill="#EA4335"/>
21
+ <rect x="-12" y="74" width="12" height="12" rx="4" fill="#EA4335"/>
22
+ <rect x="-12" y="112" width="12" height="12" rx="4" fill="#EA4335"/>
23
+
24
+ <rect x="160" y="36" width="12" height="12" rx="4" fill="#FBBC04"/>
25
+ <rect x="160" y="74" width="12" height="12" rx="4" fill="#FBBC04"/>
26
+ <rect x="160" y="112" width="12" height="12" rx="4" fill="#FBBC04"/>
27
+
28
+ <!-- Central Parallel Compute Lattice / "F" and Lightning Node -->
29
+ <!-- Top Bar: Google Blue -->
30
+ <rect x="32" y="32" width="96" height="24" rx="8" fill="#1A73E8"/>
31
+
32
+ <!-- Middle Stem: Google Coral Red -->
33
+ <rect x="32" y="32" width="24" height="96" rx="8" fill="#EA4335"/>
34
+
35
+ <!-- Middle Horizontal Branch: Google Amber -->
36
+ <rect x="32" y="68" width="68" height="22" rx="8" fill="#FBBC04"/>
37
+
38
+ <!-- High-Performance Acceleration Arrow / String Match Wave: Google Emerald Green -->
39
+ <path d="M72 108 L114 108 L128 122 L114 136 L72 136 Z" fill="#34A853"/>
40
+
41
+ <!-- Inner Core Processor Node -->
42
+ <circle cx="114" cy="44" r="7" fill="#FFFFFF"/>
43
+ <circle cx="86" cy="79" r="6" fill="#FFFFFF"/>
44
+ <circle cx="106" cy="122" r="5" fill="#FFFFFF"/>
45
+ </g>
46
+ </svg>
fuzzgpu/__init__.py ADDED
@@ -0,0 +1,96 @@
1
+ """
2
+ fuzzgpu - GPU-accelerated fuzzy string matching.
3
+
4
+ Cross-platform GPU acceleration via wgpu (Metal, Vulkan, DX12).
5
+ No CUDA required. Works on Mac, Linux, Windows.
6
+
7
+ Usage:
8
+ import fuzzgpu
9
+
10
+ # Levenshtein & Damerau-Levenshtein
11
+ dist = fuzzgpu.levenshtein_distance("kitten", "sitting") # 3
12
+ dam = fuzzgpu.damerau_levenshtein_distance("ab", "ba") # 1
13
+
14
+ # Batch & Cross-product Matrix
15
+ distances = fuzzgpu.levenshtein_batch("hello", ["hallo", "hullo"])
16
+ matrix = fuzzgpu.levenshtein_cdist(["abc", "def"], ["abc", "xyz"])
17
+
18
+ # Needleman-Wunsch with linear or affine gap penalty
19
+ score = fuzzgpu.needleman_wunsch_score("AGTACGCA", "TATGC", 2, -1, -2)
20
+ score_affine = fuzzgpu.needleman_wunsch_affine("AGTACGCA", "TATGC", 2, -1, -3, -1)
21
+
22
+ # Jaro-Winkler similarity (GPU-accelerated for batches)
23
+ sim = fuzzgpu.jaro_winkler_similarity("MARTHA", "MARHTA", 0.1) # 0.96
24
+ jw_batch = fuzzgpu.jaro_winkler_batch("MARTHA", ["MARHTA", "MATRH"], 0.1)
25
+
26
+ # Fuzzy matching (rapidfuzz-compatible)
27
+ from fuzzgpu.fuzz import ratio, partial_ratio, token_sort_ratio, token_set_ratio, extract, extractOne
28
+ """
29
+
30
+ from fuzzgpu.fuzzgpu import (
31
+ # Levenshtein
32
+ levenshtein_distance,
33
+ levenshtein_batch,
34
+ levenshtein_cdist,
35
+ # Damerau-Levenshtein
36
+ damerau_levenshtein_distance,
37
+ damerau_levenshtein_batch,
38
+ damerau_levenshtein_cdist,
39
+ damerau_ratio,
40
+ # Needleman-Wunsch
41
+ needleman_wunsch_score,
42
+ needleman_wunsch_batch_fn,
43
+ needleman_wunsch_affine,
44
+ needleman_wunsch_affine_batch,
45
+ # Jaro-Winkler
46
+ jaro_similarity,
47
+ jaro_winkler_similarity,
48
+ jaro_winkler_batch_fn,
49
+ jaro_winkler_cdist,
50
+ # Fuzzy matching
51
+ fuzz_ratio,
52
+ fuzz_partial_ratio,
53
+ fuzz_token_sort_ratio,
54
+ fuzz_token_set_ratio,
55
+ fuzz_wratio,
56
+ fuzz_ratio_batch,
57
+ fuzz_extract,
58
+ fuzz_extract_one,
59
+ # Optimized algorithm variants
60
+ levenshtein_myers,
61
+ needleman_wunsch_striped,
62
+ jaro_optimized,
63
+ # GPU
64
+ gpu_info,
65
+ __version__,
66
+ )
67
+
68
+ # Re-export with clean names
69
+ levenshtein = levenshtein_distance
70
+ damerau_levenshtein = damerau_levenshtein_distance
71
+ needleman_wunsch = needleman_wunsch_score
72
+ needleman_wunsch_batch = needleman_wunsch_batch_fn
73
+ jaro_winkler_batch = jaro_winkler_batch_fn
74
+ ratio = fuzz_ratio
75
+ partial_ratio = fuzz_partial_ratio
76
+ token_sort_ratio = fuzz_token_sort_ratio
77
+ token_set_ratio = fuzz_token_set_ratio
78
+ wratio = fuzz_wratio
79
+ ratio_batch = fuzz_ratio_batch
80
+ extract = fuzz_extract
81
+ extractOne = fuzz_extract_one
82
+
83
+ __all__ = [
84
+ "levenshtein_distance", "levenshtein_batch", "levenshtein_cdist",
85
+ "damerau_levenshtein_distance", "damerau_levenshtein_batch", "damerau_levenshtein_cdist", "damerau_ratio",
86
+ "needleman_wunsch_score", "needleman_wunsch_batch_fn", "needleman_wunsch_affine", "needleman_wunsch_affine_batch",
87
+ "jaro_similarity", "jaro_winkler_similarity", "jaro_winkler_batch_fn", "jaro_winkler_cdist",
88
+ "fuzz_ratio", "fuzz_partial_ratio", "fuzz_token_sort_ratio", "fuzz_token_set_ratio",
89
+ "fuzz_wratio", "fuzz_ratio_batch", "fuzz_extract", "fuzz_extract_one",
90
+ "levenshtein_myers", "needleman_wunsch_striped", "jaro_optimized",
91
+ "gpu_info", "__version__",
92
+ # Aliases
93
+ "levenshtein", "damerau_levenshtein", "needleman_wunsch", "needleman_wunsch_batch",
94
+ "jaro_winkler_batch", "ratio", "partial_ratio", "token_sort_ratio", "token_set_ratio",
95
+ "wratio", "ratio_batch", "extract", "extractOne",
96
+ ]
fuzzgpu/fuzz.py ADDED
@@ -0,0 +1,18 @@
1
+ """rapidfuzz-compatible API for fuzzgpu — delegates to Rust implementations."""
2
+
3
+ from fuzzgpu.fuzzgpu import (
4
+ fuzz_ratio as ratio,
5
+ fuzz_partial_ratio as partial_ratio,
6
+ fuzz_token_sort_ratio as token_sort_ratio,
7
+ fuzz_token_set_ratio as token_set_ratio,
8
+ fuzz_wratio as WRatio,
9
+ fuzz_ratio_batch as ratio_batch,
10
+ fuzz_extract as extract,
11
+ fuzz_extract_one as extractOne,
12
+ damerau_ratio as damerau_ratio,
13
+ )
14
+
15
+ __all__ = [
16
+ "ratio", "partial_ratio", "token_sort_ratio", "token_set_ratio",
17
+ "WRatio", "ratio_batch", "extract", "extractOne", "damerau_ratio",
18
+ ]
fuzzgpu/fuzzgpu.pyd ADDED
Binary file
@@ -0,0 +1,253 @@
1
+ Metadata-Version: 2.4
2
+ Name: fuzzgpu
3
+ Version: 0.1.0
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Rust
14
+ Classifier: Topic :: Scientific/Engineering
15
+ Classifier: Topic :: Text Processing :: General
16
+ License-File: LICENSE
17
+ Summary: Hardware-accelerated fuzzy string matching & sequence alignment — cross-platform, no CUDA required
18
+ Keywords: gpu,fuzzy,string-matching,levenshtein,damerau,jaro-winkler,needleman-wunsch,webgpu
19
+ Home-Page: https://github.com/kuntal-devrat/fuzzgpu
20
+ Author: Devrat Kuntal
21
+ License: MIT
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
24
+ Project-URL: Homepage, https://github.com/kuntal-devrat/fuzzgpu
25
+ Project-URL: Issues, https://github.com/kuntal-devrat/fuzzgpu/issues
26
+ Project-URL: Repository, https://github.com/kuntal-devrat/fuzzgpu
27
+
28
+ <div align="center">
29
+
30
+ <img src="https://raw.githubusercontent.com/kuntal-devrat/fuzzgpu/main/assets/logo.png" alt="fuzzgpu logo" width="140" height="140" />
31
+
32
+ # fuzzgpu
33
+
34
+ **Hardware-Accelerated Fuzzy String Matching & Sequence Alignment**
35
+
36
+ *Cross-platform GPU compute via WebGPU (`wgpu`) & Multi-Core CPU parallelism with Rayon. Zero CUDA dependencies.*
37
+
38
+ [![PyPI Version](https://img.shields.io/badge/pypi-v0.1.0-blue.svg?style=flat-square)](https://pypi.org/project/fuzzgpu/)
39
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://opensource.org/licenses/MIT)
40
+ [![Rust](https://img.shields.io/badge/rust-1.75+-orange.svg?style=flat-square)](https://www.rust-lang.org)
41
+ [![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)
42
+
43
+ </div>
44
+
45
+ ---
46
+
47
+ ## Overview
48
+
49
+ `fuzzgpu` is a high-throughput string distance and sequence alignment engine written in **Rust** with native **Python** and **WebAssembly** bindings. It leverages GPU compute shaders (`wgpu` / WGSL) and Rayon multi-threading to accelerate large-scale batch queries and distance matrix computations across:
50
+
51
+ - **Apple Silicon (Metal)**
52
+ - **Linux (Vulkan)**
53
+ - **Windows (DirectX 12 / Vulkan)**
54
+ - **Integrated GPUs (Intel Iris Xe, AMD Radeon)**
55
+ - **WebAssembly (In-browser execution)**
56
+
57
+ No NVIDIA CUDA drivers or complex toolkits required.
58
+
59
+ ---
60
+
61
+ ## Benchmark Results
62
+
63
+ *Hardware: Intel(R) Iris(R) Xe Graphics (Vulkan) / Intel Core i7 CPU*
64
+
65
+ ### 1. Damerau-Levenshtein Batch (1 Query × N Candidates)
66
+ | Batch Size | `fuzzgpu` | `rapidfuzz` | `python-Levenshtein` | Speedup vs RapidFuzz |
67
+ | :--- | :---: | :---: | :---: | :---: |
68
+ | **100** | **0.21 ms** | 0.36 ms | N/A | **1.74×** |
69
+ | **1,000** | **0.96 ms** | 3.72 ms | N/A | **3.88×** |
70
+ | **5,000** | **3.67 ms** | 18.44 ms | N/A | **5.02×** |
71
+ | **10,000** | **5.95 ms** | 37.46 ms | N/A | **6.30×** |
72
+ | **50,000** | **31.74 ms** | 85.87 ms | N/A | **2.71×** |
73
+
74
+ ### 2. Levenshtein Cross-Product Matrix (`cdist` $N \times M$)
75
+ *Utilizing dedicated 2D Grid Workgroup Shaders with $O(N + M)$ memory bandwidth:*
76
+ | Matrix Size | Total Pairs | `fuzzgpu` | `rapidfuzz` | `python-Levenshtein` | Speedup vs RF | Speedup vs py-Lev |
77
+ | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
78
+ | **10 × 10** | 100 | **0.04 ms** | 0.04 ms | 0.05 ms | 1.00× | **1.31×** |
79
+ | **50 × 50** | 2,500 | **2.22 ms** | 0.71 ms | 0.99 ms | 0.32× | 0.45× |
80
+ | **100 × 100** | 10,000 | **5.29 ms** | 3.51 ms | 4.03 ms | 0.66× | 0.76× |
81
+ | **200 × 200** | 40,000 | **15.05 ms** | 33.58 ms | 46.82 ms | **2.23×** | **3.11×** |
82
+
83
+ ### 3. Jaro-Winkler Similarity Batch
84
+ | Batch Size | `fuzzgpu` | `rapidfuzz` | `python-Levenshtein` | Speedup vs RapidFuzz |
85
+ | :--- | :---: | :---: | :---: | :---: |
86
+ | **1,000** | **3.10 ms** | 0.81 ms | 1.13 ms | 0.26× |
87
+ | **5,000** | **6.56 ms** | 5.12 ms | 5.78 ms | 0.78× |
88
+ | **10,000** | **8.56 ms** | 7.80 ms | 9.17 ms | 0.91× |
89
+ | **50,000** | **33.24 ms** | 47.11 ms | 24.86 ms | **1.42×** |
90
+
91
+ ---
92
+
93
+ ## Installation
94
+
95
+ ### Python
96
+ ```bash
97
+ pip install fuzzgpu
98
+ ```
99
+
100
+ ### Rust (Cargo.toml)
101
+ ```toml
102
+ [dependencies]
103
+ fuzzgpu-core = "0.1.0"
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Quickstart
109
+
110
+ ```python
111
+ import fuzzgpu
112
+ from fuzzgpu.fuzz import ratio, partial_ratio, token_sort_ratio, token_set_ratio, extract, extractOne
113
+
114
+ # 1. Classical Distance Metrics
115
+ lev = fuzzgpu.levenshtein_distance("kitten", "sitting") # 3
116
+ dam = fuzzgpu.damerau_levenshtein_distance("ab", "ba") # 1 (transposition-aware)
117
+ jw = fuzzgpu.jaro_winkler_similarity("MARTHA", "MARHTA", 0.1) # 0.9611
118
+
119
+ # 2. High-Throughput Batch Processing (Auto-dispatched to GPU/CPU)
120
+ candidates = ["hallo", "hullo", "jello", "yellow", "hello world"] * 10_000
121
+ distances = fuzzgpu.levenshtein_batch("hello", candidates)
122
+ jw_scores = fuzzgpu.jaro_winkler_batch("hello", candidates, prefix_weight=0.1)
123
+
124
+ # 3. 2D Cross-Product Distance Matrix (Dedicated 2D Grid Shader)
125
+ matrix = fuzzgpu.levenshtein_cdist(["abc", "def", "xyz"], ["abd", "axy", "def"])
126
+
127
+ # 4. Global Sequence Alignment (Gotoh 1982 Linear & Affine Gap Penalties)
128
+ score_linear = fuzzgpu.needleman_wunsch_score("AGTACGCA", "TATGC", match=2, mismatch=-1, gap=-2)
129
+ score_affine = fuzzgpu.needleman_wunsch_affine("AGTACGCA", "TATGC", match=2, mismatch=-1, gap_open=-3, gap_extend=-1)
130
+
131
+ # 5. RapidFuzz-Compatible Scorer & Search API
132
+ score = ratio("fuzzy was a bear", "fuzzy was a bear") # 100.0
133
+ part = partial_ratio("hello", "oh hello there") # 100.0
134
+ tsr = token_sort_ratio("new york mets", "mets new york") # 100.0
135
+ tset = token_set_ratio("fuzzy was a bear", "fuzzy bear") # 100.0
136
+
137
+ # 6. Top-K Best Match Search
138
+ best = extractOne("hellp", ["hello", "world", "help"], score_cutoff=50.0)
139
+ # Output: ("hello", 80.0, 0)
140
+
141
+ top_3 = extract("apple", ["apply", "ape", "banana", "applesauce"], score_cutoff=50.0, limit=3)
142
+
143
+ # 7. Hardware Diagnostics
144
+ print(fuzzgpu.gpu_info())
145
+ # Output: Intel(R) Iris(R) Xe Graphics (Vulkan) / Apple M2 (Metal)
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Technical Architecture
151
+
152
+ `fuzzgpu` combines a tiered execution pipeline to balance low-latency single queries and high-throughput batch workloads:
153
+
154
+ ```
155
+ ┌──────────────────────────┐
156
+ │ User Query / API │
157
+ └─────────────┬────────────┘
158
+ │
159
+ Batch Size / Dataset Assessment
160
+ │
161
+ ┌───────────────────────┴───────────────────────┐
162
+ ▼ ▼
163
+ Small Workloads (< 500) Large Batches (≥ 500)
164
+ │ │
165
+ ┌───────────────────────────┐ ┌───────────────────────────┐
166
+ │ Rayon Multi-Threaded │ │ wgpu WebGPU Compute │
167
+ │ CPU Parallelism │ │ Shaders (Metal/Vulkan) │
168
+ │ - Myers 1999 Bit-Vector │ │ - 2D Workgroup Grids │
169
+ │ - Zero PCIe Latency │ │ - Streaming Chunking │
170
+ └───────────────────────────┘ └───────────────────────────┘
171
+ ```
172
+
173
+ ### Key Architectural Optimizations
174
+
175
+ 1. **2D Grid Matrix Shaders (`levenshtein_matrix.wgsl` & `jaro_matrix.wgsl`)**:
176
+ Instead of duplicating string pairs across PCIe ($O(N \cdot M)$ transfers), List A and List B are uploaded once ($O(N + M)$ memory bandwidth). Workgroups execute on a 2D grid (`@workgroup_size(16, 16)`).
177
+ 2. **Myers (1999) Bit-Parallel CPU Engine**:
178
+ For strings $\le 64$ characters, computes Levenshtein edit distance using bit-vector operations with zero inner dynamic programming loops ($O(N)$ execution).
179
+ 3. **Lowrance & Wagner (1975) Unrestricted Damerau-Levenshtein**:
180
+ Full support for character insertions, deletions, substitutions, and arbitrary transpositions.
181
+ 4. **Gotoh (1982) Affine Gap Sequence Alignment**:
182
+ Memory-efficient 3-state recurrence ($O(N)$ auxiliary space) for bioinformatics and long-sequence alignment.
183
+ 5. **Streaming Chunk Partitioner**:
184
+ Datasets exceeding GPU buffer limits (>128MB or >500,000 pairs) are automatically streamed in chunks to prevent VRAM overflow.
185
+
186
+ ---
187
+
188
+ ## Project Structure
189
+
190
+ ```
191
+ fuzzgpu/
192
+ ├── assets/
193
+ │ └── logo.svg # Vector brand asset
194
+ ├── crates/
195
+ │ ├── fuzzgpu-core/ # Core Rust engine & compute shaders
196
+ │ │ ├── src/
197
+ │ │ │ ├── gpu.rs # wgpu instance and device singleton
198
+ │ │ │ ├── levenshtein.rs # Levenshtein kernel & 2D matrix dispatch
199
+ │ │ │ ├── damerau.rs # Lowrance-Wagner Damerau-Levenshtein
200
+ │ │ │ ├── needleman.rs # Needleman-Wunsch (Linear & Affine)
201
+ │ │ │ ├── jaro.rs # Jaro / Jaro-Winkler GPU & CPU kernels
202
+ │ │ │ ├── fuzz.rs # Fuzzy ratio, token sort/set, extract
203
+ │ │ │ ├── simd.rs # Myers bit-vector algorithms
204
+ │ │ │ └── shaders/ # WGSL compute shaders (1D & 2D)
205
+ │ ├── fuzzgpu-python/ # PyO3 CPython C-extension module
206
+ │ └── fuzzgpu-wasm/ # wasm-bindgen WebAssembly module
207
+ ├── python/
208
+ │ └── fuzzgpu/ # Python package wrapper & typing
209
+ ├── tests/
210
+ │ └── test_basic.py # Comprehensive test suite (50 tests)
211
+ └── benchmarks/
212
+ └── bench_compare.py # Comparative benchmarking harness
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Building from Source
218
+
219
+ ### Prerequisites
220
+ - [Rust Toolchain (1.75+)](https://rustup.rs/)
221
+ - Python 3.8+ & `pip install maturin`
222
+
223
+ ### Build Python Extension
224
+ ```bash
225
+ # Clone the repository
226
+ git clone https://github.com/Flaxmbot/fuzzgpu.git
227
+ cd fuzzgpu
228
+
229
+ # Build and install into current virtual environment
230
+ maturin develop --release
231
+ ```
232
+
233
+ ### Run Tests & Benchmarks
234
+ ```bash
235
+ # Run pytest verification suite
236
+ pytest tests/ -v
237
+
238
+ # Run comparative benchmark harness
239
+ python benchmarks/bench_compare.py
240
+ ```
241
+
242
+ ### Build WebAssembly (Browser Target)
243
+ ```bash
244
+ cd crates/fuzzgpu-wasm
245
+ wasm-pack build --target web --release
246
+ ```
247
+
248
+ ---
249
+
250
+ ## License
251
+
252
+ This project is licensed under the [MIT License](LICENSE).
253
+