#convolution #ndarray #fft

bin+lib ndarray-conv

N-Dimension convolution (with FFT) lib for ndarray

3 releases (breaking)

0.3.3 Apr 8, 2024
0.3.2 Apr 8, 2024
0.2.0 Mar 28, 2023
0.1.3 Dec 23, 2022

#103 in Math

Download history 959/week @ 2024-04-04 629/week @ 2024-04-11 344/week @ 2024-04-18 572/week @ 2024-04-25 479/week @ 2024-05-02 227/week @ 2024-05-09 611/week @ 2024-05-16 531/week @ 2024-05-23 580/week @ 2024-05-30 409/week @ 2024-06-06 565/week @ 2024-06-13 422/week @ 2024-06-20 388/week @ 2024-06-27 415/week @ 2024-07-04 206/week @ 2024-07-11 138/week @ 2024-07-18

1,199 downloads per month
Used in proseg

MIT/Apache

66KB
1.5K SLoC

ndarray-conv

ndarray-conv is a crate that provides a N-Dimension convolutions (with FFT acceleration) library in pure Rust.

Inspired by

ndarray-vision (https://github.com/rust-cv/ndarray-vision)

convolutions-rs (https://github.com/Conzel/convolutions-rs#readme)

pocketfft (https://github.com/mreineck/pocketfft)

Roadmap

  • basic conv for N dimension Array/ArrayView
  • conv with FFT acceleration for N dimension Array/ArrayView
  • impl ConvMode and PaddingMode
    • ConvMode: Full Same Valid Custom Explicit
    • PaddingMode: Zeros Const Reflect Replicate Circular Custom Explicit
  • conv with strides
  • kernel with dilation
  • handle input size error
  • explict error type
  • bench with similar libs

Examples

use ndarray_conv::*;

x_nd.conv(
    &k_n,
    PaddingSize::Full,
    PaddingMode::Circular,
);

x_1d.view().conv_fft(
    &k_1d,
    ConvMode::Same,
    PaddingMode::Explicit([[BorderType::Replicate, BorderType::Reflect]]),
);

x_2d.conv_fft(
    k_2d.with_dilation(2),
    PaddingSize::Same,
    PaddingMode::Custom([BorderType::Reflect, BorderType::Circular]),
);

// avoid loss of accuracy for fft ver
// convert Integer to Float before caculate.
x_3d.map(|&x| x as f32)
    .conv_fft(
        &kernel.map(|&x| x as f32),
        ConvMode::Same,
        PaddingMode::Zeros,
    )
    .unwrap()
    .map(|x| x.round() as i32);
fn main() {
    use ndarray_conv::*;
    use ndarray::prelude::*;
    use ndarray_rand::rand_distr::Uniform;
    use ndarray_rand::RandomExt;
    use std::time::Instant;

    let mut small_duration = 0u128;
    let test_cycles_small = 1;
    // small input data
    for _ in 0..test_cycles_small {
        let x = Array::random((2000, 4000), Uniform::new(0., 1.));
        let k = Array::random((9, 9), Uniform::new(0., 1.));

        let now = Instant::now();
        // or use x.conv_fft() for large input data
        x.conv(
            &k,
            ConvMode::Same,
            PaddingMode::Custom([BorderType::Reflect, BorderType::Circular]),
        );
        small_duration += now.elapsed().as_nanos();
    }

    println!(
        "Time for small arrays, {} iterations: {} milliseconds",
        test_cycles_small,
        small_duration / 1_000_000
    );
}

Versions

  • 0.3.3 - Bug fix: correct conv_fft's output shape.
  • 0.3.2 - Improve performance, by modifying good_fft_size and transpose.
  • 0.3.1 - Impl basic error type. Fix some bugs.
  • 0.3.0 - update to N-Dimension convolution.
  • 0.2.0 - finished conv_2d & conv_2d_fft.

Dependencies

~7MB
~140K SLoC