Skip to content

Commit 448344c

Browse files
Merge branch 'main' into josephine/migrate-codeowners
2 parents f1ebf0a + c854ea3 commit 448344c

23 files changed

Lines changed: 295 additions & 126 deletions

File tree

.github/workflows/pr.yaml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ jobs:
160160
- '!.github/workflows/trigger-breaking-change-alert.yaml'
161161
- '!.pre-commit-config.yaml'
162162
- '!.shellcheckrc'
163+
- '!CODEOWNERS'
164+
- '!Dockerfile'
165+
- '!README.md'
166+
- '!SECURITY.md'
163167
- '!ci/build_docs.sh'
164168
- '!ci/build_go.sh'
165169
- '!ci/build_python.sh'
@@ -171,14 +175,19 @@ jobs:
171175
- '!ci/test_python.sh'
172176
- '!ci/test_wheel_cuvs.sh'
173177
- '!ci/validate_wheel.sh'
174-
- '!Dockerfile'
178+
- '!conda/environments/**'
179+
- '!conda/recipes/cuvs/**'
180+
- '!conda/recipes/cuvs-bench/**'
181+
- '!conda/recipes/cuvs-bench-cpu/**'
175182
- '!docs/**'
183+
- '!examples/**'
176184
- '!fern/**'
185+
- '!go/**'
177186
- '!img/**'
178187
- '!notebooks/**'
188+
- '!pyproject.toml'
179189
- '!python/**'
180190
- '!rust/**'
181-
- '!go/**'
182191
- '!thirdparty/LICENSES/**'
183192
test_python_conda:
184193
- '**'
@@ -192,8 +201,12 @@ jobs:
192201
- '!.github/labeler.yml'
193202
- '!.github/ops-bot.yaml'
194203
- '!.github/release.yml'
204+
- '!.github/workflows/check-c-abi.yaml'
205+
- '!.github/workflows/labeler.yml'
195206
- '!.github/workflows/publish-rust.yaml'
207+
- '!.github/workflows/store-c-abi-baseline.yaml'
196208
- '!.github/workflows/trigger-breaking-change-alert.yaml'
209+
- '!.github/workflows/update-c-abi-baseline.yaml'
197210
- '!.pre-commit-config.yaml'
198211
- '!.shellcheckrc'
199212
- '!ci/build_go.sh'
@@ -210,6 +223,7 @@ jobs:
210223
- '!cpp/.clang-format'
211224
- '!cpp/.clang-tidy'
212225
- '!cpp/doxygen/**'
226+
- '!CODEOWNERS'
213227
- '!Dockerfile'
214228
- '!README.md'
215229
- '!SECURITY.md'
@@ -252,6 +266,7 @@ jobs:
252266
- '!ci/test_python.sh'
253267
- '!ci/test_standalone_c.sh'
254268
- '!ci/validate_wheel.sh'
269+
- '!CODEOWNERS'
255270
- '!Dockerfile'
256271
- '!README.md'
257272
- '!SECURITY.md'
@@ -283,6 +298,7 @@ jobs:
283298
- '!.github/workflows/trigger-breaking-change-alert.yaml'
284299
- '!.pre-commit-config.yaml'
285300
- '!.shellcheckrc'
301+
- '!CODEOWNERS'
286302
- '!Dockerfile'
287303
- '!README.md'
288304
- '!SECURITY.md'
@@ -324,6 +340,7 @@ jobs:
324340
- '!.github/workflows/trigger-breaking-change-alert.yaml'
325341
- '!.pre-commit-config.yaml'
326342
- '!.shellcheckrc'
343+
- '!CODEOWNERS'
327344
- '!Dockerfile'
328345
- '!README.md'
329346
- '!SECURITY.md'

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33

44
repos:
55
- repo: https://github.com/pre-commit/pre-commit-hooks
6-
rev: v5.0.0
6+
rev: v6.0.0
77
hooks:
88
- id: check-json
99
- id: trailing-whitespace
1010
- id: end-of-file-fixer
1111
- id: check-symlinks
12+
- id: check-xml
1213
- repo: https://github.com/PyCQA/isort
1314
rev: 5.12.0
1415
hooks:

c/src/neighbors/brute_force.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION.
3+
* SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

@@ -10,6 +10,7 @@
1010

1111
#include <raft/core/error.hpp>
1212
#include <raft/core/mdspan_types.hpp>
13+
#include <raft/core/numpy_serializer.hpp>
1314
#include <raft/core/resources.hpp>
1415
#include <raft/core/serialize.hpp>
1516

@@ -238,9 +239,13 @@ extern "C" cuvsError_t cuvsBruteForceDeserialize(cuvsResources_t res,
238239
// read the numpy dtype from the beginning of the file
239240
std::ifstream is(filename, std::ios::in | std::ios::binary);
240241
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
241-
char dtype_string[4];
242-
is.read(dtype_string, 4);
243-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
242+
char dtype_string[4]{};
243+
if (!is.read(dtype_string, sizeof(dtype_string))) {
244+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
245+
}
246+
auto dtype =
247+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
248+
is.close();
244249

245250
index->dtype.bits = dtype.itemsize * 8;
246251
if (dtype.kind == 'f' && dtype.itemsize == 4) {

c/src/neighbors/cagra.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <raft/core/error.hpp>
1111
#include <raft/core/mdspan_types.hpp>
12+
#include <raft/core/numpy_serializer.hpp>
1213
#include <raft/core/resources.hpp>
1314
#include <raft/core/serialize.hpp>
1415

@@ -873,9 +874,13 @@ extern "C" cuvsError_t cuvsCagraDeserialize(cuvsResources_t res,
873874
// read the numpy dtype from the beginning of the file
874875
std::ifstream is(filename, std::ios::in | std::ios::binary);
875876
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
876-
char dtype_string[4];
877-
is.read(dtype_string, 4);
878-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
877+
char dtype_string[4]{};
878+
if (!is.read(dtype_string, sizeof(dtype_string))) {
879+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
880+
}
881+
auto dtype =
882+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
883+
is.close();
879884

880885
index->dtype.bits = dtype.itemsize * 8;
881886
if (dtype.kind == 'f' && dtype.itemsize == 4) {

c/src/neighbors/ivf_flat.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
/*
3-
* SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION.
3+
* SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

@@ -9,6 +9,7 @@
99

1010
#include <raft/core/error.hpp>
1111
#include <raft/core/mdspan_types.hpp>
12+
#include <raft/core/numpy_serializer.hpp>
1213
#include <raft/core/resources.hpp>
1314
#include <raft/core/serialize.hpp>
1415
#include <raft/util/cudart_utils.hpp>
@@ -299,9 +300,13 @@ extern "C" cuvsError_t cuvsIvfFlatDeserialize(cuvsResources_t res,
299300
// read the numpy dtype from the beginning of the file
300301
std::ifstream is(filename, std::ios::in | std::ios::binary);
301302
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
302-
char dtype_string[4];
303-
is.read(dtype_string, 4);
304-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
303+
char dtype_string[4]{};
304+
if (!is.read(dtype_string, sizeof(dtype_string))) {
305+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
306+
}
307+
auto dtype =
308+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
309+
is.close();
305310

306311
index->dtype.bits = dtype.itemsize * 8;
307312
if (dtype.kind == 'f' && dtype.itemsize == 4) {

c/src/neighbors/mg_cagra.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
2+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -10,6 +10,7 @@
1010
#include <cuvs/neighbors/common.hpp>
1111
#include <dlpack/dlpack.h>
1212
#include <raft/core/error.hpp>
13+
#include <raft/core/numpy_serializer.hpp>
1314
#include <raft/core/serialize.hpp>
1415

1516
#include "../core/exceptions.hpp"
@@ -399,9 +400,12 @@ extern "C" cuvsError_t cuvsMultiGpuCagraDeserialize(cuvsResources_t res,
399400
return cuvs::core::translate_exceptions([=] {
400401
std::ifstream is(filename, std::ios::in | std::ios::binary);
401402
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
402-
char dtype_string[4];
403-
is.read(dtype_string, 4);
404-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
403+
char dtype_string[4]{};
404+
if (!is.read(dtype_string, sizeof(dtype_string))) {
405+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
406+
}
407+
auto dtype =
408+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
405409
is.close();
406410

407411
index->dtype.bits = dtype.itemsize * 8;
@@ -430,9 +434,12 @@ extern "C" cuvsError_t cuvsMultiGpuCagraDistribute(cuvsResources_t res,
430434
return cuvs::core::translate_exceptions([=] {
431435
std::ifstream is(filename, std::ios::in | std::ios::binary);
432436
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
433-
char dtype_string[4];
434-
is.read(dtype_string, 4);
435-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
437+
char dtype_string[4]{};
438+
if (!is.read(dtype_string, sizeof(dtype_string))) {
439+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
440+
}
441+
auto dtype =
442+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
436443
is.close();
437444

438445
index->dtype.bits = dtype.itemsize * 8;

c/src/neighbors/mg_ivf_flat.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
2+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -10,6 +10,7 @@
1010
#include <cuvs/neighbors/ivf_flat.hpp>
1111
#include <dlpack/dlpack.h>
1212
#include <raft/core/error.hpp>
13+
#include <raft/core/numpy_serializer.hpp>
1314
#include <raft/core/serialize.hpp>
1415

1516
#include "../core/exceptions.hpp"
@@ -396,9 +397,12 @@ extern "C" cuvsError_t cuvsMultiGpuIvfFlatDeserialize(cuvsResources_t res,
396397
return cuvs::core::translate_exceptions([=] {
397398
std::ifstream is(filename, std::ios::in | std::ios::binary);
398399
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
399-
char dtype_string[4];
400-
is.read(dtype_string, 4);
401-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
400+
char dtype_string[4]{};
401+
if (!is.read(dtype_string, sizeof(dtype_string))) {
402+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
403+
}
404+
auto dtype =
405+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
402406
is.close();
403407

404408
index->dtype.bits = dtype.itemsize * 8;
@@ -427,9 +431,12 @@ extern "C" cuvsError_t cuvsMultiGpuIvfFlatDistribute(cuvsResources_t res,
427431
return cuvs::core::translate_exceptions([=] {
428432
std::ifstream is(filename, std::ios::in | std::ios::binary);
429433
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
430-
char dtype_string[4];
431-
is.read(dtype_string, 4);
432-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
434+
char dtype_string[4]{};
435+
if (!is.read(dtype_string, sizeof(dtype_string))) {
436+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
437+
}
438+
auto dtype =
439+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
433440
is.close();
434441

435442
index->dtype.bits = dtype.itemsize * 8;

c/src/neighbors/mg_ivf_pq.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
2+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -10,6 +10,7 @@
1010
#include <cuvs/neighbors/ivf_pq.hpp>
1111
#include <dlpack/dlpack.h>
1212
#include <raft/core/error.hpp>
13+
#include <raft/core/numpy_serializer.hpp>
1314
#include <raft/core/serialize.hpp>
1415

1516
#include "../core/exceptions.hpp"
@@ -388,9 +389,12 @@ extern "C" cuvsError_t cuvsMultiGpuIvfPqDeserialize(cuvsResources_t res,
388389
return cuvs::core::translate_exceptions([=] {
389390
std::ifstream is(filename, std::ios::in | std::ios::binary);
390391
if (!is) { RAFT_FAIL("Cannot open file %s", filename); }
391-
char dtype_string[4];
392-
is.read(dtype_string, 4);
393-
auto dtype = raft::detail::numpy_serializer::parse_descr(std::string(dtype_string, 4));
392+
char dtype_string[4]{};
393+
if (!is.read(dtype_string, sizeof(dtype_string))) {
394+
RAFT_FAIL("Invalid or truncated index header in file %s", filename);
395+
}
396+
auto dtype =
397+
raft::numpy_serializer::parse_descr(std::string(dtype_string, sizeof(dtype_string)));
394398
is.close();
395399

396400
index->dtype.bits = dtype.itemsize * 8;

cpp/include/cuvs/neighbors/cagra.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <raft/core/host_mdspan.hpp>
1717
#include <raft/core/mdspan.hpp>
1818
#include <raft/core/mdspan_types.hpp>
19+
#include <raft/core/numpy_serializer.hpp>
1920
#include <raft/core/resource/stream_view.hpp>
2021
#include <raft/core/serialize.hpp>
2122

@@ -773,7 +774,7 @@ struct CUVS_EXPORT index : cuvs::neighbors::index {
773774
if (lseek(fd.get(), 0, SEEK_SET) == -1) {
774775
RAFT_FAIL("Failed to seek to beginning of dataset file");
775776
}
776-
auto header = raft::detail::numpy_serializer::read_header(stream);
777+
auto header = raft::numpy_serializer::read_header(stream);
777778
RAFT_EXPECTS(header.shape.size() == 2,
778779
"Dataset file should be 2D, got %zu dimensions",
779780
header.shape.size());
@@ -808,7 +809,7 @@ struct CUVS_EXPORT index : cuvs::neighbors::index {
808809
if (lseek(fd.get(), 0, SEEK_SET) == -1) {
809810
RAFT_FAIL("Failed to seek to beginning of graph file");
810811
}
811-
auto header = raft::detail::numpy_serializer::read_header(stream);
812+
auto header = raft::numpy_serializer::read_header(stream);
812813
RAFT_EXPECTS(
813814
header.shape.size() == 2, "Graph file should be 2D, got %zu dimensions", header.shape.size());
814815

@@ -849,7 +850,7 @@ struct CUVS_EXPORT index : cuvs::neighbors::index {
849850
if (lseek(fd.get(), 0, SEEK_SET) == -1) {
850851
RAFT_FAIL("Failed to seek to beginning of mapping file");
851852
}
852-
auto header = raft::detail::numpy_serializer::read_header(stream);
853+
auto header = raft::numpy_serializer::read_header(stream);
853854
RAFT_EXPECTS(header.shape.size() == 1,
854855
"Mapping file should be 1D, got %zu dimensions",
855856
header.shape.size());

cpp/include/cuvs/util/file_io.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include <raft/core/error.hpp>
8+
#include <raft/core/numpy_serializer.hpp>
89
#include <raft/core/serialize.hpp>
910

1011
#include <algorithm>
@@ -189,12 +190,12 @@ std::pair<file_descriptor, size_t> create_numpy_file(const std::string& path,
189190
file_descriptor fd(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
190191

191192
// Build header
192-
const auto dtype = raft::detail::numpy_serializer::get_numpy_dtype<T>();
193-
const bool fortran_order = false;
194-
const raft::detail::numpy_serializer::header_t header = {dtype, fortran_order, shape};
193+
const auto dtype = raft::numpy_serializer::get_numpy_dtype<T>();
194+
const bool fortran_order = false;
195+
const raft::numpy_serializer::header_t header = {dtype, fortran_order, shape};
195196

196197
std::stringstream ss;
197-
raft::detail::numpy_serializer::write_header(ss, header);
198+
raft::numpy_serializer::write_header(ss, header);
198199
std::string header_str = ss.str();
199200
size_t header_size = header_str.size();
200201

0 commit comments

Comments
 (0)