I would like to report a discrepancy between the CUDA Math API documentation and the actual runtime behavior of __vseteq2 (and potentially other __vset* SIMD intrinsics).
According to the CUDA Math API Manual (CUDA_Math_API.pdf):
“Performs per-halfword (un)signed comparison: returns 1 if both parts compare equal. Splits 4 bytes of each argument into 2 parts, each consisting of 2 bytes. For corresponding parts function performs comparison ‘a’ part == ‘b’ part. If both equalities are satisfied, function returns 1. Returns 1 if a = b, else returns 0.”
Based on the documentation, this function should perform a reduction comparison and return a scalar boolean/integer value (1 or 0).
However, the actual implementation returns a packed 32-bit result representing per-halfword comparison masks (e.g., 0x00010001 when both halfwords match, or 0x00010000 when only one halfword matches), rather than a scalar 0 or 1.
Minimal Reproducible Example:
#include <stdio.h>
#include <cuda_runtime.h>
__global__ void test_vseteq2() {
unsigned int a = 0x12345678;
unsigned int b = 0x12340000; // High 16 bits match, low 16 bits differ
unsigned int res = __vseteq2(a, b);
// Documented behavior: Should return 0 (since low halfwords do not match)
// Actual behavior: Returns 0x00010000 (packed per-halfword comparison result)
printf("a: 0x%08X, b: 0x%08X => __vseteq2 output: 0x%08X\n", a, b, res);
}
int main() {
test_vseteq2<<<1, 1>>>();
cudaDeviceSynchronize();
return 0;
}
Observed Output:
a: 0x12345678, b: 0x12340000 => __vseteq2 output: 0x00010000
Questions:
-
Is this a documentation error in the CUDA Math API Guide, or an unexpected compiler intrinsic implementation?
-
If this is a documentation error, can we officially rely on the packed per-halfword return pattern (
0x00010001,0x00010000, etc.) in future CUDA Toolkit releases without risking breaking changes?