blas_array2/blas1/
asum.rs

1use crate::ffi::{self, blas_int};
2use crate::util::*;
3use derive_builder::Builder;
4use ndarray::prelude::*;
5use num_traits::Zero;
6
7/* #region BLAS func */
8
9pub 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
32/* #endregion */
33
34/* #region BLAS driver */
35
36pub 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/* #endregion */
61
62/* #region BLAS builder */
63
64#[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
86/* #region BLAS wrapper */
87
88pub 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/* #endregion */