manifold/tests/basic_tests.rs
Julius Koskela 84e5cb256a
🚀 Finish basic types and refactor (#17)
- Finished basic API's for types Tensor, TensorIndex, TensorShape, TensorError.
- Make Axis a simple wrapper type used only for clarity.
- Add documentation and doctests.

Reviewed-on: #17
Co-authored-by: Julius Koskela <julius.koskela@unikie.com>
Co-committed-by: Julius Koskela <julius.koskela@unikie.com>
2024-01-06 00:11:30 +00:00

258 lines
7.3 KiB
Rust

use manifold::*;
use serde_json;
#[test]
fn test_serde_shape_serialization() {
// Create a shape instance
let shape: TensorShape<3> = [1, 2, 3].into();
// Serialize the shape to a JSON string
let serialized =
serde_json::to_string(&shape).expect("Failed to serialize");
// Deserialize the JSON string back into a shape
let deserialized: TensorShape<3> =
serde_json::from_str(&serialized).expect("Failed to deserialize");
// Check that the deserialized shape is equal to the original
assert_eq!(shape, deserialized);
}
#[test]
fn test_tensor_serde_serialization() {
// Create an instance of Tensor
let tensor: Tensor<i32, 2> = Tensor::new(TensorShape::new([2, 2]));
// Serialize the Tensor to a JSON string
let serialized =
serde_json::to_string(&tensor).expect("Failed to serialize");
// Deserialize the JSON string back into a Tensor
let deserialized: Tensor<i32, 2> =
serde_json::from_str(&serialized).expect("Failed to deserialize");
// Check that the deserialized Tensor is equal to the original
assert_eq!(tensor.buffer(), deserialized.buffer());
assert_eq!(tensor.shape(), deserialized.shape());
}
#[test]
fn test_iterating_3d_tensor() {
let shape = TensorShape::new([2, 2, 2]); // 3D tensor with shape 2x2x2
let mut tensor = Tensor::new(shape);
let mut num = 0;
// Fill the tensor with sequential numbers
for i in 0..2 {
for j in 0..2 {
for k in 0..2 {
tensor.buffer_mut()[i * 4 + j * 2 + k] = num;
num += 1;
}
}
}
// Iterate over the tensor and check that the numbers are correct
let mut iter = TensorIterator::new(&tensor);
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), Some(&5));
assert_eq!(iter.next(), Some(&6));
assert_eq!(iter.next(), Some(&7));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
}
#[test]
fn test_iterating_rank_4_tensor() {
// Define the shape of the rank-4 tensor (e.g., 2x2x2x2)
let shape = TensorShape::new([2, 2, 2, 2]);
let mut tensor = Tensor::new(shape);
let mut num = 0;
// Fill the tensor with sequential numbers
for i in 0..tensor.len() {
tensor.buffer_mut()[i] = num;
num += 1;
}
// Iterate over the tensor and check that the numbers are correct
let mut iter = TensorIterator::new(&tensor);
for expected_value in 0..tensor.len() {
assert_eq!(*iter.next().unwrap(), expected_value);
}
// Ensure the iterator is exhausted
assert!(iter.next().is_none());
}
#[test]
fn test_index_dec_method() {
let shape = TensorShape::new([3, 3, 3]); // Example shape for a 3x3x3 tensor
let mut index = TensorIndex::zero(shape);
// Increment the index to the maximum
for _ in 0..26 {
// 3 * 3 * 3 - 1 = 26 increments to reach the end
index.inc();
}
// Check if the index is at the maximum
assert_eq!(index, TensorIndex::new(shape, [2, 2, 2]));
// Decrement step by step and check the index
let expected_indices = [
[2, 2, 2],
[2, 2, 1],
[2, 2, 0],
[2, 1, 2],
[2, 1, 1],
[2, 1, 0],
[2, 0, 2],
[2, 0, 1],
[2, 0, 0],
[1, 2, 2],
[1, 2, 1],
[1, 2, 0],
[1, 1, 2],
[1, 1, 1],
[1, 1, 0],
[1, 0, 2],
[1, 0, 1],
[1, 0, 0],
[0, 2, 2],
[0, 2, 1],
[0, 2, 0],
[0, 1, 2],
[0, 1, 1],
[0, 1, 0],
[0, 0, 2],
[0, 0, 1],
[0, 0, 0],
];
for (i, &expected) in expected_indices.iter().enumerate() {
assert_eq!(
index,
TensorIndex::new(shape, expected),
"Failed at index {}",
i
);
index.dec();
}
// Finally, the index should reach [0, 0, 0]
index.dec();
assert_eq!(index, TensorIndex::zero(shape));
}
// #[test]
// fn test_axis_iterator() {
// // Creating a 2x2 Tensor for testing
// let tensor = Tensor::from([[1.0, 2.0], [3.0, 4.0]]);
// // Testing iteration over the first axis (axis = 0)
// let axis = TensorAxis::new(&tensor, 0);
// let mut axis_iter = axis.into_iter();
// assert_eq!(axis_iter.next(), Some(&1.0));
// assert_eq!(axis_iter.next(), Some(&2.0));
// assert_eq!(axis_iter.next(), Some(&3.0));
// assert_eq!(axis_iter.next(), Some(&4.0));
// // Resetting the iterator for the second axis (axis = 1)
// let axis = TensorAxis::new(&tensor, 1);
// let mut axis_iter = axis.into_iter();
// assert_eq!(axis_iter.next(), Some(&1.0));
// assert_eq!(axis_iter.next(), Some(&3.0));
// assert_eq!(axis_iter.next(), Some(&2.0));
// assert_eq!(axis_iter.next(), Some(&4.0));
// let shape = tensor.shape();
// let mut a: TensorIndex<2> = (shape.clone(), [0, 0]).into();
// let b: TensorIndex<2> = (shape.clone(), [1, 1]).into();
// while a <= b {
// println!("a: {}", a);
// a.inc();
// }
// }
// #[test]
// fn test_3d_tensor_axis_iteration() {
// // Create a 3D Tensor with specific values
// // Tensor shape is 2x2x2 for simplicity
// let t = Tensor::from([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
// // TensorAxis 0 (Layer-wise):
// //
// // t[0][0][0] = 1
// // t[0][0][1] = 2
// // t[0][1][0] = 3
// // t[0][1][1] = 4
// // t[1][0][0] = 5
// // t[1][0][1] = 6
// // t[1][1][0] = 7
// // t[1][1][1] = 8
// // [1, 2, 3, 4, 5, 6, 7, 8]
// //
// // This order suggests that for each "layer" (first level of arrays),
// // the iterator goes through all rows and columns. It first completes
// // the entire first layer, then moves to the second.
// let a0 = TensorAxis::new(&t, 0);
// let a0_order = a0.into_iter().cloned().collect::<Vec<_>>();
// assert_eq!(a0_order, [1, 2, 3, 4, 5, 6, 7, 8]);
// // TensorAxis 1 (Row-wise within each layer):
// //
// // t[0][0][0] = 1
// // t[0][0][1] = 2
// // t[1][0][0] = 5
// // t[1][0][1] = 6
// // t[0][1][0] = 3
// // t[0][1][1] = 4
// // t[1][1][0] = 7
// // t[1][1][1] = 8
// // [1, 2, 5, 6, 3, 4, 7, 8]
// //
// // This indicates that within each "layer", the iterator first
// // completes the first row across all layers, then the second row
// // across all layers.
// let a1 = TensorAxis::new(&t, 1);
// let a1_order = a1.into_iter().cloned().collect::<Vec<_>>();
// assert_eq!(a1_order, [1, 2, 5, 6, 3, 4, 7, 8]);
// // TensorAxis 2 (Column-wise within each layer):
// //
// // t[0][0][0] = 1
// // t[0][1][0] = 3
// // t[1][0][0] = 5
// // t[1][1][0] = 7
// // t[0][0][1] = 2
// // t[0][1][1] = 4
// // t[1][0][1] = 6
// // t[1][1][1] = 8
// // [1, 3, 5, 7, 2, 4, 6, 8]
// //
// // This indicates that within each "layer", the iterator first
// // completes the first column across all layers, then the second
// // column across all layers.
// let a2 = TensorAxis::new(&t, 2);
// let a2_order = a2.into_iter().cloned().collect::<Vec<_>>();
// assert_eq!(a2_order, [1, 3, 5, 7, 2, 4, 6, 8]);
// }