use num_complex::Complex64;
use tenferro_cpu::CpuBackend;
use tenferro_tensor::backend::BackendSessionHost;
use tenferro_tensor::{DotGeneralConfig, Tensor, TensorRead};
fn matrix(rows: usize, columns: usize, seed: f64) -> Tensor {
let data: Vec<Complex64> = (0..rows * columns)
.map(|i| Complex64::new(seed + 0.5 * i as f64, 1.0 - 0.125 * i as f64))
.collect();
Tensor::from_vec_col_major(vec![rows, columns], data).unwrap()
}
#[test]
fn blas1_scalars_do_not_overwrite_live_session_results() {
let mut backend = CpuBackend::new();
let lhs = matrix(8, 6, 0.25);
let rhs = matrix(6, 4, -1.5);
let config = DotGeneralConfig {
lhs_contracting_dims: vec![1],
rhs_contracting_dims: vec![0],
lhs_batch_dims: vec![],
rhs_batch_dims: vec![],
};
let mut live: Vec<Tensor> = Vec::new();
for _ in 0..4 {
let product = backend
.with_backend_session(|session| {
session.dot_general_read(
TensorRead::from_tensor(&lhs),
TensorRead::from_tensor(&rhs),
&config,
)
})
.unwrap();
live.push(product);
}
let expected: Vec<Vec<Complex64>> = live
.iter()
.map(|tensor| tensor.as_slice::<Complex64>().unwrap().to_vec())
.collect();
let operand = matrix(16, 1, 0.75);
for _ in 0..8 {
let _dot = backend
.with_backend_session(|session| {
session.vdot_read(
TensorRead::from_tensor(&operand),
TensorRead::from_tensor(&operand),
)
})
.unwrap();
let _norm = backend
.with_backend_session(|session| {
session.norm_squared_read(TensorRead::from_tensor(&operand))
})
.unwrap();
}
for (index, (tensor, expected)) in live.iter().zip(&expected).enumerate() {
let actual = tensor.as_slice::<Complex64>().unwrap();
assert_eq!(
actual,
expected.as_slice(),
"contraction result {index} changed while only BLAS1 scalars ran"
);
}
}