use std::mem::MaybeUninit;
use ndarray::{Array, Array1, ArrayBase, ArrayViewMut, AsArray, Dimension, ViewRepr, Zip};
use crate::prelude::*;
#[inline]
pub fn copy_into<'a, T, A, D>(
data_a: A,
mut data_b: ArrayViewMut<T, D>,
threads: Option<usize>,
) -> Result<(), ImgalError>
where
A: AsArray<'a, T, D>,
D: Dimension,
T: 'a + AsNumeric,
{
let data_a: ArrayBase<ViewRepr<&'a T>, D> = data_a.into();
if data_a.shape() != data_b.shape() {
return Err(ImgalError::MismatchedArrayShapes {
a_arr_name: "data_a",
a_shape: data_a.shape().to_vec(),
b_arr_name: "data_b",
b_shape: data_b.shape().to_vec(),
});
}
par!(threads,
seq_exp: data_b.assign(&data_a),
par_exp: Zip::from(data_a).and(data_b)
.par_for_each(|&a, b| *b = a));
Ok(())
}
#[inline]
pub fn copy_into_flat<'a, T, A, D>(data: A, threads: Option<usize>) -> Array1<T>
where
A: AsArray<'a, T, D>,
D: Dimension,
T: 'a + AsNumeric,
{
let data: ArrayBase<ViewRepr<&'a T>, D> = data.into();
let dl = data.len();
let shape = data.raw_dim();
if let Some(s) = data.as_slice() {
return Array1::from_vec(s.to_vec());
}
let seq_flat_cp = || {
let mut arr: Vec<T> = Vec::with_capacity(dl);
arr.extend(data.view().iter().copied());
Array1::from_vec(arr)
};
let par_flat_cp = || {
let mut arr: Vec<MaybeUninit<T>> = Vec::with_capacity(dl);
unsafe { arr.set_len(dl) };
let mut arr = Array1::from_vec(arr)
.into_shape_with_order(shape)
.expect("Failed to reshape flat array into input destination array shape.");
Zip::from(data.view()).and(&mut arr).par_for_each(|&v, d| {
d.write(v);
});
let arr = arr
.into_shape_with_order(dl)
.expect("Failed to reshape array into a flat 1D array.");
unsafe { arr.assume_init() }
};
par!(threads,seq_exp: seq_flat_cp(), par_exp: par_flat_cp())
}
#[inline]
pub fn duplicate<'a, T, A, D>(data: A, threads: Option<usize>) -> Array<T, D>
where
A: AsArray<'a, T, D>,
D: Dimension,
T: 'a + AsNumeric,
{
let data: ArrayBase<ViewRepr<&'a T>, D> = data.into();
let dup_par = || {
let mut dup: Array<T, D> = Array::from_elem(data.dim(), T::default());
Zip::from(data.view())
.and(dup.view_mut())
.par_for_each(|&v, d| {
*d = v;
});
dup
};
par!(threads,
seq_exp: data.to_owned(),
par_exp: dup_par())
}