@@ -19,12 +19,17 @@ use criterion::Criterion;
1919use criterion:: Throughput ;
2020use cudarc:: driver:: DeviceRepr ;
2121use futures:: executor:: block_on;
22+ use vortex:: array:: ArrayRef ;
2223use vortex:: array:: IntoArray ;
24+ use vortex:: array:: VortexSessionExecute ;
25+ use vortex:: array:: arrays:: Patched ;
2326use vortex:: array:: arrays:: PrimitiveArray ;
2427use vortex:: array:: validity:: Validity :: NonNullable ;
2528use vortex:: buffer:: Buffer ;
2629use vortex:: dtype:: NativePType ;
30+ use vortex:: encodings:: fastlanes:: BitPacked as BitPackedEncoding ;
2731use vortex:: encodings:: fastlanes:: BitPackedArray ;
32+ use vortex:: encodings:: fastlanes:: BitPackedArrayExt ;
2833use vortex:: encodings:: fastlanes:: BitPackedData ;
2934use vortex:: encodings:: fastlanes:: unpack_iter:: BitPacked ;
3035use vortex:: error:: VortexExpect ;
@@ -39,8 +44,7 @@ use crate::common::TimedLaunchStrategy;
3944const N_ROWS : usize = 100_000_000 ;
4045
4146/// Patch frequencies to benchmark (as fractions)
42- const PATCH_FREQUENCIES : & [ ( f64 , & str ) ] =
43- & [ ( 0.001 , "0.1%" ) , ( 0.01 , "1%" ) , ( 0.05 , "5%" ) , ( 0.10 , "10%" ) ] ;
47+ const PATCH_FREQUENCIES : & [ ( f64 , & str ) ] = & [ ( 0.01 , "1%" ) , ( 0.10 , "10%" ) ] ;
4448
4549/// Create a bit-packed array with the given bit width
4650fn make_bitpacked_array < T > ( bit_width : u8 , len : usize ) -> BitPackedArray
@@ -61,14 +65,20 @@ where
6165 . vortex_expect ( "failed to create BitPacked array" )
6266}
6367
64- /// Create a bit-packed array with the given bit width and patch frequency.
68+ /// Create a `Patched` array wrapping a patch-free `BitPacked` array with the given
69+ /// bit width and patch frequency.
6570///
6671/// `patch_frequency` is a fraction (0.0 to 1.0) indicating what proportion of values
6772/// should exceed the bit width and become patches.
6873///
6974/// This function uses bit_width=6 internally since patch values need to exceed
7075/// the bit width but still fit in u8 for the From<u8> trait bound.
71- fn make_bitpacked_array_with_patches < T > ( len : usize , patch_frequency : f64 ) -> BitPackedArray
76+ ///
77+ /// The bit-packed array initially produced by `BitPackedData::encode` carries its
78+ /// patches inline. We extract those patches and re-wrap the patch-free `BitPacked`
79+ /// in a `Patched` so the CUDA executor dispatches through `PatchedExecutor` (which
80+ /// fuses patching with bit-unpacking).
81+ fn make_bitpacked_array_with_patches < T > ( len : usize , patch_frequency : f64 ) -> ArrayRef
7282where
7383 T : NativePType + Add < Output = T > + From < u8 > ,
7484{
@@ -97,8 +107,33 @@ where
97107 . collect ( ) ;
98108
99109 let primitive_array = PrimitiveArray :: new ( Buffer :: from ( values) , NonNullable ) . into_array ( ) ;
100- BitPackedData :: encode ( & primitive_array, bit_width)
101- . vortex_expect ( "failed to create BitPacked array with patches" )
110+ let bitpacked = BitPackedData :: encode ( & primitive_array, bit_width)
111+ . vortex_expect ( "failed to create BitPacked array with patches" ) ;
112+
113+ let patches = bitpacked
114+ . patches ( )
115+ . vortex_expect ( "expected patches at non-zero patch frequency" ) ;
116+
117+ let bitpacked_without_patches = BitPackedEncoding :: try_new (
118+ bitpacked. packed ( ) . clone ( ) ,
119+ bitpacked. dtype ( ) . as_ptype ( ) ,
120+ BitPackedArrayExt :: validity ( & bitpacked) ,
121+ None ,
122+ bitpacked. bit_width ( ) ,
123+ bitpacked. len ( ) ,
124+ bitpacked. offset ( ) ,
125+ )
126+ . vortex_expect ( "failed to rebuild patch-free BitPacked" )
127+ . into_array ( ) ;
128+
129+ let session = VortexSession :: empty ( ) ;
130+ Patched :: from_array_and_patches (
131+ bitpacked_without_patches,
132+ & patches,
133+ & mut session. create_execution_ctx ( ) ,
134+ )
135+ . vortex_expect ( "failed to wrap BitPacked in Patched" )
136+ . into_array ( )
102137}
103138
104139/// Generic benchmark function for a specific type and bit width
0 commit comments