Skip to content

Commit 4048756

Browse files
committed
remove all to_canonical and replace with execute
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
1 parent 0e8aa1c commit 4048756

6 files changed

Lines changed: 96 additions & 45 deletions

File tree

vortex-tensor/src/encodings/turboquant/compress.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,12 @@ impl Default for TurboQuantConfig {
5656
///
5757
/// All quantization (rotation, centroid lookup) happens in f32. f16 is upcast; f64 is truncated.
5858
#[allow(clippy::cast_possible_truncation)]
59-
fn extract_f32_elements(fsl: &FixedSizeListArray) -> VortexResult<PrimitiveArray> {
59+
fn extract_f32_elements(
60+
fsl: &FixedSizeListArray,
61+
ctx: &mut ExecutionCtx,
62+
) -> VortexResult<PrimitiveArray> {
6063
let elements = fsl.elements();
61-
let primitive = elements.to_canonical()?.into_primitive();
64+
let primitive = elements.clone().execute::<PrimitiveArray>(ctx)?;
6265
let ptype = primitive.ptype();
6366

6467
match ptype {
@@ -128,7 +131,7 @@ fn turboquant_quantize_core(
128131
let rotation = RotationMatrix::try_new(seed, dimension)?;
129132
let padded_dim = rotation.padded_dim();
130133

131-
let f32_elements = extract_f32_elements(fsl)?;
134+
let f32_elements = extract_f32_elements(fsl, ctx)?;
132135

133136
let centroids = get_centroids(padded_dim as u32, bit_width)?;
134137
let boundaries = compute_centroid_boundaries(&centroids);
@@ -220,7 +223,7 @@ pub fn turboquant_encode(
220223
) -> VortexResult<ArrayRef> {
221224
let ext_dtype = ext.dtype().clone();
222225
let storage = ext.storage_array();
223-
let fsl = storage.to_canonical()?.into_fixed_size_list();
226+
let fsl = storage.clone().execute::<FixedSizeListArray>(ctx)?;
224227

225228
vortex_ensure!(
226229
config.bit_width >= 1 && config.bit_width <= TurboQuant::MAX_BIT_WIDTH,

vortex-tensor/src/encodings/turboquant/decompress.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ pub fn execute_decompress(
7373

7474
// Unpack codes from FixedSizeListArray -> flat u8 elements.
7575
let codes_fsl = array.codes().clone().execute::<FixedSizeListArray>(ctx)?;
76-
let codes_prim = codes_fsl.elements().to_canonical()?.into_primitive();
76+
let codes_prim = codes_fsl
77+
.elements()
78+
.clone()
79+
.execute::<PrimitiveArray>(ctx)?;
7780
let indices = codes_prim.as_slice::<u8>();
7881

7982
// Read norms in their native precision. Norms carry the validity of the array.

vortex-tensor/src/encodings/turboquant/tests.rs

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,24 @@ fn encode_decode(
125125
fsl: &FixedSizeListArray,
126126
config: &TurboQuantConfig,
127127
) -> VortexResult<(Vec<f32>, Vec<f32>)> {
128+
let mut ctx = SESSION.create_execution_ctx();
128129
let original: Vec<f32> = {
129-
let prim = fsl.elements().to_canonical().unwrap().into_primitive();
130+
let prim = fsl.elements().clone().execute::<PrimitiveArray>(&mut ctx)?;
130131
prim.as_slice::<f32>().to_vec()
131132
};
132133
let ext = make_vector_ext(fsl);
133134
let config = config.clone();
134-
let mut ctx = SESSION.create_execution_ctx();
135135
let encoded = turboquant_encode(ext.as_view(), &config, &mut ctx)?;
136136
let decoded_ext = encoded.execute::<ExtensionArray>(&mut ctx)?;
137137
let decoded_fsl = decoded_ext
138138
.storage_array()
139-
.to_canonical()
140-
.unwrap()
141-
.into_fixed_size_list();
139+
.clone()
140+
.execute::<FixedSizeListArray>(&mut ctx)?;
142141
let decoded_elements: Vec<f32> = {
143142
let prim = decoded_fsl
144143
.elements()
145-
.to_canonical()
146-
.unwrap()
147-
.into_primitive();
144+
.clone()
145+
.execute::<PrimitiveArray>(&mut ctx)?;
148146
prim.as_slice::<f32>().to_vec()
149147
};
150148
Ok((original, decoded_elements))
@@ -409,8 +407,8 @@ fn f16_input_encodes_successfully() -> VortexResult<()> {
409407
let decoded_ext = encoded.execute::<ExtensionArray>(&mut ctx)?;
410408
let decoded_fsl = decoded_ext
411409
.storage_array()
412-
.to_canonical()?
413-
.into_fixed_size_list();
410+
.clone()
411+
.execute::<FixedSizeListArray>(&mut ctx)?;
414412
assert_eq!(decoded_fsl.len(), num_rows);
415413
Ok(())
416414
}
@@ -470,9 +468,12 @@ fn stored_rotation_signs_produce_correct_decode() -> VortexResult<()> {
470468
.execute::<ExtensionArray>(&mut ctx)?;
471469
let decoded_fsl = decoded_ext
472470
.storage_array()
473-
.to_canonical()?
474-
.into_fixed_size_list();
475-
let decoded = decoded_fsl.elements().to_canonical()?.into_primitive();
471+
.clone()
472+
.execute::<FixedSizeListArray>(&mut ctx)?;
473+
let decoded = decoded_fsl
474+
.elements()
475+
.clone()
476+
.execute::<PrimitiveArray>(&mut ctx)?;
476477
let decoded_slice = decoded.as_slice::<f32>();
477478

478479
// Verify stored signs match seed-derived signs.
@@ -514,20 +515,26 @@ fn slice_preserves_data() -> VortexResult<()> {
514515
let full_decoded = encoded.clone().execute::<ExtensionArray>(&mut ctx)?;
515516
let full_fsl = full_decoded
516517
.storage_array()
517-
.to_canonical()?
518-
.into_fixed_size_list();
518+
.clone()
519+
.execute::<FixedSizeListArray>(&mut ctx)?;
519520
let expected = full_fsl.slice(5..10)?;
520-
let expected_prim = expected.to_canonical()?.into_fixed_size_list();
521-
let expected_elements = expected_prim.elements().to_canonical()?.into_primitive();
521+
let expected_fsl = expected.execute::<FixedSizeListArray>(&mut ctx)?;
522+
let expected_elements = expected_fsl
523+
.elements()
524+
.clone()
525+
.execute::<PrimitiveArray>(&mut ctx)?;
522526

523527
// Slice then decompress.
524528
let sliced = encoded.slice(5..10)?;
525529
let sliced_decoded = sliced.execute::<ExtensionArray>(&mut ctx)?;
526530
let sliced_fsl = sliced_decoded
527531
.storage_array()
528-
.to_canonical()?
529-
.into_fixed_size_list();
530-
let actual_elements = sliced_fsl.elements().to_canonical()?.into_primitive();
532+
.clone()
533+
.execute::<FixedSizeListArray>(&mut ctx)?;
534+
let actual_elements = sliced_fsl
535+
.elements()
536+
.clone()
537+
.execute::<PrimitiveArray>(&mut ctx)?;
531538

532539
assert_eq!(
533540
expected_elements.as_slice::<f32>(),
@@ -570,10 +577,10 @@ fn l2_norm_readthrough() -> VortexResult<()> {
570577
let tq = encoded.as_opt::<TurboQuant>().unwrap();
571578

572579
// Stored norms should match the actual L2 norms of the input.
573-
let norms_prim = tq.norms().to_canonical()?.into_primitive();
580+
let norms_prim = tq.norms().clone().execute::<PrimitiveArray>(&mut ctx)?;
574581
let stored_norms = norms_prim.as_slice::<f32>();
575582

576-
let input_prim = fsl.elements().to_canonical()?.into_primitive();
583+
let input_prim = fsl.elements().clone().execute::<PrimitiveArray>(&mut ctx)?;
577584
let input_f32 = input_prim.as_slice::<f32>();
578585
for row in 0..10 {
579586
let vec = &input_f32[row * 128..(row + 1) * 128];
@@ -601,7 +608,7 @@ fn cosine_similarity_quantized_accuracy() -> VortexResult<()> {
601608
let tq = encoded.as_opt::<TurboQuant>().unwrap();
602609

603610
// Compute exact cosine similarity from original data.
604-
let input_prim = fsl.elements().to_canonical()?.into_primitive();
611+
let input_prim = fsl.elements().clone().execute::<PrimitiveArray>(&mut ctx)?;
605612
let input_f32 = input_prim.as_slice::<f32>();
606613

607614
// Read quantized codes, norms, and centroids for approximate computation.
@@ -610,7 +617,10 @@ fn cosine_similarity_quantized_accuracy() -> VortexResult<()> {
610617
let norms_prim = tq.norms().clone().execute::<PrimitiveArray>(&mut ctx)?;
611618
let norms = norms_prim.as_slice::<f32>();
612619
let codes_fsl = tq.codes().clone().execute::<FixedSizeListArray>(&mut ctx)?;
613-
let codes_prim = codes_fsl.elements().to_canonical()?.into_primitive();
620+
let codes_prim = codes_fsl
621+
.elements()
622+
.clone()
623+
.execute::<PrimitiveArray>(&mut ctx)?;
614624
let all_codes = codes_prim.as_slice::<u8>();
615625
let centroids_prim = tq.centroids().clone().execute::<PrimitiveArray>(&mut ctx)?;
616626
let centroid_vals = centroids_prim.as_slice::<f32>();
@@ -674,15 +684,18 @@ fn dot_product_quantized_accuracy() -> VortexResult<()> {
674684
let encoded = turboquant_encode(ext.as_view(), &config, &mut ctx)?;
675685
let tq = encoded.as_opt::<TurboQuant>().unwrap();
676686

677-
let input_prim = fsl.elements().to_canonical()?.into_primitive();
687+
let input_prim = fsl.elements().clone().execute::<PrimitiveArray>(&mut ctx)?;
678688
let input_f32 = input_prim.as_slice::<f32>();
679689

680690
let mut ctx = SESSION.create_execution_ctx();
681691
let pd = tq.padded_dim() as usize;
682692
let norms_prim = tq.norms().clone().execute::<PrimitiveArray>(&mut ctx)?;
683693
let norms = norms_prim.as_slice::<f32>();
684694
let codes_fsl = tq.codes().clone().execute::<FixedSizeListArray>(&mut ctx)?;
685-
let codes_prim = codes_fsl.elements().to_canonical()?.into_primitive();
695+
let codes_prim = codes_fsl
696+
.elements()
697+
.clone()
698+
.execute::<PrimitiveArray>(&mut ctx)?;
686699
let all_codes = codes_prim.as_slice::<u8>();
687700
let centroids_prim = tq.centroids().clone().execute::<PrimitiveArray>(&mut ctx)?;
688701
let centroid_vals = centroids_prim.as_slice::<f32>();
@@ -815,13 +828,16 @@ fn nullable_vectors_roundtrip() -> VortexResult<()> {
815828

816829
let decoded_fsl = decoded_ext
817830
.storage_array()
818-
.to_canonical()?
819-
.into_fixed_size_list();
820-
let decoded_prim = decoded_fsl.elements().to_canonical()?.into_primitive();
831+
.clone()
832+
.execute::<FixedSizeListArray>(&mut ctx)?;
833+
let decoded_prim = decoded_fsl
834+
.elements()
835+
.clone()
836+
.execute::<PrimitiveArray>(&mut ctx)?;
821837
let decoded_f32 = decoded_prim.as_slice::<f32>();
822838

823839
// Original f32 elements for non-null row comparison.
824-
let orig_prim = fsl.elements().to_canonical()?.into_primitive();
840+
let orig_prim = fsl.elements().clone().execute::<PrimitiveArray>(&mut ctx)?;
825841
let orig_f32 = orig_prim.as_slice::<f32>();
826842

827843
// Non-null rows should have reasonable reconstruction (within MSE bounds).
@@ -889,7 +905,7 @@ fn nullable_l2_norm_readthrough() -> VortexResult<()> {
889905
let norms: PrimitiveArray = norm_sfn.into_array().execute(&mut ctx)?;
890906

891907
// Null rows should have null norms, valid rows should have correct norms.
892-
let orig_prim = fsl.elements().to_canonical()?.into_primitive();
908+
let orig_prim = fsl.elements().clone().execute::<PrimitiveArray>(&mut ctx)?;
893909
let orig_f32 = orig_prim.as_slice::<f32>();
894910
for row in 0..5 {
895911
if row % 2 == 0 {

vortex-tensor/src/scalar_fns/cosine_similarity.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,20 @@ impl ScalarFnVTable for CosineSimilarity {
206206

207207
#[cfg(test)]
208208
mod tests {
209+
use std::sync::LazyLock;
210+
209211
use rstest::rstest;
210212
use vortex_array::ArrayRef;
211213
use vortex_array::IntoArray;
212-
use vortex_array::ToCanonical;
214+
use vortex_array::VortexSessionExecute;
213215
use vortex_array::arrays::MaskedArray;
216+
use vortex_array::arrays::PrimitiveArray;
214217
use vortex_array::arrays::ScalarFnArray;
215218
use vortex_array::scalar_fn::ScalarFn;
219+
use vortex_array::session::ArraySession;
216220
use vortex_array::validity::Validity;
217221
use vortex_error::VortexResult;
222+
use vortex_session::VortexSession;
218223

219224
use crate::scalar_fns::ApproxOptions;
220225
use crate::scalar_fns::cosine_similarity::CosineSimilarity;
@@ -224,11 +229,15 @@ mod tests {
224229
use crate::utils::test_helpers::tensor_array;
225230
use crate::utils::test_helpers::vector_array;
226231

232+
static SESSION: LazyLock<VortexSession> =
233+
LazyLock::new(|| VortexSession::empty().with::<ArraySession>());
234+
227235
/// Evaluates cosine similarity between two tensor arrays and returns the result as `Vec<f64>`.
228236
fn eval_cosine_similarity(lhs: ArrayRef, rhs: ArrayRef, len: usize) -> VortexResult<Vec<f64>> {
229237
let scalar_fn = ScalarFn::new(CosineSimilarity, ApproxOptions::Exact).erased();
230238
let result = ScalarFnArray::try_new(scalar_fn, vec![lhs, rhs], len)?;
231-
let prim = result.as_array().to_primitive();
239+
let mut ctx = SESSION.create_execution_ctx();
240+
let prim: PrimitiveArray = result.into_array().execute(&mut ctx)?;
232241
Ok(prim.as_slice::<f64>().to_vec())
233242
}
234243

@@ -398,7 +407,8 @@ mod tests {
398407

399408
let scalar_fn = ScalarFn::new(CosineSimilarity, ApproxOptions::Exact).erased();
400409
let result = ScalarFnArray::try_new(scalar_fn, vec![lhs, rhs], 2)?;
401-
let prim = result.as_array().to_primitive();
410+
let mut ctx = SESSION.create_execution_ctx();
411+
let prim: PrimitiveArray = result.into_array().execute(&mut ctx)?;
402412

403413
// Row 0: self-similarity = 1.0, row 1: null.
404414
assert!(prim.is_valid(0)?);

vortex-tensor/src/scalar_fns/inner_product.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,28 +213,36 @@ fn inner_product_row<T: Float + NativePType>(a: &[T], b: &[T]) -> T {
213213

214214
#[cfg(test)]
215215
mod tests {
216+
use std::sync::LazyLock;
217+
216218
use rstest::rstest;
217219
use vortex_array::ArrayRef;
218220
use vortex_array::IntoArray;
219-
use vortex_array::ToCanonical;
221+
use vortex_array::VortexSessionExecute;
220222
use vortex_array::arrays::MaskedArray;
221223
use vortex_array::arrays::PrimitiveArray;
222224
use vortex_array::arrays::ScalarFnArray;
223225
use vortex_array::scalar_fn::ScalarFn;
226+
use vortex_array::session::ArraySession;
224227
use vortex_array::validity::Validity;
225228
use vortex_error::VortexResult;
229+
use vortex_session::VortexSession;
226230

227231
use crate::scalar_fns::ApproxOptions;
228232
use crate::scalar_fns::inner_product::InnerProduct;
229233
use crate::utils::test_helpers::assert_close;
230234
use crate::utils::test_helpers::tensor_array;
231235
use crate::utils::test_helpers::vector_array;
232236

237+
static SESSION: LazyLock<VortexSession> =
238+
LazyLock::new(|| VortexSession::empty().with::<ArraySession>());
239+
233240
/// Evaluates inner product between two tensor arrays and returns the result as `Vec<f64>`.
234241
fn eval_inner_product(lhs: ArrayRef, rhs: ArrayRef, len: usize) -> VortexResult<Vec<f64>> {
235242
let scalar_fn = ScalarFn::new(InnerProduct, ApproxOptions::Exact).erased();
236243
let result = ScalarFnArray::try_new(scalar_fn, vec![lhs, rhs], len)?;
237-
let prim = result.as_array().to_primitive();
244+
let mut ctx = SESSION.create_execution_ctx();
245+
let prim: PrimitiveArray = result.into_array().execute(&mut ctx)?;
238246
Ok(prim.as_slice::<f64>().to_vec())
239247
}
240248

@@ -311,7 +319,8 @@ mod tests {
311319

312320
let scalar_fn = ScalarFn::new(InnerProduct, ApproxOptions::Exact).erased();
313321
let result = ScalarFnArray::try_new(scalar_fn, vec![lhs, rhs], 3)?;
314-
let prim = result.as_array().to_primitive();
322+
let mut ctx = SESSION.create_execution_ctx();
323+
let prim: PrimitiveArray = result.into_array().execute(&mut ctx)?;
315324

316325
// Row 0: 1*7 + 2*8 = 23, row 1: null, row 2: 5*11 + 6*12 = 127.
317326
assert!(prim.is_valid(0)?);

vortex-tensor/src/scalar_fns/l2_norm.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,27 +196,36 @@ fn l2_norm_row<T: Float + NativePType>(v: &[T]) -> T {
196196

197197
#[cfg(test)]
198198
mod tests {
199+
use std::sync::LazyLock;
200+
199201
use rstest::rstest;
200202
use vortex_array::ArrayRef;
201203
use vortex_array::IntoArray;
202-
use vortex_array::ToCanonical;
204+
use vortex_array::VortexSessionExecute;
203205
use vortex_array::arrays::MaskedArray;
206+
use vortex_array::arrays::PrimitiveArray;
204207
use vortex_array::arrays::ScalarFnArray;
205208
use vortex_array::scalar_fn::ScalarFn;
209+
use vortex_array::session::ArraySession;
206210
use vortex_array::validity::Validity;
207211
use vortex_error::VortexResult;
212+
use vortex_session::VortexSession;
208213

209214
use crate::scalar_fns::ApproxOptions;
210215
use crate::scalar_fns::l2_norm::L2Norm;
211216
use crate::utils::test_helpers::assert_close;
212217
use crate::utils::test_helpers::tensor_array;
213218
use crate::utils::test_helpers::vector_array;
214219

220+
static SESSION: LazyLock<VortexSession> =
221+
LazyLock::new(|| VortexSession::empty().with::<ArraySession>());
222+
215223
/// Evaluates L2 norm on a tensor/vector array and returns the result as `Vec<f64>`.
216224
fn eval_l2_norm(input: ArrayRef, len: usize) -> VortexResult<Vec<f64>> {
217225
let scalar_fn = ScalarFn::new(L2Norm, ApproxOptions::Exact).erased();
218226
let result = ScalarFnArray::try_new(scalar_fn, vec![input], len)?;
219-
let prim = result.as_array().to_primitive();
227+
let mut ctx = SESSION.create_execution_ctx();
228+
let prim: PrimitiveArray = result.into_array().execute(&mut ctx)?;
220229
Ok(prim.as_slice::<f64>().to_vec())
221230
}
222231

@@ -270,7 +279,8 @@ mod tests {
270279

271280
let scalar_fn = ScalarFn::new(L2Norm, ApproxOptions::Exact).erased();
272281
let result = ScalarFnArray::try_new(scalar_fn, vec![arr], 2)?;
273-
let prim = result.as_array().to_primitive();
282+
let mut ctx = SESSION.create_execution_ctx();
283+
let prim: PrimitiveArray = result.into_array().execute(&mut ctx)?;
274284

275285
// Row 0: norm = 5.0, row 1: null.
276286
assert!(prim.is_valid(0)?);

0 commit comments

Comments
 (0)