use std::fmt;
use std::iter::FromIterator;
use std::marker::PhantomData;
use std::ops::*;
use arrayfire as af;
use async_trait::async_trait;
use destream::{de, en};
use futures::{future, stream, Stream};
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use super::{dim4, Complex};
pub trait ArrayInstance: Deref<Target = af::Array<Self::DType>> + DerefMut {
type DType: af::HasAfEnum;
fn af_cast<T: af::HasAfEnum>(&self) -> af::Array<T> {
self.cast()
}
fn len(&self) -> usize {
self.elements()
}
fn get(&self, index: af::Indexer) -> af::Array<Self::DType> {
af::index_gen(self, index)
}
fn set<T: ArrayInstance<DType = Self::DType>>(&mut self, index: &af::Indexer, other: &T) {
af::assign_gen(self, index, other);
}
fn set_at(&mut self, offset: usize, value: Self::DType) {
let seq = af::Seq::new(offset as f32, offset as f32, 1.0f32);
af::assign_seq(self, &[seq], &af::Array::new(&[value], dim4(1)));
}
fn to_vec(&self) -> Vec<Self::DType>
where
Self::DType: Clone + Default,
{
let mut v = vec![Self::DType::default(); self.len()];
self.host(&mut v);
v
}
}
#[derive(Clone)]
pub struct ArrayExt<T: af::HasAfEnum>(af::Array<T>);
impl<T: af::HasAfEnum + Default> ArrayExt<T> {
pub fn constant(value: T, length: usize) -> Self
where
T: af::ConstGenerator<OutType = T>,
{
let dim = dim4(length);
Self(af::constant(value, dim))
}
pub fn concatenate(left: &Self, right: &Self) -> Self {
af::join(0, left, right).into()
}
pub fn exp(&self) -> ArrayExt<T::UnaryOutType> {
af::exp(self).into()
}
pub fn is_sorted(&self) -> bool
where
T: af::RealNumber + Clone,
{
let sorted = self.sorted(true);
af::all_true_all(&af::eq(self.deref(), sorted.deref(), false)).0
}
pub fn type_cast<D: af::HasAfEnum>(&self) -> ArrayExt<D> {
ArrayExt(self.af_cast())
}
pub fn get(&self, index: af::Indexer) -> Self {
Self(ArrayInstance::get(self, index))
}
pub fn get_value(&self, index: usize) -> T {
debug_assert!(index < self.elements());
let af_value = af::index(self, &[af::Seq::new(index as f64, index as f64, 1f64)]);
if af_value.elements() == 1 {
let mut value = vec![T::default()];
af_value.host(&mut value);
value.pop().unwrap()
} else {
panic!("no value at {}", index)
}
}
pub fn into_inner(self) -> af::Array<T> {
self.0
}
pub fn slice(&self, start: usize, end: usize) -> Self {
af::index(self, &[af::Seq::new(start as f32, (end - 1) as f32, 1.)]).into()
}
pub fn sort(&mut self, ascending: bool)
where
T: af::RealNumber,
{
*self = self.sorted(ascending)
}
pub fn sorted(&self, ascending: bool) -> Self
where
T: af::RealNumber,
{
debug_assert_eq!(self.0.dims(), dim4(self.len()));
Self(af::sort(&self.0, 0, ascending))
}
pub fn split(&self, at: usize) -> (Self, Self) {
let left = af::Seq::new(0.0, at as f32, 1.0);
let right = af::Seq::new(at as f32, self.len() as f32, 1.0);
(
ArrayExt(af::index(self, &[left, af::Seq::default()])),
ArrayExt(af::index(self, &[right, af::Seq::default()])),
)
}
pub fn unique(&self, sorted: bool) -> Self
where
T: af::RealNumber,
{
Self(af::set_unique(self, sorted))
}
fn into_stream(self) -> impl Stream<Item = Vec<T>>
where
T: Clone,
{
stream::once(future::ready(self.to_vec()))
}
fn to_stream(&self) -> impl Stream<Item = Vec<T>>
where
T: Clone,
{
stream::once(future::ready(self.to_vec()))
}
}
impl<T: af::HasAfEnum> ArrayInstance for ArrayExt<T> {
type DType = T;
}
impl<T: af::HasAfEnum> Deref for ArrayExt<T> {
type Target = af::Array<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: af::HasAfEnum> DerefMut for ArrayExt<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl ArrayExt<bool> {
pub fn not(&self) -> Self {
ArrayExt(!self.deref())
}
pub fn and(&self, other: &Self) -> Self {
ArrayExt(af::and(self, other, batch(self, other)))
}
pub fn or(&self, other: &Self) -> Self {
ArrayExt(af::or(self, other, batch(self, other)))
}
pub fn xor(&self, other: &Self) -> Self {
let batch = batch(self, other);
let one = af::or(self, other, batch);
let not_both = !(&af::and(self, other, batch));
let one_and_not_both = af::and(&one, ¬_both, batch);
ArrayExt(one_and_not_both)
}
}
impl ArrayExt<Complex<f32>> {
pub fn re(&self) -> ArrayExt<f32> {
af::real(&self.0).into()
}
pub fn im(&self) -> ArrayExt<f32> {
af::imag(&self.0).into()
}
}
impl ArrayExt<Complex<f64>> {
pub fn re(&self) -> ArrayExt<f64> {
af::real(&self.0).into()
}
pub fn im(&self) -> ArrayExt<f64> {
af::imag(&self.0).into()
}
}
impl ArrayExt<u64> {
pub fn range(start: u64, end: u64) -> Self {
let dims = dim4((end - start) as usize);
let tile = dim4(1);
let range: af::Array<u64> = af::iota(dims, tile).into();
if start == 0 {
range.into()
} else {
af::add(&range, &af::Array::new(&[start], dim4(1)), true).into()
}
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Add for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn add(self, other: Self) -> Self::Output {
ArrayExt(af::add(&self.0, &other.0, batch(&self, &other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Add for &ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn add(self, other: Self) -> Self::Output {
ArrayExt(af::add(&self.0, &other.0, batch(self, other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Mul for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn mul(self, other: Self) -> Self::Output {
ArrayExt(af::mul(&self.0, &other.0, batch(&self, &other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Mul for &ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn mul(self, other: Self) -> Self::Output {
ArrayExt(af::mul(&self.0, &other.0, batch(self, other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Div for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn div(self, other: Self) -> Self::Output {
ArrayExt(af::div(&self.0, &other.0, batch(&self, &other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Div for &ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn div(self, other: Self) -> Self::Output {
ArrayExt(af::div(&self.0, &other.0, batch(self, other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> DivAssign for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum
{
fn div_assign(&mut self, other: Self) {
let quotient = &*self / &other;
*self = quotient.type_cast();
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Sub for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn sub(self, other: Self) -> Self::Output {
ArrayExt(af::sub(&self.0, &other.0, batch(&self, &other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Sub for &ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn sub(self, other: Self) -> Self::Output {
ArrayExt(af::sub(&self.0, &other.0, batch(self, other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> SubAssign for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
fn sub_assign(&mut self, other: Self) {
let diff = &*self - &other;
*self = diff.type_cast();
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Rem for ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn rem(self, other: Self) -> Self::Output {
ArrayExt(af::modulo(&self.0, &other.0, batch(&self, &other)))
}
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T> + af::Convertable<OutType = T>> Rem for &ArrayExt<T>
where
<T as af::ImplicitPromote<T>>::Output: af::HasAfEnum + Default,
<T as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output: af::HasAfEnum, {
type Output = ArrayExt<<<T as af::Convertable>::OutType as af::ImplicitPromote<<T as af::Convertable>::OutType>>::Output>;
fn rem(self, other: Self) -> Self::Output {
ArrayExt(af::modulo(&self.0, &other.0, batch(self, other)))
}
}
impl From<(ArrayExt<f32>, ArrayExt<f32>)> for ArrayExt<Complex<f32>> {
fn from(elements: (ArrayExt<f32>, ArrayExt<f32>)) -> Self {
let (re, im) = elements;
Self(af::cplx2(&*re, &*im, false).cast())
}
}
impl From<(ArrayExt<f64>, ArrayExt<f64>)> for ArrayExt<Complex<f64>> {
fn from(elements: (ArrayExt<f64>, ArrayExt<f64>)) -> Self {
let (re, im) = elements;
Self(af::cplx2(&*re, &*im, false).cast())
}
}
impl<T: af::HasAfEnum> From<af::Array<T>> for ArrayExt<T> {
fn from(array: af::Array<T>) -> ArrayExt<T> {
ArrayExt(array)
}
}
impl<T: af::HasAfEnum> From<&[T]> for ArrayExt<T> {
fn from(values: &[T]) -> ArrayExt<T> {
let dim = dim4(values.len());
ArrayExt(af::Array::new(values, dim))
}
}
impl<T: af::HasAfEnum> From<Vec<T>> for ArrayExt<T> {
fn from(values: Vec<T>) -> ArrayExt<T> {
Self::from(&values[..])
}
}
impl<T: af::HasAfEnum> FromIterator<T> for ArrayExt<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let values = Vec::from_iter(iter);
let dim = dim4(values.len());
ArrayExt(af::Array::new(&values, dim))
}
}
pub trait ArrayInstanceAbs: ArrayInstance {
type AbsValue: af::HasAfEnum;
fn abs(&self) -> ArrayExt<Self::AbsValue>;
}
impl ArrayInstanceAbs for ArrayExt<Complex<f32>> {
type AbsValue = f32;
fn abs(&self) -> ArrayExt<f32> {
ArrayExt(af::abs(&*self))
}
}
impl ArrayInstanceAbs for ArrayExt<Complex<f64>> {
type AbsValue = f64;
fn abs(&self) -> ArrayExt<f64> {
ArrayExt(af::abs(&*self))
}
}
impl ArrayInstanceAbs for ArrayExt<f32> {
type AbsValue = f32;
fn abs(&self) -> ArrayExt<f32> {
ArrayExt(af::abs(&*self))
}
}
impl ArrayInstanceAbs for ArrayExt<f64> {
type AbsValue = f64;
fn abs(&self) -> ArrayExt<f64> {
ArrayExt(af::abs(&*self))
}
}
impl ArrayInstanceAbs for ArrayExt<i16> {
type AbsValue = i16;
fn abs(&self) -> ArrayExt<i16> {
ArrayExt(af::abs(&*self).cast())
}
}
impl ArrayInstanceAbs for ArrayExt<i32> {
type AbsValue = i32;
fn abs(&self) -> ArrayExt<i32> {
ArrayExt(af::abs(&*self).cast())
}
}
impl ArrayInstanceAbs for ArrayExt<i64> {
type AbsValue = i64;
fn abs(&self) -> ArrayExt<i64> {
ArrayExt(af::abs(&*self).cast())
}
}
pub trait ArrayInstanceAnyAll: ArrayInstance {
fn all(&self) -> bool {
af::all_true_all(&*self).0
}
fn any(&self) -> bool {
af::any_true_all(&*self).0
}
}
impl ArrayInstanceAnyAll for ArrayExt<bool> {}
impl ArrayInstanceAnyAll for ArrayExt<f32> {}
impl ArrayInstanceAnyAll for ArrayExt<f64> {}
impl ArrayInstanceAnyAll for ArrayExt<i16> {}
impl ArrayInstanceAnyAll for ArrayExt<i32> {}
impl ArrayInstanceAnyAll for ArrayExt<i64> {}
impl ArrayInstanceAnyAll for ArrayExt<u8> {}
impl ArrayInstanceAnyAll for ArrayExt<u16> {}
impl ArrayInstanceAnyAll for ArrayExt<u32> {}
impl ArrayInstanceAnyAll for ArrayExt<u64> {}
impl ArrayInstanceAnyAll for ArrayExt<Complex<f32>> {
fn all(&self) -> bool {
af::all_true_all(&af::abs(&*self)).0
}
fn any(&self) -> bool {
let any = af::any_true_all(&*self);
any.0 || any.1
}
}
impl ArrayInstanceAnyAll for ArrayExt<Complex<f64>> {
fn all(&self) -> bool {
af::all_true_all(&af::abs(&*self)).0
}
fn any(&self) -> bool {
let any = af::any_true_all(&*self);
any.0 || any.1
}
}
pub trait ArrayInstanceUnreal {
fn is_infinite(&self) -> ArrayExt<bool>;
fn is_nan(&self) -> ArrayExt<bool>;
}
impl<T: af::HasAfEnum + af::ImplicitPromote<T>> ArrayInstanceUnreal for ArrayExt<T> {
fn is_infinite(&self) -> ArrayExt<bool> {
af::isinf(&*self).into()
}
fn is_nan(&self) -> ArrayExt<bool> {
af::isnan(&*self).into()
}
}
pub trait ArrayInstanceCompare<U> {
fn eq(&self, other: &U) -> ArrayExt<bool>;
fn gt(&self, other: &U) -> ArrayExt<bool>;
fn gte(&self, other: &U) -> ArrayExt<bool>;
fn lt(&self, other: &U) -> ArrayExt<bool>;
fn lte(&self, other: &U) -> ArrayExt<bool>;
fn ne(&self, other: &U) -> ArrayExt<bool>;
}
impl<T, U> ArrayInstanceCompare<U> for ArrayExt<T>
where
T: Clone + af::HasAfEnum + af::Convertable<OutType = T>,
U: af::Convertable<OutType = T>,
<T as af::Convertable>::OutType: af::ImplicitPromote<<U as af::Convertable>::OutType>,
<U as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
{
fn eq(&self, other: &U) -> ArrayExt<bool> {
af::eq(self.deref(), other, true).into()
}
fn gt(&self, other: &U) -> ArrayExt<bool> {
af::gt(self.deref(), other, true).into()
}
fn gte(&self, other: &U) -> ArrayExt<bool> {
af::ge(self.deref(), other, true).into()
}
fn lt(&self, other: &U) -> ArrayExt<bool> {
af::lt(self.deref(), other, true).into()
}
fn lte(&self, other: &U) -> ArrayExt<bool> {
af::le(self.deref(), other, true).into()
}
fn ne(&self, other: &U) -> ArrayExt<bool> {
self.eq(other).not()
}
}
pub trait ArrayInstancePow<U>: ArrayInstance {
type Pow: af::HasAfEnum;
fn pow(&self, other: &U) -> ArrayExt<Self::Pow>;
}
impl<T, U> ArrayInstancePow<U> for ArrayExt<T>
where
T: af::HasAfEnum + af::Convertable<OutType = T>,
U: af::Convertable<OutType = T>,
<T as af::Convertable>::OutType: af::ImplicitPromote<T> + af::ImplicitPromote<<U as af::Convertable>::OutType>,
<U as af::Convertable>::OutType: af::ImplicitPromote<<T as af::Convertable>::OutType>,
<<T as af::Convertable>::OutType as af::ImplicitPromote<<U as af::Convertable>::OutType>>::Output: af::HasAfEnum,
{
type Pow = <<T as af::Convertable>::OutType as af::ImplicitPromote<<U as af::Convertable>::OutType>>::Output;
fn pow(&self, other: &U) -> ArrayExt<Self::Pow> {
ArrayExt(af::pow(self.deref(), other, true))
}
}
pub trait ArrayInstanceReduce: ArrayInstance {
type Product: af::HasAfEnum;
type Sum: af::HasAfEnum;
fn product(&self) -> Self::Product;
fn sum(&self) -> Self::Sum;
}
impl ArrayInstanceReduce for ArrayExt<bool> {
type Product = u64;
type Sum = u64;
fn product(&self) -> u64 {
af::product_all(self).0 as u64
}
fn sum(&self) -> u64 {
af::sum_all(self).0 as u64
}
}
impl ArrayInstanceReduce for ArrayExt<Complex<f32>> {
type Product = Complex<f32>;
type Sum = Complex<f32>;
fn product(&self) -> Self::Product {
let product = af::product_all(self);
Complex::new(product.0, product.1)
}
fn sum(&self) -> Self::Sum {
let sum = af::sum_all(self);
Complex::new(sum.0, sum.1)
}
}
impl ArrayInstanceReduce for ArrayExt<Complex<f64>> {
type Product = Complex<f64>;
type Sum = Complex<f64>;
fn product(&self) -> Self::Product {
let product = af::product_all(self);
Complex::new(product.0, product.1)
}
fn sum(&self) -> Self::Sum {
let sum = af::sum_all(self);
Complex::new(sum.0, sum.1)
}
}
impl ArrayInstanceReduce for ArrayExt<f32> {
type Product = f32;
type Sum = f32;
fn product(&self) -> f32 {
af::product_all(self).0
}
fn sum(&self) -> f32 {
af::sum_all(self).0
}
}
impl ArrayInstanceReduce for ArrayExt<f64> {
type Product = f64;
type Sum = f64;
fn product(&self) -> f64 {
af::product_all(self).0
}
fn sum(&self) -> f64 {
af::sum_all(self).0
}
}
impl ArrayInstanceReduce for ArrayExt<i16> {
type Product = i64;
type Sum = i64;
fn product(&self) -> i64 {
af::product_all(self).0 as i64
}
fn sum(&self) -> i64 {
af::sum_all(self).0 as i64
}
}
impl ArrayInstanceReduce for ArrayExt<i32> {
type Product = i64;
type Sum = i64;
fn product(&self) -> i64 {
af::product_all(self).0 as i64
}
fn sum(&self) -> i64 {
af::sum_all(self).0 as i64
}
}
impl ArrayInstanceReduce for ArrayExt<i64> {
type Product = i64;
type Sum = i64;
fn product(&self) -> i64 {
af::product_all(self).0 as i64
}
fn sum(&self) -> i64 {
af::sum_all(self).0 as i64
}
}
impl ArrayInstanceReduce for ArrayExt<u8> {
type Product = u64;
type Sum = u64;
fn product(&self) -> u64 {
af::product_all(self).0 as u64
}
fn sum(&self) -> u64 {
af::sum_all(self).0 as u64
}
}
impl ArrayInstanceReduce for ArrayExt<u16> {
type Product = u64;
type Sum = u64;
fn product(&self) -> u64 {
af::product_all(self).0 as u64
}
fn sum(&self) -> u64 {
af::sum_all(self).0 as u64
}
}
impl ArrayInstanceReduce for ArrayExt<u32> {
type Product = u64;
type Sum = u64;
fn product(&self) -> u64 {
af::product_all(self).0 as u64
}
fn sum(&self) -> u64 {
af::sum_all(self).0 as u64
}
}
impl ArrayInstanceReduce for ArrayExt<u64> {
type Product = u64;
type Sum = u64;
fn product(&self) -> u64 {
af::product_all(self).0 as u64
}
fn sum(&self) -> u64 {
af::sum_all(self).0 as u64
}
}
impl<'de, T: af::HasAfEnum + Deserialize<'de> + 'de> Deserialize<'de> for ArrayExt<T>
where
ArrayExt<T>: From<Vec<T>>,
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Vec::<T>::deserialize(deserializer).map(ArrayExt::from)
}
}
impl<T: af::HasAfEnum + Clone + Default + Serialize> Serialize for ArrayExt<T> {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
self.to_vec().serialize(s)
}
}
#[async_trait]
impl de::FromStream for ArrayExt<bool> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_bool(ArrayExtVisitor::<bool>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<f32> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_f32(ArrayExtVisitor::<f32>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<f64> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_f64(ArrayExtVisitor::<f64>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<u8> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_u8(ArrayExtVisitor::<u8>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<u16> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_u16(ArrayExtVisitor::<u16>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<u32> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_u32(ArrayExtVisitor::<u32>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<u64> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_u64(ArrayExtVisitor::<u64>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<i16> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_i16(ArrayExtVisitor::<i16>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<i32> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_i32(ArrayExtVisitor::<i32>::default())
.await
}
}
#[async_trait]
impl de::FromStream for ArrayExt<i64> {
type Context = ();
async fn from_stream<D: de::Decoder>(_: (), decoder: &mut D) -> Result<Self, D::Error> {
decoder
.decode_array_i64(ArrayExtVisitor::<i64>::default())
.await
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<bool> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_bool(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<bool> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_bool(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<f32> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_f32(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<f32> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_f32(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<f64> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_f64(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<f64> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_f64(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<u8> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u8(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<u8> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u8(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<u16> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u16(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<u16> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u16(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<u32> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u32(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<u32> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u32(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<u64> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u64(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<u64> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_u64(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<i16> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_i16(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<i16> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_i16(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<i32> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_i32(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<i32> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_i32(self.to_stream())
}
}
impl<'en> en::IntoStream<'en> for ArrayExt<i64> {
fn into_stream<E: en::Encoder<'en>>(self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_i64(self.into_stream())
}
}
impl<'en> en::ToStream<'en> for ArrayExt<i64> {
fn to_stream<E: en::Encoder<'en>>(&'en self, encoder: E) -> Result<E::Ok, E::Error> {
encoder.encode_array_i64(self.to_stream())
}
}
impl<T: af::HasAfEnum + fmt::Display + Default + Clone> fmt::Debug for ArrayExt<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"ArrayExt<{}>({}): {}",
std::any::type_name::<T>(),
self.dims(),
self
)
}
}
impl<T: af::HasAfEnum + fmt::Display + Default + Clone> fmt::Display for ArrayExt<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let as_str: String = self
.to_vec()
.into_iter()
.map(|n| n.to_string())
.collect::<Vec<String>>()
.join(",");
write!(f, "[{}]", as_str)
}
}
#[derive(Default)]
struct ArrayExtVisitor<T> {
phantom: PhantomData<T>,
}
impl<'a, T: af::HasAfEnum + Clone + Copy + Default + Send + 'a> ArrayExtVisitor<T>
where
ArrayExt<T>: From<Vec<T>>,
{
async fn visit_array<A: de::ArrayAccess<T>>(mut access: A) -> Result<ArrayExt<T>, A::Error> {
let mut buf = [T::default(); 4096];
let mut elements = Vec::new();
loop {
let num = access.buffer(&mut buf).await?;
if num == 0 {
break;
} else {
elements.extend_from_slice(&buf[..num]);
}
}
Ok(ArrayExt::from(elements))
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<bool> {
type Value = ArrayExt<bool>;
fn expecting() -> &'static str {
"a boolean array"
}
async fn visit_array_bool<A: de::ArrayAccess<bool>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<f32> {
type Value = ArrayExt<f32>;
fn expecting() -> &'static str {
"a 32-bit float array"
}
async fn visit_array_f32<A: de::ArrayAccess<f32>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<f64> {
type Value = ArrayExt<f64>;
fn expecting() -> &'static str {
"a 64-bit float array"
}
async fn visit_array_f64<A: de::ArrayAccess<f64>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<u8> {
type Value = ArrayExt<u8>;
fn expecting() -> &'static str {
"an 8-bit unsigned integer array"
}
async fn visit_array_u8<A: de::ArrayAccess<u8>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<u16> {
type Value = ArrayExt<u16>;
fn expecting() -> &'static str {
"a 16-bit unsigned integer array"
}
async fn visit_array_u16<A: de::ArrayAccess<u16>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<u32> {
type Value = ArrayExt<u32>;
fn expecting() -> &'static str {
"a 32-bit unsigned integer array"
}
async fn visit_array_u32<A: de::ArrayAccess<u32>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<u64> {
type Value = ArrayExt<u64>;
fn expecting() -> &'static str {
"a 64-bit unsigned integer array"
}
async fn visit_array_u64<A: de::ArrayAccess<u64>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<i16> {
type Value = ArrayExt<i16>;
fn expecting() -> &'static str {
"a 16-bit integer array"
}
async fn visit_array_i16<A: de::ArrayAccess<i16>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<i32> {
type Value = ArrayExt<i32>;
fn expecting() -> &'static str {
"a 32-bit integer array"
}
async fn visit_array_i32<A: de::ArrayAccess<i32>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[async_trait]
impl de::Visitor for ArrayExtVisitor<i64> {
type Value = ArrayExt<i64>;
fn expecting() -> &'static str {
"a 64-bit integer array"
}
async fn visit_array_i64<A: de::ArrayAccess<i64>>(
self,
access: A,
) -> Result<Self::Value, A::Error> {
Self::visit_array(access).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_range() {
let range = ArrayExt::range(1, 10);
assert_eq!(range.to_vec(), (1..10).collect::<Vec<u64>>())
}
}
#[inline]
fn batch<T: af::HasAfEnum>(this: &ArrayExt<T>, that: &ArrayExt<T>) -> bool {
this.0.dims() != that.0.dims()
}