Skip to content

Commit acd90db

Browse files
committed
add array validation
Signed-off-by: Andrew Duffy <andrew@a10y.dev>
1 parent e481129 commit acd90db

2 files changed

Lines changed: 45 additions & 19 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
/.idea
12
build

src/main.cpp

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include <cstdlib>
2-
#include <cstring>
32
#include <dlfcn.h>
43
#include <iostream>
54
#include <memory>
@@ -8,24 +7,22 @@
87
#include <cudf/column/column.hpp>
98
#include <cudf/column/column_view.hpp>
109
#include <cudf/interop.hpp>
11-
#include <cudf/io/types.hpp>
1210
#include <cudf/types.hpp>
13-
#include <cudf/utilities/type_dispatcher.hpp>
14-
#include <rmm/mr/per_device_resource.hpp>
1511

1612
#include "arrow_c_device.h"
1713

1814
// Function pointer type for export_array
19-
using export_array_fn = int (*)(ArrowSchema*, ArrowDeviceArray*);
15+
using export_array_fn = int (*)(ArrowSchema *, ArrowDeviceArray *);
16+
using validate_array_fn = int (*)(ArrowSchema *, ArrowArray *);
2017

21-
void print_usage(const char* program_name) {
18+
void print_usage(const char *program_name) {
2219
std::cerr << "Usage: " << program_name << " check <library.so>\n";
2320
std::cerr << "\n";
2421
std::cerr << "Commands:\n";
2522
std::cerr << " check <library.so> Load the library and test Arrow device data export\n";
2623
}
2724

28-
const char* device_type_to_string(ArrowDeviceType device_type) {
25+
const char *device_type_to_string(ArrowDeviceType device_type) {
2926
switch (device_type) {
3027
case ARROW_DEVICE_CPU: return "CPU";
3128
case ARROW_DEVICE_CUDA: return "CUDA";
@@ -37,7 +34,7 @@ const char* device_type_to_string(ArrowDeviceType device_type) {
3734
}
3835
}
3936

40-
const char* cudf_type_to_string(cudf::type_id type) {
37+
const char *cudf_type_to_string(cudf::type_id type) {
4138
switch (type) {
4239
case cudf::type_id::EMPTY: return "EMPTY";
4340
case cudf::type_id::INT8: return "INT8";
@@ -72,20 +69,20 @@ const char* cudf_type_to_string(cudf::type_id type) {
7269
}
7370
}
7471

75-
void print_column_stats(const cudf::column_view& col) {
76-
std::cout << "Column Statistics:\n";
72+
void print_column_stats(const cudf::column_view &col, const char *name) {
73+
std::cout << "Column Statistics(" << name << "):\n";
7774
std::cout << " Type: " << cudf_type_to_string(col.type().id()) << "\n";
7875
std::cout << " Size: " << col.size() << " rows\n";
7976
std::cout << " Null count: " << col.null_count() << "\n";
8077
std::cout << " Has nulls: " << (col.has_nulls() ? "yes" : "no") << "\n";
8178
std::cout << " Num children: " << col.num_children() << "\n";
8279
}
8380

84-
int run_check(const char* library_path) {
81+
int run_check(const char *library_path) {
8582
std::cout << "Loading library: " << library_path << "\n";
8683

8784
// Open the shared library
88-
void* handle = dlopen(library_path, RTLD_NOW);
85+
void *handle = dlopen(library_path, RTLD_NOW);
8986
if (!handle) {
9087
std::cerr << "Error: Failed to load library: " << dlerror() << "\n";
9188
return 1;
@@ -96,7 +93,7 @@ int run_check(const char* library_path) {
9693

9794
// Load the export_array symbol
9895
auto export_array = reinterpret_cast<export_array_fn>(dlsym(handle, "export_array"));
99-
const char* dlsym_error = dlerror();
96+
const char *dlsym_error = dlerror();
10097
if (dlsym_error) {
10198
std::cerr << "Error: Failed to load symbol 'export_array': " << dlsym_error << "\n";
10299
dlclose(handle);
@@ -105,6 +102,8 @@ int run_check(const char* library_path) {
105102

106103
std::cout << "Found export_array symbol\n";
107104

105+
auto validate_array = reinterpret_cast<validate_array_fn>(dlsym(handle, "validate_array"));
106+
108107
// Initialize the Arrow structures
109108
ArrowSchema schema{};
110109
ArrowDeviceArray device_array{};
@@ -129,17 +128,43 @@ int run_check(const char* library_path) {
129128
std::cout << " Device type: " << device_type_to_string(device_array.device_type) << "\n";
130129
std::cout << " Device ID: " << device_array.device_id << "\n";
131130

131+
std::cout << "\nStruct children debug:\n";
132+
std::cout << " Schema n_children: " << schema.n_children << "\n";
133+
std::cout << " Schema children ptr: " << (void *) schema.children << "\n";
134+
std::cout << " Array n_children: " << device_array.array.n_children << "\n";
135+
std::cout << " Array children ptr: " << (void *) device_array.array.children << "\n";
136+
137+
if (schema.children) {
138+
for (int64_t i = 0; i < schema.n_children; i++) {
139+
std::cout << " Child " << i << ":\n";
140+
std::cout << " schema ptr: " << (void *) schema.children[i] << "\n";
141+
if (schema.children[i]) {
142+
std::cout << " format: " << (schema.children[i]->format ? schema.children[i]->format : "(null)") <<
143+
"\n";
144+
std::cout << " name: " << (schema.children[i]->name ? schema.children[i]->name : "(null)") << "\n";
145+
}
146+
if (device_array.array.children) {
147+
std::cout << " array ptr: " << (void *) device_array.array.children[i] << "\n";
148+
if (device_array.array.children[i]) {
149+
std::cout << " array length: " << device_array.array.children[i]->length << "\n";
150+
}
151+
}
152+
}
153+
}
154+
132155
// Convert to cuDF column view using from_arrow_device_column
133156
std::cout << "\nConverting to cuDF column view...\n";
134157
try {
135-
auto column_view_ptr = cudf::from_arrow_device_column(&schema, &device_array);
158+
auto table = cudf::from_arrow_device(&schema, &device_array);
136159

137160
std::cout << "Conversion successful!\n\n";
138161

139-
// Print summary stats
140-
print_column_stats(*column_view_ptr);
141-
142-
} catch (const std::exception& e) {
162+
// convert to host array, call the verifier inside of the shared library.
163+
auto host_array = cudf::to_arrow_host(*table);
164+
if (validate_array(&schema, &host_array->array) != 0) {
165+
std::cerr << "\nValidation failed!\n";
166+
}
167+
} catch (const std::exception &e) {
143168
std::cerr << "Error: Failed to convert Arrow array to cuDF column: " << e.what() << "\n";
144169

145170
// Release the Arrow array
@@ -177,7 +202,7 @@ int run_check(const char* library_path) {
177202
return 0;
178203
}
179204

180-
int main(int argc, char* argv[]) {
205+
int main(int argc, char *argv[]) {
181206
if (argc < 2) {
182207
print_usage(argv[0]);
183208
return 1;

0 commit comments

Comments
 (0)