singe-npp 0.1.0-alpha.8

Safe Rust wrappers for NVIDIA Performance Primitives library (NPP).
Documentation
use singe_cuda::types::{Complex32, Complex64};
use singe_npp_sys as sys;

use crate::{
    context::StreamContext,
    error::Result,
    signal::view::{SignalView, SignalViewMut},
    try_ffi,
    types::{ComplexI16, ComplexI32, ComplexI64, DataTypeLike, IntoNpp},
    utility::{to_u64, validate_same_len},
};

macro_rules! impl_set {
    ($name:ident, $ty:ty, $ffi:ident) => {
        pub fn $name(
            stream_context: &StreamContext,
            value: $ty,
            destination: &mut SignalViewMut<'_, $ty>,
        ) -> Result<()> {
            unsafe {
                try_ffi!(sys::$ffi(
                    value.into_npp(),
                    destination.as_mut_ptr().cast(),
                    to_u64(destination.len(), "len")?,
                    stream_context.as_raw(),
                ))?;
            }
            Ok(())
        }
    };
}

macro_rules! impl_zero {
    ($name:ident, $ty:ty, $ffi:ident) => {
        pub fn $name(
            stream_context: &StreamContext,
            destination: &mut SignalViewMut<'_, $ty>,
        ) -> Result<()> {
            unsafe {
                try_ffi!(sys::$ffi(
                    destination.as_mut_ptr().cast(),
                    to_u64(destination.len(), "len")?,
                    stream_context.as_raw(),
                ))?;
            }
            Ok(())
        }
    };
}

macro_rules! impl_copy {
    ($name:ident, $ty:ty, $ffi:ident) => {
        pub fn $name(
            stream_context: &StreamContext,
            source: &SignalView<'_, $ty>,
            destination: &mut SignalViewMut<'_, $ty>,
        ) -> Result<()> {
            validate_same_len(source.len(), destination.len(), "destination")?;

            unsafe {
                try_ffi!(sys::$ffi(
                    source.as_ptr().cast(),
                    destination.as_mut_ptr().cast(),
                    to_u64(source.len(), "len")?,
                    stream_context.as_raw(),
                ))?;
            }
            Ok(())
        }
    };
}

impl_set!(set_u8, u8, nppsSet_8u_Ctx);
impl_set!(set_i8, i8, nppsSet_8s_Ctx);
impl_set!(set_u16, u16, nppsSet_16u_Ctx);
impl_set!(set_i16, i16, nppsSet_16s_Ctx);
impl_set!(set_u32, u32, nppsSet_32u_Ctx);
impl_set!(set_i32, i32, nppsSet_32s_Ctx);
impl_set!(set_i64, i64, nppsSet_64s_Ctx);
impl_set!(set_f32, f32, nppsSet_32f_Ctx);
impl_set!(set_f64, f64, nppsSet_64f_Ctx);

impl_set!(set_i16_complex, ComplexI16, nppsSet_16sc_Ctx);
impl_set!(set_i32_complex, ComplexI32, nppsSet_32sc_Ctx);
impl_set!(set_i64_complex, ComplexI64, nppsSet_64sc_Ctx);
impl_set!(set_f32_complex, Complex32, nppsSet_32fc_Ctx);
impl_set!(set_f64_complex, Complex64, nppsSet_64fc_Ctx);

impl_zero!(zero_u8, u8, nppsZero_8u_Ctx);
impl_zero!(zero_i16, i16, nppsZero_16s_Ctx);
impl_zero!(zero_i32, i32, nppsZero_32s_Ctx);
impl_zero!(zero_i64, i64, nppsZero_64s_Ctx);
impl_zero!(zero_f32, f32, nppsZero_32f_Ctx);
impl_zero!(zero_f64, f64, nppsZero_64f_Ctx);

impl_zero!(zero_i16_complex, ComplexI16, nppsZero_16sc_Ctx);
impl_zero!(zero_i32_complex, ComplexI32, nppsZero_32sc_Ctx);
impl_zero!(zero_i64_complex, ComplexI64, nppsZero_64sc_Ctx);
impl_zero!(zero_f32_complex, Complex32, nppsZero_32fc_Ctx);
impl_zero!(zero_f64_complex, Complex64, nppsZero_64fc_Ctx);

impl_copy!(copy_u8, u8, nppsCopy_8u_Ctx);
impl_copy!(copy_i16, i16, nppsCopy_16s_Ctx);
impl_copy!(copy_i32, i32, nppsCopy_32s_Ctx);
impl_copy!(copy_i64, i64, nppsCopy_64s_Ctx);
impl_copy!(copy_f32, f32, nppsCopy_32f_Ctx);

impl_copy!(copy_i16_complex, ComplexI16, nppsCopy_16sc_Ctx);
impl_copy!(copy_i32_complex, ComplexI32, nppsCopy_32sc_Ctx);
impl_copy!(copy_i64_complex, ComplexI64, nppsCopy_64sc_Ctx);
impl_copy!(copy_f32_complex, Complex32, nppsCopy_32fc_Ctx);
impl_copy!(copy_f64_complex, Complex64, nppsCopy_64fc_Ctx);

macro_rules! impl_signal_set_dispatch {
    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
        pub trait $trait: DataTypeLike {
            fn $method(
                stream_context: &StreamContext,
                value: Self,
                destination: &mut SignalViewMut<'_, Self>,
            ) -> Result<()>;
        }

        $(
            impl $trait for $ty {
                fn $method(
                    stream_context: &StreamContext,
                    value: Self,
                    destination: &mut SignalViewMut<'_, Self>,
                ) -> Result<()> {
                    $direct(stream_context, value, destination)
                }
            }
        )*

        pub fn $function<T: $trait>(
            stream_context: &StreamContext,
            value: T,
            destination: &mut SignalViewMut<'_, T>,
        ) -> Result<()> {
            T::$method(stream_context, value, destination)
        }
    };
}

macro_rules! impl_signal_zero_dispatch {
    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
        pub trait $trait: DataTypeLike {
            fn $method(
                stream_context: &StreamContext,
                destination: &mut SignalViewMut<'_, Self>,
            ) -> Result<()>;
        }

        $(
            impl $trait for $ty {
                fn $method(
                    stream_context: &StreamContext,
                    destination: &mut SignalViewMut<'_, Self>,
                ) -> Result<()> {
                    $direct(stream_context, destination)
                }
            }
        )*

        pub fn $function<T: $trait>(
            stream_context: &StreamContext,
            destination: &mut SignalViewMut<'_, T>,
        ) -> Result<()> {
            T::$method(stream_context, destination)
        }
    };
}

macro_rules! impl_signal_copy_dispatch {
    ($trait:ident, $method:ident, $function:ident, [$($ty:ty => $direct:ident),* $(,)?]) => {
        pub trait $trait: DataTypeLike {
            fn $method(
                stream_context: &StreamContext,
                source: &SignalView<'_, Self>,
                destination: &mut SignalViewMut<'_, Self>,
            ) -> Result<()>;
        }

        $(
            impl $trait for $ty {
                fn $method(
                    stream_context: &StreamContext,
                    source: &SignalView<'_, Self>,
                    destination: &mut SignalViewMut<'_, Self>,
                ) -> Result<()> {
                    $direct(stream_context, source, destination)
                }
            }
        )*

        pub fn $function<T: $trait>(
            stream_context: &StreamContext,
            source: &SignalView<'_, T>,
            destination: &mut SignalViewMut<'_, T>,
        ) -> Result<()> {
            T::$method(stream_context, source, destination)
        }
    };
}

impl_signal_set_dispatch!(Set, set, set, [
    u8 => set_u8,
    i8 => set_i8,
    u16 => set_u16,
    i16 => set_i16,
    u32 => set_u32,
    i32 => set_i32,
    i64 => set_i64,
    f32 => set_f32,
    f64 => set_f64,
    ComplexI16 => set_i16_complex,
    ComplexI32 => set_i32_complex,
    ComplexI64 => set_i64_complex,
    Complex32 => set_f32_complex,
    Complex64 => set_f64_complex
]);

impl_signal_zero_dispatch!(Zero, zero, zero, [
    u8 => zero_u8,
    i16 => zero_i16,
    i32 => zero_i32,
    i64 => zero_i64,
    f32 => zero_f32,
    f64 => zero_f64,
    ComplexI16 => zero_i16_complex,
    ComplexI32 => zero_i32_complex,
    ComplexI64 => zero_i64_complex,
    Complex32 => zero_f32_complex,
    Complex64 => zero_f64_complex
]);

impl_signal_copy_dispatch!(Copy, copy, copy, [
    u8 => copy_u8,
    i16 => copy_i16,
    i32 => copy_i32,
    i64 => copy_i64,
    f32 => copy_f32,
    ComplexI16 => copy_i16_complex,
    ComplexI32 => copy_i32_complex,
    ComplexI64 => copy_i64_complex,
    Complex32 => copy_f32_complex,
    Complex64 => copy_f64_complex
]);