blas_array2/blas1/
asum.rs1use crate::ffi::{self, blas_int};
2use crate::util::*;
3use derive_builder::Builder;
4use ndarray::prelude::*;
5use num_traits::Zero;
6
7pub trait ASUMNum: BLASFloat {
10 unsafe fn asum(n: *const blas_int, x: *const Self, incx: *const blas_int) -> Self::RealFloat;
11}
12
13macro_rules! impl_func {
14 ($type: ty, $func: ident) => {
15 impl ASUMNum for $type {
16 unsafe fn asum(
17 n: *const blas_int,
18 x: *const Self,
19 incx: *const blas_int,
20 ) -> <$type as BLASFloat>::RealFloat {
21 ffi::$func(n, x, incx)
22 }
23 }
24 };
25}
26
27impl_func!(f32, sasum_);
28impl_func!(f64, dasum_);
29impl_func!(c32, scasum_);
30impl_func!(c64, dzasum_);
31
32pub struct ASUM_Driver<'x, F>
37where
38 F: ASUMNum,
39{
40 n: blas_int,
41 x: ArrayView1<'x, F>,
42 incx: blas_int,
43}
44
45impl<'x, F> ASUM_Driver<'x, F>
46where
47 F: ASUMNum,
48{
49 pub fn run_blas(self) -> Result<F::RealFloat, BLASError> {
50 let Self { n, x, incx } = self;
51 let x_ptr = x.as_ptr();
52 if n == 0 {
53 return Ok(F::RealFloat::zero());
54 } else {
55 return unsafe { Ok(F::asum(&n, x_ptr, &incx)) };
56 }
57 }
58}
59
60#[derive(Builder)]
65#[builder(pattern = "owned", build_fn(error = "BLASError"), no_std)]
66pub struct ASUM_<'x, F>
67where
68 F: ASUMNum,
69{
70 pub x: ArrayView1<'x, F>,
71}
72
73impl<'x, F> ASUM_<'x, F>
74where
75 F: ASUMNum,
76{
77 pub fn driver(self) -> Result<ASUM_Driver<'x, F>, BLASError> {
78 let Self { x } = self;
79 let incx = x.stride_of(Axis(0));
80 let n = x.len_of(Axis(0));
81 let driver = ASUM_Driver { n: n.try_into()?, x, incx: incx.try_into()? };
82 return Ok(driver);
83 }
84}
85
86pub type ASUM<'x, F> = ASUM_Builder<'x, F>;
89pub type SASUM<'x> = ASUM<'x, f32>;
90pub type DASUM<'x> = ASUM<'x, f64>;
91pub type SCASUM<'x> = ASUM<'x, c32>;
92pub type DZASUM<'x> = ASUM<'x, c64>;
93
94impl<'x, F> ASUM<'x, F>
95where
96 F: ASUMNum,
97{
98 pub fn run(self) -> Result<F::RealFloat, BLASError> {
99 self.build()?.driver()?.run_blas()
100 }
101}
102
103