@@ -12,7 +12,7 @@ use vortex_array::arrays::PrimitiveArrayParts;
1212use vortex_array:: arrays:: StructArray ;
1313use vortex_array:: arrays:: StructArrayParts ;
1414use vortex_array:: buffer:: BufferHandle ;
15- use vortex_array:: validity :: Validity ;
15+ use vortex_array:: vtable :: ValidityHelper ;
1616use vortex_dtype:: DecimalType ;
1717use vortex_dtype:: datetime:: AnyTemporal ;
1818use vortex_error:: VortexResult ;
@@ -26,6 +26,10 @@ use crate::arrow::DeviceType;
2626use crate :: arrow:: ExportDeviceArray ;
2727use crate :: arrow:: PrivateData ;
2828use crate :: arrow:: SyncEvent ;
29+ use crate :: arrow:: check_validity_empty;
30+ use crate :: arrow:: ensure_device_resident;
31+ use crate :: arrow:: varbinview:: BinaryParts ;
32+ use crate :: arrow:: varbinview:: copy_varbinview_to_varbin;
2933use crate :: executor:: CudaArrayExt ;
3034
3135/// An implementation of `ExportDeviceArray` that exports Vortex arrays to `ArrowDeviceArray` by
@@ -43,11 +47,11 @@ impl ExportDeviceArray for CanonicalDeviceArrayExport {
4347 ) -> VortexResult < ArrowDeviceArray > {
4448 let cuda_array = array. execute_cuda ( ctx) . await ?;
4549
46- let ( arrow_array, sync_event ) = export_canonical ( cuda_array, ctx) . await ?;
50+ let ( arrow_array, _ ) = export_canonical ( cuda_array, ctx) . await ?;
4751
4852 Ok ( ArrowDeviceArray {
4953 array : arrow_array,
50- sync_event,
54+ sync_event : None ,
5155 device_id : ctx. stream ( ) . context ( ) . ordinal ( ) as i64 ,
5256 device_type : DeviceType :: Cuda ,
5357 _reserved : Default :: default ( ) ,
@@ -68,7 +72,7 @@ fn export_canonical(
6872 buffer, validity, ..
6973 } = primitive. into_parts ( ) ;
7074
71- check_validity_empty ( validity) ?;
75+ check_validity_empty ( & validity) ?;
7276
7377 let buffer = ensure_device_resident ( buffer, ctx) . await ?;
7478
@@ -96,7 +100,7 @@ fn export_canonical(
96100 } = decimal. into_parts ( ) ;
97101
98102 // verify that there is no null buffer
99- check_validity_empty ( validity) ?;
103+ check_validity_empty ( & validity) ?;
100104
101105 // TODO(aduffy): GPU kernel for upcasting.
102106 vortex_ensure ! (
@@ -120,12 +124,11 @@ fn export_canonical(
120124 buffer, validity, ..
121125 } = values. into_parts ( ) ;
122126
123- check_validity_empty ( validity) ?;
127+ check_validity_empty ( & validity) ?;
124128
125129 let buffer = ensure_device_resident ( buffer, ctx) . await ?;
126130 export_fixed_size ( buffer, len, 0 , ctx)
127131 }
128-
129132 Canonical :: Bool ( bool_array) => {
130133 let BoolArrayParts {
131134 bits,
@@ -135,10 +138,40 @@ fn export_canonical(
135138 ..
136139 } = bool_array. into_parts ( ) ;
137140
138- check_validity_empty ( validity) ?;
141+ check_validity_empty ( & validity) ?;
139142
140143 export_fixed_size ( bits, len, offset, ctx)
141144 }
145+ Canonical :: VarBinView ( varbinview) => {
146+ let len = varbinview. len ( ) ;
147+ check_validity_empty ( varbinview. validity ( ) ) ?;
148+
149+ let BinaryParts { offsets, bytes } =
150+ copy_varbinview_to_varbin ( varbinview, ctx) . await ?;
151+
152+ let offsets = ensure_device_resident ( offsets, ctx) . await ?;
153+ let bytes = ensure_device_resident ( bytes, ctx) . await ?;
154+
155+ let buffers = vec ! [ None , Some ( offsets) , Some ( bytes) ] ;
156+ let mut private_data = PrivateData :: new ( buffers, vec ! [ ] , ctx) ?;
157+ let sync_event = private_data. sync_event ( ) ;
158+ //
159+ let arrow_array = ArrowArray {
160+ length : len as i64 ,
161+ null_count : 0 ,
162+ offset : 0 ,
163+ // 1 (optional) buffer for nulls, one buffer for the data
164+ n_buffers : 2 ,
165+ buffers : private_data. buffer_ptrs . as_mut_ptr ( ) ,
166+ n_children : 0 ,
167+ children : std:: ptr:: null_mut ( ) ,
168+ release : Some ( release_array) ,
169+ dictionary : std:: ptr:: null_mut ( ) ,
170+ private_data : Box :: into_raw ( private_data) . cast ( ) ,
171+ } ;
172+
173+ Ok ( ( arrow_array, sync_event) )
174+ }
142175 // TODO(aduffy): implement VarBinView. cudf doesn't support it, so we need to
143176 // execute a kernel to translate from VarBinView -> VarBin.
144177 c => todo ! ( "support for exporting {} arrays" , c. dtype( ) ) ,
@@ -155,7 +188,7 @@ async fn export_struct(
155188 validity, fields, ..
156189 } = array. into_parts ( ) ;
157190
158- check_validity_empty ( validity) ?;
191+ check_validity_empty ( & validity) ?;
159192
160193 // We need the children to be held across await points.
161194 let mut children = Vec :: with_capacity ( fields. len ( ) ) ;
@@ -220,26 +253,6 @@ fn export_fixed_size(
220253 Ok ( ( arrow_array, sync_event) )
221254}
222255
223- /// Check that the validity buffer is empty and does not need to be copied over the device boundary.
224- fn check_validity_empty ( validity : Validity ) -> VortexResult < ( ) > {
225- if let Validity :: AllInvalid | Validity :: Array ( _) = validity {
226- vortex_bail ! ( "Exporting array with non-trivial validity not supported yet" )
227- }
228-
229- Ok ( ( ) )
230- }
231-
232- async fn ensure_device_resident (
233- buffer_handle : BufferHandle ,
234- ctx : & mut CudaExecutionCtx ,
235- ) -> VortexResult < BufferHandle > {
236- if buffer_handle. is_on_device ( ) {
237- Ok ( buffer_handle)
238- } else {
239- ctx. move_to_device ( buffer_handle) ?. await
240- }
241- }
242-
243256// export some nested data
244257
245258unsafe extern "C" fn release_array ( array : * mut ArrowArray ) {
0 commit comments