-
Notifications
You must be signed in to change notification settings - Fork 211
Expand file tree
/
Copy pathpairwise_distance.cpp
More file actions
137 lines (117 loc) · 5.09 KB
/
Copy pathpairwise_distance.cpp
File metadata and controls
137 lines (117 loc) · 5.09 KB
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
/*
* SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
* SPDX-License-Identifier: Apache-2.0
*/
#include <cstdint>
#include <dlpack/dlpack.h>
#include <raft/core/error.hpp>
#include <raft/core/mdspan_types.hpp>
#include <raft/core/resources.hpp>
#include <cuvs/core/c_api.h>
#include <cuvs/distance/distance.h>
#include <cuvs/distance/pairwise_distance.h>
#include <cuvs/distance/distance.hpp>
#include "../core/exceptions.hpp"
#include "../core/interop.hpp"
namespace {
template <typename T, typename DistT, typename LayoutT = raft::row_major>
void _pairwise_distance(cuvsResources_t res,
DLManagedTensor* x_tensor,
DLManagedTensor* y_tensor,
DLManagedTensor* distances_tensor,
cuvsDistanceType metric,
float metric_arg)
{
auto res_ptr = reinterpret_cast<raft::resources*>(res);
using mdspan_type = raft::device_matrix_view<T const, int64_t, LayoutT>;
using distances_mdspan_type = raft::device_matrix_view<DistT, int64_t, LayoutT>;
auto x_mds = cuvs::core::from_dlpack<mdspan_type>(x_tensor);
auto y_mds = cuvs::core::from_dlpack<mdspan_type>(y_tensor);
auto distances_mds = cuvs::core::from_dlpack<distances_mdspan_type>(distances_tensor);
auto metric_type = static_cast<cuvs::distance::DistanceType>(metric);
cuvs::distance::pairwise_distance(*res_ptr, x_mds, y_mds, distances_mds, metric_type, metric_arg);
}
} // namespace
extern "C" cuvsError_t cuvsPairwiseDistance(cuvsResources_t res,
DLManagedTensor* x_tensor,
DLManagedTensor* y_tensor,
DLManagedTensor* distances_tensor,
cuvsDistanceType metric,
float metric_arg)
{
return cuvs::core::translate_exceptions([=] {
auto x_dt = x_tensor->dl_tensor.dtype;
auto y_dt = y_tensor->dl_tensor.dtype;
auto dist_dt = distances_tensor->dl_tensor.dtype;
if ((x_dt.code != kDLFloat) || (y_dt.code != kDLFloat) || (dist_dt.code != kDLFloat)) {
RAFT_FAIL("Inputs to cuvsPairwiseDistance must all be floating point tensors");
}
if (x_dt.lanes != 1 || y_dt.lanes != 1 || dist_dt.lanes != 1) {
RAFT_FAIL("Inputs to cuvsPairwiseDistance must all have a single dtype lane");
}
if (x_dt.bits != y_dt.bits) {
RAFT_FAIL("X and Y inputs to cuvsPairwiseDistance must have the same dtype");
}
auto expected_dist_bits = x_dt.bits == 16 ? 32 : x_dt.bits;
if (dist_dt.bits != expected_dist_bits) {
RAFT_FAIL(
"distances output to cuvsPairwiseDistance must have dtype float32 for float16 inputs "
"and match the input dtype otherwise");
}
bool x_row_major;
if (cuvs::core::is_c_contiguous(x_tensor)) {
x_row_major = true;
} else if (cuvs::core::is_f_contiguous(x_tensor)) {
x_row_major = false;
} else {
RAFT_FAIL("X input to cuvsPairwiseDistance must be contiguous (non-strided)");
}
bool y_row_major;
if (cuvs::core::is_c_contiguous(y_tensor)) {
y_row_major = true;
} else if (cuvs::core::is_f_contiguous(y_tensor)) {
y_row_major = false;
} else {
RAFT_FAIL("Y input to cuvsPairwiseDistance must be contiguous (non-strided)");
}
bool distances_row_major;
if (cuvs::core::is_c_contiguous(distances_tensor)) {
distances_row_major = true;
} else if (cuvs::core::is_f_contiguous(distances_tensor)) {
distances_row_major = false;
} else {
RAFT_FAIL("distances input to cuvsPairwiseDistance must be contiguous (non-strided)");
}
if ((x_row_major != y_row_major) || (x_row_major != distances_row_major)) {
RAFT_FAIL(
"Inputs to cuvsPairwiseDistance must all have the same layout (row-major or col-major)");
}
if (x_row_major) {
if (x_dt.bits == 32) {
_pairwise_distance<float, float>(
res, x_tensor, y_tensor, distances_tensor, metric, metric_arg);
} else if (x_dt.bits == 16) {
_pairwise_distance<half, float>(
res, x_tensor, y_tensor, distances_tensor, metric, metric_arg);
} else if (x_dt.bits == 64) {
_pairwise_distance<double, double>(
res, x_tensor, y_tensor, distances_tensor, metric, metric_arg);
} else {
RAFT_FAIL("Unsupported DLtensor dtype: %d and bits: %d", x_dt.code, x_dt.bits);
}
} else {
if (x_dt.bits == 32) {
_pairwise_distance<float, float, raft::col_major>(
res, x_tensor, y_tensor, distances_tensor, metric, metric_arg);
} else if (x_dt.bits == 16) {
_pairwise_distance<half, float, raft::col_major>(
res, x_tensor, y_tensor, distances_tensor, metric, metric_arg);
} else if (x_dt.bits == 64) {
_pairwise_distance<double, double, raft::col_major>(
res, x_tensor, y_tensor, distances_tensor, metric, metric_arg);
} else {
RAFT_FAIL("Unsupported DLtensor dtype: %d and bits: %d", x_dt.code, x_dt.bits);
}
}
});
}