cuknn 0.1.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.
- cuknn-0.1.0/LICENSE +21 -0
- cuknn-0.1.0/PKG-INFO +134 -0
- cuknn-0.1.0/README.md +121 -0
- cuknn-0.1.0/pyproject.toml +30 -0
- cuknn-0.1.0/setup.cfg +4 -0
- cuknn-0.1.0/src/cuknn/__init__.py +7 -0
- cuknn-0.1.0/src/cuknn/cuknn.py +127 -0
- cuknn-0.1.0/src/cuknn/distances.py +78 -0
- cuknn-0.1.0/src/cuknn.egg-info/PKG-INFO +134 -0
- cuknn-0.1.0/src/cuknn.egg-info/SOURCES.txt +11 -0
- cuknn-0.1.0/src/cuknn.egg-info/dependency_links.txt +1 -0
- cuknn-0.1.0/src/cuknn.egg-info/requires.txt +2 -0
- cuknn-0.1.0/src/cuknn.egg-info/top_level.txt +1 -0
cuknn-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Salvatore Calderaro
|
|
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.
|
cuknn-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cuknn
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: GPU accelerated K-Nearest Neighbors using CuPy
|
|
5
|
+
Author: Salvatore Calderaro
|
|
6
|
+
Project-URL: Homepage, https://github.com/salvatorecalderaro/cuKNN
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: tqdm
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# CuPy-KNN ⚡
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="logo.png" alt="CuPy-KNN logo" width="600">
|
|
17
|
+
</p>
|
|
18
|
+
<p align="center">
|
|
19
|
+
GPU-Accelerated K-Nearest Neighbors using NVIDIA CUDA and CuPy
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
## 🚀 Overview
|
|
31
|
+
|
|
32
|
+
**CuPy-KNN** is a GPU accelerated implementation of the
|
|
33
|
+
K-Nearest Neighbors algorithm powered by
|
|
34
|
+
[CuPy](https://cupy.dev/).
|
|
35
|
+
|
|
36
|
+
It provides a scikit-learn compatible API while exploiting NVIDIA GPUs
|
|
37
|
+
for large-scale nearest neighbor search.
|
|
38
|
+
|
|
39
|
+
Designed for:
|
|
40
|
+
|
|
41
|
+
- Machine Learning
|
|
42
|
+
- Deep Learning embeddings
|
|
43
|
+
- Computer Vision features
|
|
44
|
+
- Bioinformatics embeddings
|
|
45
|
+
- Large-scale similarity search
|
|
46
|
+
|
|
47
|
+
## ✨ Features
|
|
48
|
+
|
|
49
|
+
✅ GPU acceleration with CUDA
|
|
50
|
+
✅ Batch-based distance computation
|
|
51
|
+
✅ Multiple distance metrics:
|
|
52
|
+
|
|
53
|
+
- Euclidean
|
|
54
|
+
- Cosine
|
|
55
|
+
- Manhattan
|
|
56
|
+
|
|
57
|
+
✅ sklearn-like API
|
|
58
|
+
|
|
59
|
+
- `fit()`
|
|
60
|
+
- `predict()`
|
|
61
|
+
- `predict_proba()`
|
|
62
|
+
- `kneighbors()`
|
|
63
|
+
|
|
64
|
+
✅ Supports large datasets
|
|
65
|
+
✅ Fully implemented with CuPy tensors
|
|
66
|
+
|
|
67
|
+
## 📦 Installation
|
|
68
|
+
|
|
69
|
+
Install from PyPI:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install cuknn
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For CUDA-enabled systems install CuPy first:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install cupy-cuda12x
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
or select the version matching your CUDA installation.
|
|
82
|
+
|
|
83
|
+
## ⚡ Quick Start
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from cuknn import KNN
|
|
87
|
+
|
|
88
|
+
from sklearn.datasets import make_classification
|
|
89
|
+
from sklearn.model_selection import train_test_split
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
X, y = make_classification(
|
|
93
|
+
n_samples=100000,
|
|
94
|
+
n_features=512,
|
|
95
|
+
n_classes=5
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
100
|
+
X,
|
|
101
|
+
y
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
model = KNN(
|
|
106
|
+
k=5,
|
|
107
|
+
distance="euclidean",
|
|
108
|
+
batch_size=1024
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
model.fit(
|
|
113
|
+
X_train,
|
|
114
|
+
y_train
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
prediction = model.predict(
|
|
119
|
+
X_test
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 📚 Citation
|
|
125
|
+
|
|
126
|
+
If you use cuKNN in your research:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
@software{cupy_knn,
|
|
130
|
+
author = {Calderaro, Salvatore},
|
|
131
|
+
title = {cuKNN: GPU Accelerated K-Nearest Neighbors},
|
|
132
|
+
year = {2026}
|
|
133
|
+
}
|
|
134
|
+
```
|
cuknn-0.1.0/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# CuPy-KNN ⚡
|
|
2
|
+
<p align="center">
|
|
3
|
+
<img src="logo.png" alt="CuPy-KNN logo" width="600">
|
|
4
|
+
</p>
|
|
5
|
+
<p align="center">
|
|
6
|
+
GPU-Accelerated K-Nearest Neighbors using NVIDIA CUDA and CuPy
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+

|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## 🚀 Overview
|
|
18
|
+
|
|
19
|
+
**CuPy-KNN** is a GPU accelerated implementation of the
|
|
20
|
+
K-Nearest Neighbors algorithm powered by
|
|
21
|
+
[CuPy](https://cupy.dev/).
|
|
22
|
+
|
|
23
|
+
It provides a scikit-learn compatible API while exploiting NVIDIA GPUs
|
|
24
|
+
for large-scale nearest neighbor search.
|
|
25
|
+
|
|
26
|
+
Designed for:
|
|
27
|
+
|
|
28
|
+
- Machine Learning
|
|
29
|
+
- Deep Learning embeddings
|
|
30
|
+
- Computer Vision features
|
|
31
|
+
- Bioinformatics embeddings
|
|
32
|
+
- Large-scale similarity search
|
|
33
|
+
|
|
34
|
+
## ✨ Features
|
|
35
|
+
|
|
36
|
+
✅ GPU acceleration with CUDA
|
|
37
|
+
✅ Batch-based distance computation
|
|
38
|
+
✅ Multiple distance metrics:
|
|
39
|
+
|
|
40
|
+
- Euclidean
|
|
41
|
+
- Cosine
|
|
42
|
+
- Manhattan
|
|
43
|
+
|
|
44
|
+
✅ sklearn-like API
|
|
45
|
+
|
|
46
|
+
- `fit()`
|
|
47
|
+
- `predict()`
|
|
48
|
+
- `predict_proba()`
|
|
49
|
+
- `kneighbors()`
|
|
50
|
+
|
|
51
|
+
✅ Supports large datasets
|
|
52
|
+
✅ Fully implemented with CuPy tensors
|
|
53
|
+
|
|
54
|
+
## 📦 Installation
|
|
55
|
+
|
|
56
|
+
Install from PyPI:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install cuknn
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For CUDA-enabled systems install CuPy first:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install cupy-cuda12x
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
or select the version matching your CUDA installation.
|
|
69
|
+
|
|
70
|
+
## ⚡ Quick Start
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from cuknn import KNN
|
|
74
|
+
|
|
75
|
+
from sklearn.datasets import make_classification
|
|
76
|
+
from sklearn.model_selection import train_test_split
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
X, y = make_classification(
|
|
80
|
+
n_samples=100000,
|
|
81
|
+
n_features=512,
|
|
82
|
+
n_classes=5
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
87
|
+
X,
|
|
88
|
+
y
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
model = KNN(
|
|
93
|
+
k=5,
|
|
94
|
+
distance="euclidean",
|
|
95
|
+
batch_size=1024
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
model.fit(
|
|
100
|
+
X_train,
|
|
101
|
+
y_train
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
prediction = model.predict(
|
|
106
|
+
X_test
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 📚 Citation
|
|
112
|
+
|
|
113
|
+
If you use cuKNN in your research:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
@software{cupy_knn,
|
|
117
|
+
author = {Calderaro, Salvatore},
|
|
118
|
+
title = {cuKNN: GPU Accelerated K-Nearest Neighbors},
|
|
119
|
+
year = {2026}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"setuptools>=61",
|
|
4
|
+
"wheel"
|
|
5
|
+
]
|
|
6
|
+
build-backend = "setuptools.build_meta"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
[project]
|
|
10
|
+
name = "cuknn"
|
|
11
|
+
version = "0.1.0"
|
|
12
|
+
|
|
13
|
+
description = "GPU accelerated K-Nearest Neighbors using CuPy"
|
|
14
|
+
|
|
15
|
+
authors = [
|
|
16
|
+
{name="Salvatore Calderaro"}
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
readme = "README.md"
|
|
20
|
+
|
|
21
|
+
requires-python = ">=3.9"
|
|
22
|
+
|
|
23
|
+
dependencies = [
|
|
24
|
+
"numpy",
|
|
25
|
+
"tqdm"
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/salvatorecalderaro/cuKNN"
|
cuknn-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import cupy as cp
|
|
2
|
+
from .distances import euclidean_distance, cosine_distance,manhattan_distance
|
|
3
|
+
from tqdm import tqdm
|
|
4
|
+
|
|
5
|
+
class KNN:
|
|
6
|
+
"""
|
|
7
|
+
A simple K-Nearest Neighbors (KNN) classifier using CuPy for GPU acceleration.
|
|
8
|
+
Attributes:
|
|
9
|
+
k (int): The number of nearest neighbors to consider for classification.
|
|
10
|
+
distance (str): The distance metric to use ('euclidean', 'cosine', or 'manhattan').
|
|
11
|
+
batch_size (int): The number of samples to process in each batch during prediction.
|
|
12
|
+
X_train (cp.ndarray): The training data features.
|
|
13
|
+
y_train (cp.ndarray): The training data labels.
|
|
14
|
+
Methods:
|
|
15
|
+
fit(X, y): Fit the KNN model using the training data.
|
|
16
|
+
predict(X): Predict the labels for the given test data.
|
|
17
|
+
"""
|
|
18
|
+
def __init__(self, k=5, distance='euclidean',batch_size=128):
|
|
19
|
+
self.k = k
|
|
20
|
+
self.batch_size = batch_size
|
|
21
|
+
|
|
22
|
+
metrics = {
|
|
23
|
+
"euclidean": euclidean_distance,
|
|
24
|
+
"cosine": cosine_distance,
|
|
25
|
+
"manhattan": manhattan_distance,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if distance not in metrics:
|
|
29
|
+
raise ValueError(f"Unknown distance metric: {distance}")
|
|
30
|
+
|
|
31
|
+
self.distance = metrics[distance]
|
|
32
|
+
self.X_train = None
|
|
33
|
+
self.y_train = None
|
|
34
|
+
|
|
35
|
+
self.neighbor_indices_ = None
|
|
36
|
+
self.neighbor_distances_ = None
|
|
37
|
+
self._last_X = None
|
|
38
|
+
|
|
39
|
+
def fit(self, X, y):
|
|
40
|
+
self.X_train = cp.asarray(X)
|
|
41
|
+
self.y_train = cp.asarray(y)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def kneighbors(self, X):
|
|
45
|
+
"""
|
|
46
|
+
Find the k-nearest neighbors for each sample in X.
|
|
47
|
+
Args:
|
|
48
|
+
X: A 2D array of shape (n_samples, n_features).
|
|
49
|
+
Returns:
|
|
50
|
+
A tuple containing:
|
|
51
|
+
- distances: A 2D array of shape (n_samples, k) containing the distances to the k-nearest neighbors.
|
|
52
|
+
- indices: A 2D array of shape (n_samples, k) containing the indices of the k-nearest neighbors in the training data.
|
|
53
|
+
"""
|
|
54
|
+
X = cp.asarray(X)
|
|
55
|
+
n_samples = X.shape[0]
|
|
56
|
+
|
|
57
|
+
all_distances = []
|
|
58
|
+
all_indices = []
|
|
59
|
+
|
|
60
|
+
for i in tqdm(range(0, n_samples, self.batch_size), desc="Finding Neighbors", unit="batch"):
|
|
61
|
+
X_batch = X[i:i+self.batch_size]
|
|
62
|
+
distances = self.distance(X_batch, self.X_train)
|
|
63
|
+
nearest_indices = cp.argpartition(distances, self.k, axis=1)[:, :self.k]
|
|
64
|
+
nearest_distances = cp.take_along_axis(distances, nearest_indices, axis=1)
|
|
65
|
+
all_distances.append(nearest_distances)
|
|
66
|
+
all_indices.append(nearest_indices)
|
|
67
|
+
|
|
68
|
+
all_distances = cp.concatenate(all_distances, axis=0)
|
|
69
|
+
all_indices = cp.concatenate(all_indices, axis=0)
|
|
70
|
+
self.neighbor_indices_ = all_indices
|
|
71
|
+
self.neighbor_distances_ = all_distances
|
|
72
|
+
self._last_X = X.copy()
|
|
73
|
+
return self.neighbor_distances_, self.neighbor_indices_
|
|
74
|
+
|
|
75
|
+
def _check_kneighbors(self, X):
|
|
76
|
+
"""
|
|
77
|
+
Check if kneighbors has been called for the given input X.
|
|
78
|
+
If not, call kneighbors to compute the neighbors.
|
|
79
|
+
Args:
|
|
80
|
+
X: A 2D array of shape (n_samples, n_features).
|
|
81
|
+
"""
|
|
82
|
+
X = cp.asarray(X)
|
|
83
|
+
if self.neighbor_indices_ is None or self.neighbor_distances_ is None or not cp.array_equal(self._last_X, X):
|
|
84
|
+
self.kneighbors(X)
|
|
85
|
+
|
|
86
|
+
def predict(self, X):
|
|
87
|
+
"""
|
|
88
|
+
Predict the labels for the given test data.
|
|
89
|
+
Args:
|
|
90
|
+
X: A 2D array of shape (n_samples, n_features).
|
|
91
|
+
Returns:
|
|
92
|
+
A 1D array of shape (n_samples,) containing the predicted labels.
|
|
93
|
+
"""
|
|
94
|
+
self._check_kneighbors(X)
|
|
95
|
+
indices = self.neighbor_indices_
|
|
96
|
+
|
|
97
|
+
predictions = []
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
for row in tqdm(indices,desc="Predicting",unit="batch"):
|
|
101
|
+
labels = self.y_train[row]
|
|
102
|
+
values, counts = cp.unique(labels,return_counts=True)
|
|
103
|
+
predictions.append(values[cp.argmax(counts)])
|
|
104
|
+
return cp.asarray(predictions)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def predict_proba(self,X):
|
|
108
|
+
self._check_kneighbors(X)
|
|
109
|
+
|
|
110
|
+
classes = cp.unique(self.y_train)
|
|
111
|
+
probas = []
|
|
112
|
+
|
|
113
|
+
indices = self.neighbor_indices_
|
|
114
|
+
|
|
115
|
+
for row in tqdm(indices,desc="Predicting Probabilities",unit="batch"):
|
|
116
|
+
labels = self.y_train[row]
|
|
117
|
+
for cls in classes:
|
|
118
|
+
probas.append(cp.sum(labels == cls) / self.k)
|
|
119
|
+
return cp.asarray(probas).reshape(X.shape[0], len(classes))
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import cupy as cp
|
|
2
|
+
|
|
3
|
+
def euclidean_distance(x,y):
|
|
4
|
+
"""
|
|
5
|
+
Compute the Euclidean distance between two sets of points.
|
|
6
|
+
Args:
|
|
7
|
+
x: A 2D array of shape (n_samples_x, n_features).
|
|
8
|
+
y: A 2D array of shape (n_samples_y, n_features).
|
|
9
|
+
Returns:
|
|
10
|
+
A 2D array of shape (n_samples_x, n_samples_y) containing the
|
|
11
|
+
pairwise Euclidean distances between the points in x and y.
|
|
12
|
+
"""
|
|
13
|
+
x = cp.asarray(x)
|
|
14
|
+
y = cp.asarray(y)
|
|
15
|
+
x_norm = cp.sum(x**2, axis=1, keepdims=True)
|
|
16
|
+
y_norm = cp.sum(y**2, axis=1)
|
|
17
|
+
|
|
18
|
+
dist = (x_norm + y_norm - 2 * cp.dot(x, y.T))
|
|
19
|
+
|
|
20
|
+
dist = cp.sqrt(cp.maximum(dist, 0))
|
|
21
|
+
return dist
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def manhattan_distance(x,y):
|
|
25
|
+
"""
|
|
26
|
+
Compute the Manhattan distance between two sets of points.
|
|
27
|
+
Args:
|
|
28
|
+
x: A 2D array of shape (n_samples_x, n_features).
|
|
29
|
+
y: A 2D array of shape (n_samples_y, n_features).
|
|
30
|
+
Returns:
|
|
31
|
+
A 2D array of shape (n_samples_x, n_samples_y) containing the
|
|
32
|
+
pairwise Manhattan distances between the points in x and y.
|
|
33
|
+
"""
|
|
34
|
+
x = cp.asarray(x)
|
|
35
|
+
y = cp.asarray(y)
|
|
36
|
+
dist = cp.sum(cp.abs(x[:, None] - y[None, :]), axis=-1)
|
|
37
|
+
return dist
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def cosine_distance(x,y):
|
|
41
|
+
"""
|
|
42
|
+
Compute the Cosine distance between two sets of points.
|
|
43
|
+
Args:
|
|
44
|
+
x: A 2D array of shape (n_samples_x, n_features).
|
|
45
|
+
y: A 2D array of shape (n_samples_y, n_features).
|
|
46
|
+
Returns:
|
|
47
|
+
A 2D array of shape (n_samples_x, n_samples_y) containing the
|
|
48
|
+
pairwise Cosine distances between the points in x and y.
|
|
49
|
+
"""
|
|
50
|
+
x = cp.asarray(x)
|
|
51
|
+
y = cp.asarray(y)
|
|
52
|
+
x_norm = cp.linalg.norm(x, axis=1, keepdims=True)
|
|
53
|
+
y_norm = cp.linalg.norm(y, axis=1, keepdims=True)
|
|
54
|
+
|
|
55
|
+
dist = 1 - (cp.dot(x, y.T) / (x_norm * y_norm.T))
|
|
56
|
+
|
|
57
|
+
return dist
|
|
58
|
+
|
|
59
|
+
def precomputed_distance(D):
|
|
60
|
+
"""
|
|
61
|
+
Return a function that computes the precomputed distance between two sets of points.
|
|
62
|
+
Args:
|
|
63
|
+
D: A 2D array of shape (n_samples_x, n_samples_y) containing the precomputed distances.
|
|
64
|
+
Returns:
|
|
65
|
+
A function that takes two 2D arrays x and y and returns the precomputed distances between the points in x and y.
|
|
66
|
+
"""
|
|
67
|
+
def distance(x, y):
|
|
68
|
+
"""
|
|
69
|
+
Return the precomputed distances between the points in x and y.
|
|
70
|
+
Args:
|
|
71
|
+
x: A 2D array of shape (n_samples_x, n_features).
|
|
72
|
+
y: A 2D array of shape (n_samples_y, n_features).
|
|
73
|
+
Returns:
|
|
74
|
+
A 2D array of shape (n_samples_x, n_samples_y) containing the
|
|
75
|
+
precomputed distances between the points in x and y."""
|
|
76
|
+
return D
|
|
77
|
+
|
|
78
|
+
return distance
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cuknn
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: GPU accelerated K-Nearest Neighbors using CuPy
|
|
5
|
+
Author: Salvatore Calderaro
|
|
6
|
+
Project-URL: Homepage, https://github.com/salvatorecalderaro/cuKNN
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: tqdm
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# CuPy-KNN ⚡
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="logo.png" alt="CuPy-KNN logo" width="600">
|
|
17
|
+
</p>
|
|
18
|
+
<p align="center">
|
|
19
|
+
GPU-Accelerated K-Nearest Neighbors using NVIDIA CUDA and CuPy
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
## 🚀 Overview
|
|
31
|
+
|
|
32
|
+
**CuPy-KNN** is a GPU accelerated implementation of the
|
|
33
|
+
K-Nearest Neighbors algorithm powered by
|
|
34
|
+
[CuPy](https://cupy.dev/).
|
|
35
|
+
|
|
36
|
+
It provides a scikit-learn compatible API while exploiting NVIDIA GPUs
|
|
37
|
+
for large-scale nearest neighbor search.
|
|
38
|
+
|
|
39
|
+
Designed for:
|
|
40
|
+
|
|
41
|
+
- Machine Learning
|
|
42
|
+
- Deep Learning embeddings
|
|
43
|
+
- Computer Vision features
|
|
44
|
+
- Bioinformatics embeddings
|
|
45
|
+
- Large-scale similarity search
|
|
46
|
+
|
|
47
|
+
## ✨ Features
|
|
48
|
+
|
|
49
|
+
✅ GPU acceleration with CUDA
|
|
50
|
+
✅ Batch-based distance computation
|
|
51
|
+
✅ Multiple distance metrics:
|
|
52
|
+
|
|
53
|
+
- Euclidean
|
|
54
|
+
- Cosine
|
|
55
|
+
- Manhattan
|
|
56
|
+
|
|
57
|
+
✅ sklearn-like API
|
|
58
|
+
|
|
59
|
+
- `fit()`
|
|
60
|
+
- `predict()`
|
|
61
|
+
- `predict_proba()`
|
|
62
|
+
- `kneighbors()`
|
|
63
|
+
|
|
64
|
+
✅ Supports large datasets
|
|
65
|
+
✅ Fully implemented with CuPy tensors
|
|
66
|
+
|
|
67
|
+
## 📦 Installation
|
|
68
|
+
|
|
69
|
+
Install from PyPI:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install cuknn
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For CUDA-enabled systems install CuPy first:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install cupy-cuda12x
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
or select the version matching your CUDA installation.
|
|
82
|
+
|
|
83
|
+
## ⚡ Quick Start
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from cuknn import KNN
|
|
87
|
+
|
|
88
|
+
from sklearn.datasets import make_classification
|
|
89
|
+
from sklearn.model_selection import train_test_split
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
X, y = make_classification(
|
|
93
|
+
n_samples=100000,
|
|
94
|
+
n_features=512,
|
|
95
|
+
n_classes=5
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
100
|
+
X,
|
|
101
|
+
y
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
model = KNN(
|
|
106
|
+
k=5,
|
|
107
|
+
distance="euclidean",
|
|
108
|
+
batch_size=1024
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
model.fit(
|
|
113
|
+
X_train,
|
|
114
|
+
y_train
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
prediction = model.predict(
|
|
119
|
+
X_test
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 📚 Citation
|
|
125
|
+
|
|
126
|
+
If you use cuKNN in your research:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
@software{cupy_knn,
|
|
130
|
+
author = {Calderaro, Salvatore},
|
|
131
|
+
title = {cuKNN: GPU Accelerated K-Nearest Neighbors},
|
|
132
|
+
year = {2026}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/cuknn/__init__.py
|
|
5
|
+
src/cuknn/cuknn.py
|
|
6
|
+
src/cuknn/distances.py
|
|
7
|
+
src/cuknn.egg-info/PKG-INFO
|
|
8
|
+
src/cuknn.egg-info/SOURCES.txt
|
|
9
|
+
src/cuknn.egg-info/dependency_links.txt
|
|
10
|
+
src/cuknn.egg-info/requires.txt
|
|
11
|
+
src/cuknn.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cuknn
|