Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions encodings/alp/src/alp/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ use vortex_array::IntoArray;
use vortex_array::Precision;
use vortex_array::ProstMetadata;
use vortex_array::SerializeMetadata;
use vortex_array::arrays::Primitive;
use vortex_array::buffer::BufferHandle;
use vortex_array::dtype::DType;
use vortex_array::dtype::PType;
use vortex_array::patches::Patches;
use vortex_array::patches::PatchesMetadata;
use vortex_array::require_child;
use vortex_array::require_patches;
use vortex_array::serde::ArrayChildren;
use vortex_array::stats::ArrayStats;
use vortex_array::stats::StatsSetRef;
Expand Down Expand Up @@ -191,6 +194,15 @@ impl VTable for ALP {
}

fn execute(array: Arc<Array<Self>>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
let array = require_child!(array, array.encoded(), ENCODED_SLOT => Primitive);
require_patches!(
array,
array.patches(),
PATCH_INDICES_SLOT,
PATCH_VALUES_SLOT,
PATCH_CHUNK_OFFSETS_SLOT
);

Ok(ExecutionResult::done(
execute_decompress(Arc::unwrap_or_clone(array).into_inner(), ctx)?.into_array(),
))
Expand Down
9 changes: 8 additions & 1 deletion encodings/alp/src/alp_rd/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use vortex_array::dtype::PType;
use vortex_array::patches::Patches;
use vortex_array::patches::PatchesMetadata;
use vortex_array::require_child;
use vortex_array::require_patches;
use vortex_array::serde::ArrayChildren;
use vortex_array::stats::ArrayStats;
use vortex_array::stats::StatsSetRef;
Expand Down Expand Up @@ -271,6 +272,13 @@ impl VTable for ALPRD {
fn execute(array: Arc<Array<Self>>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
let array = require_child!(array, array.left_parts(), 0 => Primitive);
let array = require_child!(array, array.right_parts(), 1 => Primitive);
require_patches!(
array,
array.left_parts_patches(),
LP_PATCH_INDICES_SLOT,
LP_PATCH_VALUES_SLOT,
LP_PATCH_CHUNK_OFFSETS_SLOT
);

let right_bit_width = array.right_bit_width();
let ALPRDArrayParts {
Expand All @@ -297,7 +305,6 @@ impl VTable for ALPRD {
let validity = left_parts.validity_mask()?;

let decoded_array = if ptype == PType::F32 {
// TODO(joe): use iterative execution for the patches.
PrimitiveArray::new(
alp_rd_decode::<f32>(
left_parts.into_buffer::<u16>(),
Expand Down
14 changes: 14 additions & 0 deletions encodings/fastlanes/src/bitpacking/vtable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use std::hash::Hash;
use std::sync::Arc;

use vortex_array::AnyCanonical;
use vortex_array::ArrayEq;
use vortex_array::ArrayHash;
use vortex_array::ArrayRef;
Expand All @@ -21,6 +22,8 @@ use vortex_array::dtype::PType;
use vortex_array::match_each_integer_ptype;
use vortex_array::patches::Patches;
use vortex_array::patches::PatchesMetadata;
use vortex_array::require_patches;
use vortex_array::require_validity;
use vortex_array::serde::ArrayChildren;
use vortex_array::stats::StatsSetRef;
use vortex_array::validity::Validity;
Expand All @@ -40,9 +43,11 @@ use crate::BitPackedArray;
use crate::bitpack_decompress::unpack_array;
use crate::bitpack_decompress::unpack_into_primitive_builder;
use crate::bitpacking::array::NUM_SLOTS;
use crate::bitpacking::array::PATCH_CHUNK_OFFSETS_SLOT;
use crate::bitpacking::array::PATCH_INDICES_SLOT;
use crate::bitpacking::array::PATCH_VALUES_SLOT;
use crate::bitpacking::array::SLOT_NAMES;
use crate::bitpacking::array::VALIDITY_SLOT;
use crate::bitpacking::vtable::kernels::PARENT_KERNELS;
use crate::bitpacking::vtable::rules::RULES;
mod kernels;
Expand Down Expand Up @@ -286,6 +291,15 @@ impl VTable for BitPacked {
}

fn execute(array: Arc<Array<Self>>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
require_patches!(
array,
array.patches(),
PATCH_INDICES_SLOT,
PATCH_VALUES_SLOT,
PATCH_CHUNK_OFFSETS_SLOT
);
require_validity!(array, &array.validity(), VALIDITY_SLOT => AnyCanonical);

Ok(ExecutionResult::done(
unpack_array(&array, ctx)?.into_array(),
))
Expand Down
6 changes: 6 additions & 0 deletions vortex-array/public-api.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24082,6 +24082,12 @@ pub macro vortex_array::match_smallest_offset_type!

pub macro vortex_array::require_child!

pub macro vortex_array::require_opt_child!

pub macro vortex_array::require_patches!

pub macro vortex_array::require_validity!

pub macro vortex_array::vtable!

pub enum vortex_array::Canonical
Expand Down
71 changes: 71 additions & 0 deletions vortex-array/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,77 @@ macro_rules! require_child {
}};
}

/// Like [`require_child!`], but for optional children. If the child is `None`, this is a no-op.
/// If the child is `Some` but does not match `$M`, early-returns an [`ExecutionResult`] requesting
/// execution of child `$idx`.
///
/// Unlike `require_child!`, this is a statement macro (no value produced) and does not clone
/// `$parent` — it is moved into the early-return path.
///
/// ```ignore
/// require_opt_child!(array, array.patches().map(|p| p.indices()), 1 => Primitive);
/// ```
#[macro_export]
macro_rules! require_opt_child {
($parent:expr, $child_opt:expr, $idx:expr => $M:ty) => {
if $child_opt.is_some_and(|child| !child.is::<$M>()) {
return Ok($crate::ExecutionResult::execute_slot::<$M>($parent, $idx));
}
};
}

/// Require that all children of a [`Patches`](crate::patches::Patches) (indices, values, and
/// optionally chunk_offsets) are `Primitive`. If no patches are present, this is a no-op.
///
/// Like [`require_opt_child!`], `$parent` is moved (not cloned) into the early-return path.
///
/// ```ignore
/// require_patches!(array, array.patches(), PATCH_INDICES_SLOT, PATCH_VALUES_SLOT, PATCH_CHUNK_OFFSETS_SLOT);
/// ```
#[macro_export]
macro_rules! require_patches {
($parent:expr, $patches:expr, $indices_slot:expr, $values_slot:expr, $chunk_offsets_slot:expr) => {
let __patches = $patches;
$crate::require_opt_child!(
$parent,
__patches.as_ref().map(|p| p.indices()),
$indices_slot => $crate::arrays::Primitive
);
let __patches = $patches;
$crate::require_opt_child!(
$parent,
__patches.as_ref().map(|p| p.values()),
$values_slot => $crate::arrays::Primitive
);
let __patches = $patches;
$crate::require_opt_child!(
$parent,
__patches.as_ref().and_then(|p| p.chunk_offsets().as_ref()),
$chunk_offsets_slot => $crate::arrays::Primitive
);
};
}

/// Require that a [`Validity::Array`](crate::validity::Validity::Array) child matches `$M`. If validity is not array-backed
/// (e.g. `NonNullable` or `AllValid`), this is a no-op. If it is array-backed but does not
/// match `$M`, early-returns an [`ExecutionResult`] requesting execution of the validity slot.
///
/// Like [`require_opt_child!`], `$parent` is moved (not cloned) into the early-return path.
///
/// ```ignore
/// require_validity!(array, &array.validity, VALIDITY_SLOT => AnyCanonical);
/// ```
#[macro_export]
macro_rules! require_validity {
($parent:expr, $validity:expr, $idx:expr => $M:ty) => {
if let $crate::validity::Validity::Array(v) = $validity {
if !v.is::<$M>() {
return Ok($crate::ExecutionResult::execute_slot::<$M>($parent, $idx));
}
}
};
}

/// Extension trait for creating an execution context from a session.
pub trait VortexSessionExecute {
/// Create a new execution context from this session.
Expand Down
Loading