Describe the bug
cuvsDatasetMakePadded fails when handed a device tensor whose rows already sit at CAGRA's required stride. The refusal makes sense since it avoids a redundant copy. However, it is not documented in the API, and the C API exposes no way to predict it.
Steps/Code to reproduce bug
- Allocate a contiguous float32 device matrix whose dimension is a multiple of 4 — e.g. 64 rows × 128 dims. (Contiguous means
rowStride == columns, which for 4-byte elements is already the 16-byte-aligned width CAGRA requires.)
- Wrap it in a
DLManagedTensor with device type kDLCUDA.
- Call
cuvsDatasetMakePadded(res, tensor, CUVS_DATASET_MEM_TYPE_DEVICE, &out).
- Repeat with 127 dims instead of 128 — it succeeds. The boundary is
dim % 4 == 0 for float32.
Expected behavior
The dataset contents are copied into newly allocated padded storage, as documented at
|
* The source tensor may reside in host- or device-accessible memory. Its contents are copied into |
|
* newly allocated padded storage in `target_mem_type`. |
Actual behavior
CUVS_ERROR, with cuvsGetLastErrorText() returning:
RAFT failure at cpp/include/cuvs/neighbors/common.hpp:1162:
source is device and stride is already correct.
Use make_device_padded_dataset_view() to get a view instead.
Environment details
Not environment specific. Present on main and release/26.08:
|
if (device_src && src_stride == target_stride) { |
|
RAFT_EXPECTS(false, |
|
"source is device and stride is already correct. " |
|
"Use %s() to get a view instead.", |
|
view_factory_name); |
|
} |
Additional context
The Python workaround is probably the clearest signal that the API is missing something:
|
cdef cuvsError_t status = cuvsDatasetMakePadded( |
|
res, |
|
dataset_dlpack, |
|
CUVS_DATASET_MEM_TYPE_DEVICE, |
|
&padded.dataset |
|
) |
|
if status == cuvsError_t.CUVS_SUCCESS: |
|
return padded |
|
err = get_last_error_text() or "" |
|
if "stride is already correct" not in err: |
|
check_cuvs(status) |
|
check_cuvs(cuvsDatasetMakePaddedView( |
|
res, |
|
dataset_dlpack, |
|
&padded.dataset |
|
)) |
|
return padded |
It matches on the error text, so any rewording of that message turns the workaround into a crash. Rust, Go, and Java have no equivalent workaround and propagate the failure.
Might be related: #2402 (Dataset API C++, C, and language wrapper follow-up), #2394 (Remove dataset views from language wrappers).
Describe the bug
cuvsDatasetMakePaddedfails when handed a device tensor whose rows already sit at CAGRA's required stride. The refusal makes sense since it avoids a redundant copy. However, it is not documented in the API, and the C API exposes no way to predict it.Steps/Code to reproduce bug
rowStride == columns, which for 4-byte elements is already the 16-byte-aligned width CAGRA requires.)DLManagedTensorwith device typekDLCUDA.cuvsDatasetMakePadded(res, tensor, CUVS_DATASET_MEM_TYPE_DEVICE, &out).dim % 4 == 0for float32.Expected behavior
The dataset contents are copied into newly allocated padded storage, as documented at
cuvs/c/include/cuvs/core/dataset.h
Lines 62 to 63 in 2140532
Actual behavior
CUVS_ERROR, withcuvsGetLastErrorText()returning:Environment details
Not environment specific. Present on
mainandrelease/26.08:cuvs/cpp/include/cuvs/neighbors/common.hpp
Lines 1161 to 1166 in 2140532
Additional context
The Python workaround is probably the clearest signal that the API is missing something:
cuvs/python/cuvs/cuvs/common/dataset.pyx
Lines 73 to 89 in 2140532
It matches on the error text, so any rewording of that message turns the workaround into a crash. Rust, Go, and Java have no equivalent workaround and propagate the failure.
Might be related: #2402 (Dataset API C++, C, and language wrapper follow-up), #2394 (Remove dataset views from language wrappers).