Skip to content

Commit 1726f5e

Browse files
authored
test: expand cuDF CUDA e2e coverage (#8463)
Expand the CUDA cuDF end-to-end harness with boolean columns, sliced primitive and boolean columns, and nullable timestamp millisecond coverage. Signed-off-by: Alexander Droste <alexander.droste@protonmail.com>
1 parent b2c9e79 commit 1726f5e

2 files changed

Lines changed: 69 additions & 3 deletions

File tree

vortex-cuda/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,15 @@ cmake -S cpp -B cpp/build \
2727
-DBUILD_TESTS=ON \
2828
-DDISABLE_DEPRECATION_WARNINGS=ON \
2929
-DCMAKE_BUILD_TYPE=Debug \
30+
-DCUDF_BUILD_STATIC_DEPS=OFF \
3031
-DCUDF_BUILD_STREAMS_TEST_UTIL=OFF \
3132
-DCUDAToolkit_ROOT=/usr/local/cuda \
3233
-DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc \
3334
-DCMAKE_C_COMPILER=gcc \
3435
-DCMAKE_CXX_COMPILER=g++ \
36+
# In large AArch64 Debug links, CALL26/JUMP26 relocations can exceed their branch range.
37+
# Use 1 MiB stub groups so GNU ld emits veneers close enough to each relocation site.
38+
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,--stub-group-size=1048576" \
39+
-DCMAKE_EXE_LINKER_FLAGS="-Wl,--stub-group-size=1048576" \
3540
-GNinja && cmake --build cpp/build --target INTEROP_TEST --parallel
3641
```

vortex-test/e2e-cuda/src/lib.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ use std::sync::LazyLock;
1313

1414
use arrow_array::Array;
1515
use arrow_array::ArrayRef as ArrowArrayRef;
16+
use arrow_array::BooleanArray;
1617
use arrow_array::Date32Array;
1718
use arrow_array::Decimal32Array;
1819
use arrow_array::Decimal64Array;
1920
use arrow_array::Decimal128Array;
2021
use arrow_array::DictionaryArray;
22+
use arrow_array::Int32Array;
2123
use arrow_array::StringArray;
24+
use arrow_array::TimestampMillisecondArray;
2225
use arrow_array::cast::AsArray;
2326
use arrow_array::ffi::FFI_ArrowArray;
2427
use arrow_array::ffi::from_ffi;
@@ -32,6 +35,7 @@ use futures::executor::block_on;
3235
use vortex::array::ArrayRef as VortexArrayRef;
3336
use vortex::array::IntoArray;
3437
use vortex::array::VortexSessionExecute;
38+
use vortex::array::arrays::BoolArray;
3539
use vortex::array::arrays::DecimalArray;
3640
use vortex::array::arrays::DictArray as VortexDictArray;
3741
use vortex::array::arrays::FixedSizeListArray;
@@ -100,6 +104,42 @@ fn primitive_array() -> Result<VortexArrayRef, String> {
100104
})
101105
}
102106

107+
fn bool_array() -> VortexArrayRef {
108+
BoolArray::from_iter([true, false, false, true, true]).into_array()
109+
}
110+
111+
fn sliced_i32_array() -> VortexArrayRef {
112+
PrimitiveArray::from_option_iter([
113+
Some(-999i32),
114+
Some(10),
115+
None,
116+
Some(30),
117+
Some(40),
118+
None,
119+
Some(999),
120+
])
121+
.into_array()
122+
.slice(1..6)
123+
.expect("sliced i32 array")
124+
}
125+
126+
fn sliced_bool_array() -> VortexArrayRef {
127+
BoolArray::from_iter([true, false, true, true, false, true, false])
128+
.into_array()
129+
.slice(1..6)
130+
.expect("sliced bool array")
131+
}
132+
133+
fn timestamp_ms_array() -> VortexArrayRef {
134+
TemporalArray::new_timestamp(
135+
PrimitiveArray::from_option_iter([Some(1_000i64), None, Some(3_000), Some(4_000), None])
136+
.into_array(),
137+
TimeUnit::Milliseconds,
138+
None,
139+
)
140+
.into_array()
141+
}
142+
103143
fn list_array() -> VortexArrayRef {
104144
ListArray::try_new(
105145
PrimitiveArray::from_iter([10i32, 11, 12, 13, 14]).into_array(),
@@ -236,6 +276,9 @@ fn export_array_inner(schema_ptr: &mut FFI_ArrowSchema, array_ptr: &mut ArrowDev
236276
let array = StructArray::new(
237277
FieldNames::from_iter([
238278
"prims",
279+
"bools",
280+
"sliced_i32",
281+
"sliced_bools",
239282
"decimal32",
240283
"decimal64",
241284
"decimal128",
@@ -246,19 +289,24 @@ fn export_array_inner(schema_ptr: &mut FFI_ArrowSchema, array_ptr: &mut ArrowDev
246289
// Arrow Device import path rejects NANOARROW_TYPE_BINARY, and treating arbitrary
247290
// bytes as strings would be semantically incorrect.
248291
"dates",
292+
"timestamp_ms",
249293
"dictionary",
250294
"lists",
251295
"fixed_lists",
252296
]),
253297
vec![
254298
primitive,
299+
bool_array(),
300+
sliced_i32_array(),
301+
sliced_bool_array(),
255302
decimal32.into_array(),
256303
decimal64.into_array(),
257304
decimal128.into_array(),
258305
strings.into_array(),
259306
sliced_utf8_array(),
260307
multi_buffer_utf8_array(),
261308
dates.into_array(),
309+
timestamp_ms_array(),
262310
dictionary_array(),
263311
list_array(),
264312
fixed_size_list_array(),
@@ -327,6 +375,9 @@ fn validate_array_inner(ffi_schema: &FFI_ArrowSchema, ffi_array: &mut FFI_ArrowA
327375
&mut SESSION.create_execution_ctx(),
328376
)
329377
.expect("expected primitive Arrow array");
378+
let bools = BooleanArray::from(vec![true, false, false, true, true]);
379+
let sliced_i32 = Int32Array::from(vec![Some(10), None, Some(30), Some(40), None]);
380+
let sliced_bools = BooleanArray::from(vec![false, true, true, false, true]);
330381
let decimal32 = Decimal32Array::from_iter([Some(0i32), Some(1), None, Some(3), Some(4)])
331382
// cuDF stores decimals using the maximum precision for the physical width and preserves scale.
332383
.with_precision_and_scale(9, 2)
@@ -359,6 +410,8 @@ fn validate_array_inner(ffi_schema: &FFI_ArrowSchema, ffi_array: &mut FFI_ArrowA
359410
Some("short"),
360411
]);
361412
let date = Date32Array::from(vec![Some(100i32), None, Some(300), Some(400), None]);
413+
let timestamp_ms =
414+
TimestampMillisecondArray::from(vec![Some(1_000i64), None, Some(3_000), Some(4_000), None]);
362415
let dictionary = Arc::new(
363416
vec![
364417
Some("apple"),
@@ -385,6 +438,9 @@ fn validate_array_inner(ffi_schema: &FFI_ArrowSchema, ffi_array: &mut FFI_ArrowA
385438

386439
let expected_fields = Fields::from_iter([
387440
Field::new("prims", primitive.data_type().clone(), true),
441+
Field::new("bools", bools.data_type().clone(), false),
442+
Field::new("sliced_i32", sliced_i32.data_type().clone(), true),
443+
Field::new("sliced_bools", sliced_bools.data_type().clone(), false),
388444
Field::new("decimal32", decimal32.data_type().clone(), true),
389445
Field::new("decimal64", decimal64.data_type().clone(), true),
390446
Field::new("decimal128", decimal128.data_type().clone(), true),
@@ -396,6 +452,7 @@ fn validate_array_inner(ffi_schema: &FFI_ArrowSchema, ffi_array: &mut FFI_ArrowA
396452
false,
397453
),
398454
Field::new("dates", date.data_type().clone(), true),
455+
Field::new("timestamp_ms", timestamp_ms.data_type().clone(), true),
399456
Field::new("dictionary", dictionary.data_type().clone(), true),
400457
cudf_list_field("lists"),
401458
cudf_list_field("fixed_lists"),
@@ -407,15 +464,19 @@ fn validate_array_inner(ffi_schema: &FFI_ArrowSchema, ffi_array: &mut FFI_ArrowA
407464
return 1;
408465
}
409466

410-
let expected_arrays: [ArrowArrayRef; 9] = [
467+
let expected_arrays: Vec<ArrowArrayRef> = vec![
411468
primitive,
469+
Arc::new(bools),
470+
Arc::new(sliced_i32),
471+
Arc::new(sliced_bools),
412472
Arc::new(decimal32),
413473
Arc::new(decimal64),
414474
Arc::new(decimal128),
415475
Arc::new(string),
416476
Arc::new(sliced_utf8),
417477
Arc::new(multi_buffer_utf8),
418478
Arc::new(date),
479+
Arc::new(timestamp_ms),
419480
dictionary,
420481
];
421482

@@ -430,11 +491,11 @@ fn validate_array_inner(ffi_schema: &FFI_ArrowSchema, ffi_array: &mut FFI_ArrowA
430491
}
431492
}
432493

433-
if !list_values_eq(list.as_ref(), struct_array.column(9).as_ref()) {
494+
if !list_values_eq(list.as_ref(), struct_array.column(13).as_ref()) {
434495
eprintln!("wrong values for lists column");
435496
return 1;
436497
}
437-
if !list_values_eq(fixed_size_list.as_ref(), struct_array.column(10).as_ref()) {
498+
if !list_values_eq(fixed_size_list.as_ref(), struct_array.column(14).as_ref()) {
438499
eprintln!("wrong values for fixed_lists column");
439500
return 1;
440501
}

0 commit comments

Comments
 (0)