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

Add support for multi-threaded FFTW operations. #11

Closed
SallySoul opened this issue Dec 23, 2024 · 11 comments
Closed

Add support for multi-threaded FFTW operations. #11

SallySoul opened this issue Dec 23, 2024 · 11 comments

Comments

@SallySoul
Copy link
Collaborator

This issue has two parts.

First, we need to implement the changes from:
rust-math/fftw#127
in our fork of the FFTW3 bindings:
https://github.com/SallySoul/fftw3-rs

Second, we need to add support for using the Rayon thread pool with FFTW3.
This involves exposing fftw_threads_set_callback, as described here
Second we need to setup an actual callback function that utilizes rayon.

@SallySoul
Copy link
Collaborator Author

Starting to dig into this. Relevant issues from fftw3
How many threads to use with Cilk? (Same model as Rayon)
FFTW/fftw3#369

Issue for the thread callback model, lots of useful info:
FFTW/fftw3#175

@SallySoul
Copy link
Collaborator Author

SallySoul commented Dec 30, 2024

To quote that last thread:

I've looked at it a bit more, and implemented something even simpler:

Compile FFTW with --enable-threads and call fftw_init_threads etc. as usual.

Call the undocumented function fftw_threads_set_callback(spawnloop_function callback, void *callback_data), where callback is a function with the signature void callback(void *(*f)(void *), size_t elsize, int num, void *fdata, void callback_data). This function should then execute f(fdata + ielsize) for i = 0 to num-1 — it can perform these calls in parallel if it wants, but it must not return until all of the executions are finished (i.e. it should do both spawn and sync).

If you call fftw_threads_set_callback before any FFTW planning, then it will never launch its own worker threads, and will just use the callback. On the other hand it still links to pthreads, so the mutexes for threadsafe-planning still work, and we can decide at runtime to stick with pthreads (e.g. for Julia versions < 1.3) with the same FFTW binary.

@SallySoul
Copy link
Collaborator Author

SallySoul commented Dec 30, 2024

It seems that work got released as part of 3.3.10:
FFTW/fftw3@f1ad19c

With this in mind, I need to do

  • Update FFTW3 src to newer version
  • Build fftw-src with --enable-threads
  • Expose fftw_init_threads in fftw3-rs
  • Implement Rayon thread callback.

@SallySoul
Copy link
Collaborator Author

Update FFTW3 version:
SallySoul/fftw3-rs#4

@SallySoul
Copy link
Collaborator Author

The bindings currently handle plan thread safety exactly the way I want:

  • Making plans requires exclusive access to fftw,
  • Executing a plan can be done by any thread with new buffer pointers.

@SallySoul
Copy link
Collaborator Author

Working on the rayon callback, hitting a snag with Rust ptrs not being Sync + Send:
https://internals.rust-lang.org/t/shouldnt-pointers-be-send-sync-or/8818/3

There is a crate to handle this issue:
https://github.com/AlexanderSchuetz97/sync-ptr

@SallySoul
Copy link
Collaborator Author

Got the rayon callback compiled and setup a simple test, running into a linking issue, I think I forgot to link the threads library.

  = note: Undefined symbols for architecture arm64:
            "_fftw_init_threads", referenced from:
                fftw::threading::init_threads_f64::h0187b6e386d2ff8a in libfftw-904fa5a30efd52a8.rlib[11](fftw-904fa5a30efd52a8.fftw.53ceecbe4a6c6038-cgu.8.rcgu.o)
                fftw::threading::init_threads_f64::h0187b6e386d2ff8a in libfftw-904fa5a30efd52a8.rlib[11](fftw-904fa5a30efd52a8.fftw.53ceecbe4a6c6038-cgu.8.rcgu.o)
            "_fftw_plan_with_nthreads", referenced from:
                fftw::threading::plan_with_nthreads_f64::h7abf27c265bf81a3 in libfftw-904fa5a30efd52a8.rlib[11](fftw-904fa5a30efd52a8.fftw.53ceecbe4a6c6038-cgu.8.rcgu.o)
                fftw::threading::plan_with_nthreads_f64::h7abf27c265bf81a3 in libfftw-904fa5a30efd52a8.rlib[11](fftw-904fa5a30efd52a8.fftw.53ceecbe4a6c6038-cgu.8.rcgu.o)
            "_fftw_threads_set_callback", referenced from:
                fftw::threading::init_threads_f64::h0187b6e386d2ff8a in libfftw-904fa5a30efd52a8.rlib[11](fftw-904fa5a30efd52a8.fftw.53ceecbe4a6c6038-cgu.8.rcgu.o)
                fftw::threading::init_threads_f64::h0187b6e386d2ff8a in libfftw-904fa5a30efd52a8.rlib[11](fftw-904fa5a30efd52a8.fftw.53ceecbe4a6c6038-cgu.8.rcgu.o)
          ld: symbol(s) not found for architecture arm64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

@SallySoul
Copy link
Collaborator Author

Oh and I had to set export MACOSX_DEPLOYMENT_TARGET=14.0 to fix another error.
https://stackoverflow.com/questions/64864117/how-to-specify-the-macos-deployment-target-for-a-library

@SallySoul
Copy link
Collaborator Author

I think the rayon thread callback is working now. An interesting note there, I had to double check how building FFTW3 works again, and you need to configure and build libfftw and libfftwf separately.

@SallySoul
Copy link
Collaborator Author

Initial threading PR for fftw bindings:
SallySoul/fftw3-rs#6

@SallySoul
Copy link
Collaborator Author

This is complete for our purposes. I need to do some cleanup on the feature in the bindings, but I'll deal with that over there.

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

No branches or pull requests

1 participant