singe-npp 0.1.0-alpha.8

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

use crate::{
    context::StreamContext,
    error::{Error, Result},
    image::view::{C1, ImageView, ImageViewMut},
    try_ffi,
    types::{DataTypeLike, Size},
};

pub trait MagnitudeC1: DataTypeLike + Sized {
    type Output: DataTypeLike;

    fn magnitude(
        stream_context: &StreamContext,
        source: &ImageView<'_, Self, C1>,
        destination: &mut ImageViewMut<'_, Self::Output, C1>,
    ) -> Result<()>;
}

pub fn magnitude<T>(
    stream_context: &StreamContext,
    source: &ImageView<'_, T, C1>,
    destination: &mut ImageViewMut<'_, T::Output, C1>,
) -> Result<()>
where
    T: MagnitudeC1,
{
    T::magnitude(stream_context, source, destination)
}

pub trait MagnitudeSquaredC1: DataTypeLike + Sized {
    type Output: DataTypeLike;

    fn magnitude_squared(
        stream_context: &StreamContext,
        source: &ImageView<'_, Self, C1>,
        destination: &mut ImageViewMut<'_, Self::Output, C1>,
    ) -> Result<()>;
}

pub fn magnitude_squared<T>(
    stream_context: &StreamContext,
    source: &ImageView<'_, T, C1>,
    destination: &mut ImageViewMut<'_, T::Output, C1>,
) -> Result<()>
where
    T: MagnitudeSquaredC1,
{
    T::magnitude_squared(stream_context, source, destination)
}

pub(crate) fn magnitude_f32_complex_c1(
    stream_context: &StreamContext,
    source: &ImageView<'_, Complex32, C1>,
    destination: &mut ImageViewMut<'_, f32, C1>,
) -> Result<()> {
    validate_same_size(source.size(), destination.size())?;

    unsafe {
        try_ffi!(sys::nppiMagnitude_32fc32f_C1R_Ctx(
            source.as_ptr().cast(),
            source.step(),
            destination.as_mut_ptr().cast(),
            destination.step(),
            source.size().into(),
            stream_context.as_raw(),
        ))?;
    }
    Ok(())
}

pub(crate) fn magnitude_squared_f32_complex_c1(
    stream_context: &StreamContext,
    source: &ImageView<'_, Complex32, C1>,
    destination: &mut ImageViewMut<'_, f32, C1>,
) -> Result<()> {
    validate_same_size(source.size(), destination.size())?;

    unsafe {
        try_ffi!(sys::nppiMagnitudeSqr_32fc32f_C1R_Ctx(
            source.as_ptr().cast(),
            source.step(),
            destination.as_mut_ptr().cast(),
            destination.step(),
            source.size().into(),
            stream_context.as_raw(),
        ))?;
    }
    Ok(())
}

impl MagnitudeC1 for Complex32 {
    type Output = f32;

    fn magnitude(
        stream_context: &StreamContext,
        source: &ImageView<'_, Self, C1>,
        destination: &mut ImageViewMut<'_, Self::Output, C1>,
    ) -> Result<()> {
        magnitude_f32_complex_c1(stream_context, source, destination)
    }
}

impl MagnitudeSquaredC1 for Complex32 {
    type Output = f32;

    fn magnitude_squared(
        stream_context: &StreamContext,
        source: &ImageView<'_, Self, C1>,
        destination: &mut ImageViewMut<'_, Self::Output, C1>,
    ) -> Result<()> {
        magnitude_squared_f32_complex_c1(stream_context, source, destination)
    }
}

fn validate_same_size(source: Size, destination: Size) -> Result<()> {
    if source == destination {
        return Ok(());
    }
    Err(Error::SizeMismatch {
        name: "image size".into(),
        expected: source,
        actual: destination,
    })
}