pub mod backward;
#[cfg(feature = "benchmarks")]
pub mod bench_catalog;
pub mod forward;
use cubecl::{
client::Client,
ir::{ElemType, IntKind},
std::tensor::TensorHandle,
};
use cubek_pool::definition::PoolError;
use cubek_test_utils::{
ExecutionOutcome, HostData, HostDataType, TestInput, TestOutcome, ValidationResult,
assert_equals_approx,
};
pub fn build_output_tensor(
client: &Client,
output_shape: Vec<usize>,
dtype: ElemType,
) -> TensorHandle {
TestInput::builder(client.clone(), output_shape)
.dtype(dtype)
.zeros()
.generate_without_host_data()
}
pub fn output_host_f32(client: &Client, output: TensorHandle) -> HostData {
HostData::from_tensor_handle(client, output, HostDataType::F32)
}
pub fn output_host_i32(client: &Client, output: TensorHandle) -> HostData {
HostData::from_tensor_handle(client, output, HostDataType::I32)
}
pub fn indices_elem_type() -> ElemType {
ElemType::Int(IntKind::I32)
}
pub fn validate_test(
result: Result<(), PoolError>,
actual: HostData,
expected: HostData,
tolerance: f32,
) {
let outcome = match ExecutionOutcome::from(result) {
ExecutionOutcome::Executed => {
assert_equals_approx(&actual, &expected, tolerance).as_test_outcome()
}
ExecutionOutcome::CompileError(e) => TestOutcome::CompileError(e),
};
outcome.enforce();
}
pub fn validate_indices(actual: HostData, expected: HostData) {
if actual.shape != expected.shape {
ValidationResult::Fail(format!(
"Indices shape mismatch: got {:?}, expected {:?}",
actual.shape, expected.shape,
))
.as_test_outcome()
.enforce();
return;
}
let mut mismatches: Vec<(Vec<usize>, i32, i32)> = Vec::new();
let mut total = 0usize;
let mut mismatched = 0usize;
for idx in actual.iter_indices() {
total += 1;
let got = actual.get_i32(&idx);
let exp = expected.get_i32(&idx);
if got != exp {
mismatched += 1;
if mismatches.len() < 8 {
mismatches.push((idx, got, exp));
}
}
}
if mismatched == 0 {
ValidationResult::Pass.as_test_outcome().enforce();
return;
}
let mut message = format!(
"Indices mismatch: {}/{} elements mismatched",
mismatched, total
);
if !mismatches.is_empty() {
message.push_str("\nFirst mismatches:");
for (idx, got, exp) in mismatches {
message.push_str(&format!("\n {:?}: got {}, expected {}", idx, got, exp));
}
}
ValidationResult::Fail(message).as_test_outcome().enforce();
}