use torsh_core::error::Result;
use torsh_tensor::Tensor;
#[test]
fn test_scoped_slice_access_immutable() -> Result<()> {
let tensor = Tensor::from_vec(vec![1.0f32, 2.0, 3.0, 4.0], &[4])?;
let sum = tensor.with_data_slice(|data| {
Ok(data.iter().sum::<f32>())
})?;
assert_eq!(sum, 10.0);
Ok(())
}
#[test]
fn test_scoped_slice_access_mutable() -> Result<()> {
let tensor = Tensor::from_vec(vec![1.0f32, 2.0, 3.0, 4.0], &[4])?;
tensor.with_data_slice_mut(|data| {
for elem in data.iter_mut() {
*elem *= 2.0;
}
Ok(())
})?;
assert_eq!(tensor.to_vec()?, vec![2.0, 4.0, 6.0, 8.0]);
Ok(())
}
#[test]
fn test_nested_zero_copy_operations() -> Result<()> {
let tensor_a = Tensor::from_vec(vec![1.0f32, 2.0, 3.0, 4.0], &[4])?;
let tensor_b = Tensor::from_vec(vec![5.0f32, 6.0, 7.0, 8.0], &[4])?;
let result: Vec<f32> = tensor_a.with_data_slice(|data_a| {
tensor_b.with_data_slice(|data_b| {
let result: Vec<f32> = data_a
.iter()
.zip(data_b.iter())
.map(|(a, b)| a + b)
.collect();
Ok(result)
})
})?;
assert_eq!(result, vec![6.0, 8.0, 10.0, 12.0]);
Ok(())
}
#[test]
fn test_zero_copy_dot_product() -> Result<()> {
let tensor_a = Tensor::from_vec(vec![1.0f32, 2.0, 3.0, 4.0], &[4])?;
let tensor_b = Tensor::from_vec(vec![5.0f32, 6.0, 7.0, 8.0], &[4])?;
let dot_product = tensor_a.with_data_slice(|data_a| {
tensor_b.with_data_slice(|data_b| {
let result = data_a
.iter()
.zip(data_b.iter())
.map(|(a, b)| a * b)
.sum::<f32>();
Ok(result)
})
})?;
assert_eq!(dot_product, 70.0);
Ok(())
}
#[test]
fn test_zero_copy_in_place_addition() -> Result<()> {
let tensor = Tensor::from_vec(vec![1.0f32, 2.0, 3.0, 4.0], &[4])?;
let other = Tensor::from_vec(vec![10.0f32, 20.0, 30.0, 40.0], &[4])?;
tensor.with_data_slice_mut(|data| {
other.with_data_slice(|other_data| {
for (x, y) in data.iter_mut().zip(other_data.iter()) {
*x += y;
}
Ok(())
})
})?;
assert_eq!(tensor.to_vec()?, vec![11.0, 22.0, 33.0, 44.0]);
Ok(())
}
#[test]
fn test_zero_copy_normalization() -> Result<()> {
let tensor = Tensor::from_vec(vec![1.0f32, 2.0, 3.0, 4.0], &[4])?;
let norm = tensor.with_data_slice(|data| {
let sum_of_squares = data.iter().map(|&x| x * x).sum::<f32>();
Ok(sum_of_squares.sqrt())
})?;
tensor.with_data_slice_mut(|data| {
for elem in data.iter_mut() {
*elem /= norm;
}
Ok(())
})?;
let normalized_norm = tensor.with_data_slice(|data| {
let sum_of_squares = data.iter().map(|&x| x * x).sum::<f32>();
Ok(sum_of_squares.sqrt())
})?;
assert!((normalized_norm - 1.0).abs() < 1e-6);
Ok(())
}
#[cfg(feature = "simd")]
#[test]
fn test_zero_copy_simd_ready() -> Result<()> {
use scirs2_core::simd_ops::SimdUnifiedOps;
let tensor_a = Tensor::from_vec(vec![1.0f32; 1000], &[1000])?;
let tensor_b = Tensor::from_vec(vec![2.0f32; 1000], &[1000])?;
let result: Vec<f32> = tensor_a.with_data_slice(|data_a| {
tensor_b.with_data_slice(|data_b| {
use scirs2_core::ndarray::ArrayView1;
let view_a = ArrayView1::from(data_a);
let view_b = ArrayView1::from(data_b);
let result_arr = f32::simd_add(&view_a, &view_b);
Ok(result_arr.to_vec())
})
})?;
assert_eq!(result.len(), 1000);
for &val in &result {
assert_eq!(val, 3.0);
}
Ok(())
}
#[test]
fn test_tensor_view_api() -> Result<()> {
use torsh_core::shape::Shape;
use torsh_tensor::TensorView;
let data = vec![1.0f32, 2.0, 3.0, 4.0];
let shape = Shape::new(vec![2, 2]);
let strides = vec![2, 1];
let view = TensorView::new(&data, shape, strides, 0);
assert_eq!(view.len(), 4);
assert!(view.is_contiguous());
assert_eq!(*view.get(0)?, 1.0);
assert_eq!(*view.get_at(&[0, 0])?, 1.0);
assert_eq!(*view.get_at(&[1, 1])?, 4.0);
Ok(())
}
#[test]
fn test_performance_comparison_documentation() {
assert!(true, "Performance improvement documentation");
}