Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numpy FFT implementation? #39

Closed
vade opened this issue Jan 31, 2023 · 11 comments
Closed

Numpy FFT implementation? #39

vade opened this issue Jan 31, 2023 · 11 comments
Labels
enhancement New feature or request

Comments

@vade
Copy link

vade commented Jan 31, 2023

Hi there

Firstly, this library looks amazing. You've done a ton of work and it looks really promising. Thank you!

I was curious if there was any plans to implement Numpy's FFTs in vDSP? If not, do you do work for hire?

I did some work looking into this myself for work on porting OpenAI's Whisper to CoreML / Accelerate https://github.com/vade/OpenAI-Whisper-CoreML

And I documented some of my findings in this issue here: vade/OpenAI-Whisper-CoreML#1

It seems like Numpy, PyTorch, Rosa / RosaKit all use PocketFFT to do non power of 2 DFTs, which is why the output matches more or less exactly numerically.

PocketFFT doesn't use vDSP, but rather scalar - no simd acceleration.

Given the rest of MatFT's current implementation, doing the STFT and Log Mel work in MatFT would just work. The only missing piece is a numerically equivalent implementation of the Numpy / Torch 'real to complex' (rfft) logic.

Thank you again for all the work on Mattft!

@jjjkkkjjj
Copy link
Owner

jjjkkkjjj commented Feb 2, 2023

@vade
Thank you for your feedback!

I have no plans to implement FFT for now, but maybe I can implement numpy's FFT to use some vDSP_* functions such like vDSP_DFT_Execute or vDSP_fft_zrip as you mentioned your issue.
And then, because the fft's output is complex, I must implement some ToDo.

do you do work for hire?

What do you mean? I'm not good at English... lol

@vade
Copy link
Author

vade commented Feb 2, 2023

Hi. We're (my company) is looking at using Matft library for usage in our product. We might want to sponsor some features, ie: pay you to do some work on Matft for the community under the same BSD license, so everyone can benefit and can be shared by all.

Some things that could be awesome:

  • MLShapedArray support - ie effortlessly use an MLShapedArray with Matft
  • FFT support to some degree (we only care about forward real ftt for now)
  • im sure there will be more here !

It would be really good for the Swift / ML / Ai / Computer Vision community to have a native, fast library similar to functionality to Numpy !

@jjjkkkjjj
Copy link
Owner

Really!?
I’m very welcome to sponsor Matft!! I’m getting motivated 🫡
Should I open a GitHub sponsor?

Anyway, I’ll try to implement some features you mentioned!

@vade
Copy link
Author

vade commented Feb 3, 2023

Hah! Glad you're feeling motivated. Before we all get carried away its helpful to align and set some expectations. I'll send you an email to the address on your git account. Look for an email from anton [at] :)

Thanks!

jjjkkkjjj pushed a commit that referenced this issue Feb 6, 2023
jjjkkkjjj added a commit that referenced this issue Feb 6, 2023
* save

* save

* fixed #39

---------

Co-authored-by: jjjkkkjjj-mizuno <[email protected]>
@jjjkkkjjj jjjkkkjjj reopened this Feb 6, 2023
@jjjkkkjjj
Copy link
Owner

jjjkkkjjj commented Feb 6, 2023

Look for an email from anton [at] :)

OK!

Notice:
I couldn't initialize MLShapedArray. So, I've supported MLMultiArray instead :( (#40)

@jjjkkkjjj
Copy link
Owner

jjjkkkjjj commented Feb 6, 2023

jjjkkkjjj pushed a commit that referenced this issue Feb 20, 2023
@jjjkkkjjj
Copy link
Owner

jjjkkkjjj commented Feb 20, 2023

I've just implemented rfft.
But its result was different from numpy

let a = MfArray([0, 1, 0, 0])
let real = MfArray([ 1,  0, -1])
 let imag = MfArray([ 0,  -1, 0])
            
XCTAssertEqual(Matft.fft.rfft(a), MfArray(real: real, imag: imag, mftype: .Float))

XCTAssertEqual failed: ("mfarray =
[ 0.99999994 +0j, -0.99999994 +0j, 0.0 +0j], type=Float, shape=[3]") is not equal to ("mfarray =
[ 1.0 +0j, 0.0 -1j, -1.0 +0j], type=Float, shape=[3]")

Its optimization may be different from numpy's one.
Anyway, I'll try to incorporate pocketFFT (used by numpy) into Matft

@jjjkkkjjj
Copy link
Owner

@vade
I've just implemented rfft and irfft!! (also complex setter (#24))
Notice: I used pocketFFT used in numpy, so this function is not accelerated. I'll try to implement vDSP_fft_op to be faster.
Anyway, please check the latest fft branch!

@jjjkkkjjj jjjkkkjjj added the enhancement New feature or request label Feb 22, 2023
@jjjkkkjjj
Copy link
Owner

jjjkkkjjj commented Mar 2, 2023

Memo:
https://www.jstage.jst.go.jp/article/jasj/77/5/77_331/_pdf
It's very helpful to understand DFT.

https://tiny-wing.hatenablog.com/entry/2016/06/27/093809
According to vDSP programming guide, real and imaginary element in the first element of a returned complex are DC component and nyquist one respectively.

@jjjkkkjjj
Copy link
Owner

Because vDSP needs the exponent of 2 as an argument, it seems vDSP function cannot calculate odd frequencies?

jjjkkkjjj added a commit that referenced this issue Jun 10, 2023
* fft

* implemented rfft backward forward (#39)

* rfft_forward

* passed real_forward

* irfft

* modified to_complex

* implemented irfft but memory leak occurred... (#39)

* passed rfft and irfft test (#39)

* fixed bug (#42)

* modified vDSP rFFT

* add fft

---------

Co-authored-by: jjjkkkjjj-mizuno <[email protected]>
@jjjkkkjjj
Copy link
Owner

I merged fft branch into master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants