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
25 changes: 8 additions & 17 deletions fuzz/src/gpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ use vortex_array::IntoArray;
use vortex_array::arrays::ArbitraryDictArray;
use vortex_dtype::Nullability;
use vortex_dtype::PType;
use vortex_error::vortex_err;

use crate::SESSION;
use crate::error::Backtrace;
use crate::error::VortexFuzzError;
use crate::error::VortexFuzzResult;
Expand Down Expand Up @@ -93,58 +95,49 @@ fn arbitrary_gpu_primitive_dtype(u: &mut Unstructured) -> Result<vortex_dtype::D
/// - `Err(_)` - a bug was found
#[allow(clippy::result_large_err)]
pub async fn run_compress_gpu(fuzz: FuzzCompressGpu) -> VortexFuzzResult<bool> {
use vortex::VortexSessionDefault;
use vortex::session::VortexSession;
use vortex_cuda::CanonicalCudaExt;
use vortex_cuda::CudaSession;
use vortex_cuda::executor::CudaArrayExt;
use vortex_error::VortexExpect;

// Runtime check - skip if CUDA is not available
if !vortex_cuda::cuda_available() {
return Ok(false);
return Err(VortexFuzzError::VortexError(
vortex_err!("no cuda device to run the fuzzer on"),
Backtrace::capture(),
));
}

let FuzzCompressGpu { array } = fuzz;

// Store original properties for error reporting
let original_len = array.len();

// 1. CPU decompression (reference)
let cpu_canonical = match array.to_canonical() {
Ok(c) => c,
Err(e) => {
return Err(VortexFuzzError::VortexError(e, Backtrace::capture()));
}
};

// 2. Create CUDA execution context
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥲

let session = VortexSession::default();

let mut cuda_ctx =
CudaSession::create_execution_ctx(&session).vortex_expect("cannot create session");
CudaSession::create_execution_ctx(&SESSION).vortex_expect("cannot create session");

// 3. GPU decompression
let gpu_canonical = match array.clone().execute_cuda(&mut cuda_ctx).await {
Ok(c) => c,
Err(e) => {
return Err(VortexFuzzError::VortexError(e, Backtrace::capture()));
}
};

// 4. Copy GPU result back to host using CanonicalCudaExt
let gpu_host_canonical = match gpu_canonical.to_host().await {
let gpu_host_canonical = match gpu_canonical.into_host().await {
Ok(c) => c,
Err(e) => {
return Err(VortexFuzzError::VortexError(e, Backtrace::capture()));
}
};

// 5. Compare canonicals
let cpu_array = cpu_canonical.into_array();
let gpu_array = gpu_host_canonical.into_array();

// Verify dtype is preserved
if cpu_array.dtype() != gpu_array.dtype() {
return Err(VortexFuzzError::DTypeMismatch(
cpu_array,
Expand All @@ -154,7 +147,6 @@ pub async fn run_compress_gpu(fuzz: FuzzCompressGpu) -> VortexFuzzResult<bool> {
));
}

// Verify length is preserved
if original_len != gpu_array.len() {
return Err(VortexFuzzError::LengthMismatch(
original_len,
Expand All @@ -166,7 +158,6 @@ pub async fn run_compress_gpu(fuzz: FuzzCompressGpu) -> VortexFuzzResult<bool> {
));
}

// Compare element by element
for i in 0..original_len {
let cpu_scalar = cpu_array
.scalar_at(i)
Expand Down
1 change: 1 addition & 0 deletions vortex-array/src/arrays/primitive/compute/take/avx2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl TakeImpl for TakeKernelAVX2 {
/// The caller must ensure that if the validity has a length, it is the same length as the indices,
/// and that the `avx2` feature is enabled.
#[target_feature(enable = "avx2")]
#[allow(unused)]
unsafe fn take_primitive_avx2<V, I>(
values: &[V],
indices: &[I],
Expand Down
4 changes: 2 additions & 2 deletions vortex-cuda/src/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ use vortex_error::VortexResult;
/// Move all canonical data from to_host from device.
#[async_trait]
pub trait CanonicalCudaExt {
async fn to_host(self) -> VortexResult<Self>
async fn into_host(self) -> VortexResult<Self>
where
Self: Sized;
}

#[async_trait]
impl CanonicalCudaExt for Canonical {
async fn to_host(self) -> VortexResult<Self> {
async fn into_host(self) -> VortexResult<Self> {
match self {
n @ Canonical::Null(_) => Ok(n),
Canonical::Bool(bool) => {
Expand Down
2 changes: 1 addition & 1 deletion vortex-cuda/src/kernel/encodings/alp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ mod tests {
.execute(alp_array.to_array(), &mut cuda_ctx)
.await
.vortex_expect("GPU decompression failed")
.to_host()
.into_host()
.await?
.into_array();

Expand Down
2 changes: 1 addition & 1 deletion vortex-cuda/src/kernel/encodings/for_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ mod tests {
.execute(for_array.to_array(), &mut cuda_ctx)
.await
.vortex_expect("GPU decompression failed")
.to_host()
.into_host()
.await?
.into_array();

Expand Down
2 changes: 1 addition & 1 deletion vortex-cuda/src/kernel/encodings/zigzag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ mod tests {
.execute(zigzag_array.to_array(), &mut cuda_ctx)
.await
.vortex_expect("GPU decompression failed")
.to_host()
.into_host()
.await?
.into_array();

Expand Down
Loading