summaryrefslogtreecommitdiff
path: root/gr-fft/lib/fft.cc
diff options
context:
space:
mode:
authorMarcus Müller <mmueller@gnuradio.org>2019-08-07 21:45:12 +0200
committerMarcus Müller <marcus@hostalia.de>2019-08-09 23:04:28 +0200
commitf7bbf2c1d8d780294f3e016aff239ca35eb6516e (patch)
treee09ab6112e02b2215b2d59ac24d3d6ea2edac745 /gr-fft/lib/fft.cc
parent78431dc6941e3acc67c858277dfe4a0ed583643c (diff)
Tree: clang-format without the include sorting
Diffstat (limited to 'gr-fft/lib/fft.cc')
-rw-r--r--gr-fft/lib/fft.cc574
1 files changed, 273 insertions, 301 deletions
diff --git a/gr-fft/lib/fft.cc b/gr-fft/lib/fft.cc
index 718cd0990f..68070d2399 100644
--- a/gr-fft/lib/fft.cc
+++ b/gr-fft/lib/fft.cc
@@ -26,17 +26,19 @@
#include <volk/volk.h>
#include <fftw3.h>
-#ifdef _WIN32 //http://www.fftw.org/install/windows.html#DLLwisdom
-static void my_fftw_write_char(char c, void *f) { fputc(c, (FILE *) f); }
-#define fftw_export_wisdom_to_file(f) fftw_export_wisdom(my_fftw_write_char, (void*) (f))
-#define fftwf_export_wisdom_to_file(f) fftwf_export_wisdom(my_fftw_write_char, (void*) (f))
-#define fftwl_export_wisdom_to_file(f) fftwl_export_wisdom(my_fftw_write_char, (void*) (f))
-
-static int my_fftw_read_char(void *f) { return fgetc((FILE *) f); }
-#define fftw_import_wisdom_from_file(f) fftw_import_wisdom(my_fftw_read_char, (void*) (f))
-#define fftwf_import_wisdom_from_file(f) fftwf_import_wisdom(my_fftw_read_char, (void*) (f))
-#define fftwl_import_wisdom_from_file(f) fftwl_import_wisdom(my_fftw_read_char, (void*) (f))
-#include <fcntl.h>
+#ifdef _WIN32 // http://www.fftw.org/install/windows.html#DLLwisdom
+static void my_fftw_write_char(char c, void* f) { fputc(c, (FILE*)f); }
+#define fftw_export_wisdom_to_file(f) fftw_export_wisdom(my_fftw_write_char, (void*)(f))
+#define fftwf_export_wisdom_to_file(f) fftwf_export_wisdom(my_fftw_write_char, (void*)(f))
+#define fftwl_export_wisdom_to_file(f) fftwl_export_wisdom(my_fftw_write_char, (void*)(f))
+
+static int my_fftw_read_char(void* f) { return fgetc((FILE*)f); }
+#define fftw_import_wisdom_from_file(f) fftw_import_wisdom(my_fftw_read_char, (void*)(f))
+#define fftwf_import_wisdom_from_file(f) \
+ fftwf_import_wisdom(my_fftw_read_char, (void*)(f))
+#define fftwl_import_wisdom_from_file(f) \
+ fftwl_import_wisdom(my_fftw_read_char, (void*)(f))
+#include <fcntl.h>
#include <io.h>
#define O_NOCTTY 0
#define O_NONBLOCK 0
@@ -54,349 +56,319 @@ static int my_fftw_read_char(void *f) { return fgetc((FILE *) f); }
namespace fs = boost::filesystem;
namespace gr {
- namespace fft {
- static boost::mutex wisdom_thread_mutex;
- boost::interprocess::file_lock wisdom_lock;
- static bool wisdom_lock_init_done = false; // Modify while holding 'wisdom_thread_mutex'
-
- gr_complex *
- malloc_complex(int size)
- {
- return (gr_complex*) volk_malloc (sizeof (gr_complex)*size, volk_get_alignment ());
- }
-
- float *
- malloc_float(int size)
- {
- return (float*) volk_malloc (sizeof (float)*size, volk_get_alignment ());
- }
+namespace fft {
+static boost::mutex wisdom_thread_mutex;
+boost::interprocess::file_lock wisdom_lock;
+static bool wisdom_lock_init_done = false; // Modify while holding 'wisdom_thread_mutex'
+
+gr_complex* malloc_complex(int size)
+{
+ return (gr_complex*)volk_malloc(sizeof(gr_complex) * size, volk_get_alignment());
+}
+
+float* malloc_float(int size)
+{
+ return (float*)volk_malloc(sizeof(float) * size, volk_get_alignment());
+}
+
+double* malloc_double(int size)
+{
+ return (double*)volk_malloc(sizeof(double) * size, volk_get_alignment());
+}
+
+void free(void* b) { volk_free(b); }
+
+boost::mutex& planner::mutex()
+{
+ static boost::mutex s_planning_mutex;
+
+ return s_planning_mutex;
+}
+
+static std::string wisdom_filename()
+{
+ static fs::path path;
+ path = fs::path(gr::appdata_path()) / ".gr_fftw_wisdom";
+ return path.string();
+}
+
+static void wisdom_lock_init()
+{
+ if (wisdom_lock_init_done)
+ return;
- double *
- malloc_double(int size)
- {
- return (double*) volk_malloc (sizeof (double)*size, volk_get_alignment ());
+ const std::string wisdom_lock_file = wisdom_filename() + ".lock";
+ // std::cerr << "Creating FFTW wisdom lockfile: " << wisdom_lock_file << std::endl;
+ int fd =
+ open(wisdom_lock_file.c_str(), O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0666);
+ if (fd < 0) {
+ throw std::runtime_error("Failed to create FFTW wisdom lockfile: " +
+ wisdom_lock_file);
}
-
- void
- free(void *b)
- {
- volk_free(b);
+ close(fd);
+ wisdom_lock = boost::interprocess::file_lock(wisdom_lock_file.c_str());
+ wisdom_lock_init_done = true;
+}
+
+static void lock_wisdom()
+{
+ wisdom_thread_mutex.lock();
+ wisdom_lock_init();
+ wisdom_lock.lock();
+}
+
+static void unlock_wisdom()
+{
+ // Assumes 'lock_wisdom' has already been called (i.e. this file_lock is valid)
+ wisdom_lock.unlock();
+ wisdom_thread_mutex.unlock();
+}
+
+static void import_wisdom()
+{
+ const std::string filename = wisdom_filename();
+ FILE* fp = fopen(filename.c_str(), "r");
+ if (fp != 0) {
+ int r = fftwf_import_wisdom_from_file(fp);
+ fclose(fp);
+ if (!r) {
+ fprintf(stderr, "gr::fft: can't import wisdom from %s\n", filename.c_str());
+ }
}
+}
- boost::mutex &
- planner::mutex()
- {
- static boost::mutex s_planning_mutex;
+static void config_threading(int nthreads)
+{
+ static int fftw_threads_inited = 0;
- return s_planning_mutex;
+#ifdef FFTW3F_THREADS
+ if (fftw_threads_inited == 0) {
+ fftw_threads_inited = 1;
+ fftwf_init_threads();
}
- static std::string
- wisdom_filename()
- {
- static fs::path path;
- path = fs::path(gr::appdata_path()) / ".gr_fftw_wisdom";
- return path.string();
+ fftwf_plan_with_nthreads(nthreads);
+#endif
+}
+
+static void export_wisdom()
+{
+ const std::string filename = wisdom_filename();
+ FILE* fp = fopen(filename.c_str(), "w");
+ if (fp != 0) {
+ fftwf_export_wisdom_to_file(fp);
+ fclose(fp);
+ } else {
+ fprintf(stderr, "fft_impl_fftw: ");
+ perror(filename.c_str());
}
+}
- static void
- wisdom_lock_init()
- {
- if (wisdom_lock_init_done)
- return;
+// ----------------------------------------------------------------
- const std::string wisdom_lock_file = wisdom_filename() + ".lock";
- // std::cerr << "Creating FFTW wisdom lockfile: " << wisdom_lock_file << std::endl;
- int fd = open(wisdom_lock_file.c_str(),
- O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK,
- 0666);
- if (fd < 0) {
- throw std::runtime_error("Failed to create FFTW wisdom lockfile: " + wisdom_lock_file);
- }
- close(fd);
- wisdom_lock = boost::interprocess::file_lock(wisdom_lock_file.c_str());
- wisdom_lock_init_done = true;
- }
+fft_complex::fft_complex(int fft_size, bool forward, int nthreads)
+{
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
- static void
- lock_wisdom()
- {
- wisdom_thread_mutex.lock();
- wisdom_lock_init();
- wisdom_lock.lock();
- }
+ assert(sizeof(fftwf_complex) == sizeof(gr_complex));
- static void
- unlock_wisdom()
- {
- // Assumes 'lock_wisdom' has already been called (i.e. this file_lock is valid)
- wisdom_lock.unlock();
- wisdom_thread_mutex.unlock();
+ if (fft_size <= 0) {
+ throw std::out_of_range("fft_impl_fftw: invalid fft_size");
}
- static void
- import_wisdom()
- {
- const std::string filename = wisdom_filename ();
- FILE *fp = fopen (filename.c_str(), "r");
- if (fp != 0){
- int r = fftwf_import_wisdom_from_file (fp);
- fclose (fp);
- if (!r){
- fprintf (stderr, "gr::fft: can't import wisdom from %s\n", filename.c_str());
- }
- }
+ d_fft_size = fft_size;
+ d_inbuf = (gr_complex*)volk_malloc(sizeof(gr_complex) * inbuf_length(),
+ volk_get_alignment());
+ if (d_inbuf == 0) {
+ throw std::runtime_error("volk_malloc");
}
-
- static void
- config_threading(int nthreads)
- {
- static int fftw_threads_inited = 0;
-
-#ifdef FFTW3F_THREADS
- if (fftw_threads_inited == 0)
- {
- fftw_threads_inited = 1;
- fftwf_init_threads();
+ d_outbuf = (gr_complex*)volk_malloc(sizeof(gr_complex) * outbuf_length(),
+ volk_get_alignment());
+ if (d_outbuf == 0) {
+ volk_free(d_inbuf);
+ throw std::runtime_error("volk_malloc");
}
- fftwf_plan_with_nthreads(nthreads);
-#endif
- }
+ d_nthreads = nthreads;
+ config_threading(nthreads);
+ lock_wisdom();
+ import_wisdom(); // load prior wisdom from disk
- static void
- export_wisdom()
- {
- const std::string filename = wisdom_filename ();
- FILE *fp = fopen (filename.c_str(), "w");
- if (fp != 0){
- fftwf_export_wisdom_to_file (fp);
- fclose (fp);
- }
- else {
- fprintf (stderr, "fft_impl_fftw: ");
- perror (filename.c_str());
- }
- }
-
-// ----------------------------------------------------------------
+ d_plan = fftwf_plan_dft_1d(fft_size,
+ reinterpret_cast<fftwf_complex*>(d_inbuf),
+ reinterpret_cast<fftwf_complex*>(d_outbuf),
+ forward ? FFTW_FORWARD : FFTW_BACKWARD,
+ FFTW_MEASURE);
- fft_complex::fft_complex(int fft_size, bool forward, int nthreads)
- {
- // Hold global mutex during plan construction and destruction.
- planner::scoped_lock lock(planner::mutex());
-
- assert (sizeof (fftwf_complex) == sizeof (gr_complex));
-
- if (fft_size <= 0){
- throw std::out_of_range ("fft_impl_fftw: invalid fft_size");
- }
-
- d_fft_size = fft_size;
- d_inbuf = (gr_complex *) volk_malloc (sizeof (gr_complex) * inbuf_length (), volk_get_alignment ());
- if (d_inbuf == 0) {
- throw std::runtime_error ("volk_malloc");
- }
- d_outbuf = (gr_complex *) volk_malloc (sizeof (gr_complex) * outbuf_length (), volk_get_alignment ());
- if (d_outbuf == 0) {
- volk_free (d_inbuf);
- throw std::runtime_error ("volk_malloc");
- }
-
- d_nthreads = nthreads;
- config_threading(nthreads);
- lock_wisdom();
- import_wisdom(); // load prior wisdom from disk
-
- d_plan = fftwf_plan_dft_1d (fft_size,
- reinterpret_cast<fftwf_complex *>(d_inbuf),
- reinterpret_cast<fftwf_complex *>(d_outbuf),
- forward ? FFTW_FORWARD : FFTW_BACKWARD,
- FFTW_MEASURE);
-
- if (d_plan == NULL) {
+ if (d_plan == NULL) {
fprintf(stderr, "gr::fft: error creating plan\n");
- throw std::runtime_error ("fftwf_plan_dft_1d failed");
- }
- export_wisdom(); // store new wisdom to disk
- unlock_wisdom();
+ throw std::runtime_error("fftwf_plan_dft_1d failed");
}
-
- fft_complex::~fft_complex()
- {
- // Hold global mutex during plan construction and destruction.
- planner::scoped_lock lock(planner::mutex());
-
- fftwf_destroy_plan ((fftwf_plan) d_plan);
- volk_free (d_inbuf);
- volk_free (d_outbuf);
+ export_wisdom(); // store new wisdom to disk
+ unlock_wisdom();
+}
+
+fft_complex::~fft_complex()
+{
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ fftwf_destroy_plan((fftwf_plan)d_plan);
+ volk_free(d_inbuf);
+ volk_free(d_outbuf);
+}
+
+void fft_complex::set_nthreads(int n)
+{
+ if (n <= 0) {
+ throw std::out_of_range("gr::fft: invalid number of threads");
}
-
- void
- fft_complex::set_nthreads(int n)
- {
- if (n <= 0) {
- throw std::out_of_range ("gr::fft: invalid number of threads");
- }
- d_nthreads = n;
+ d_nthreads = n;
#ifdef FFTW3F_THREADS
- fftwf_plan_with_nthreads(d_nthreads);
+ fftwf_plan_with_nthreads(d_nthreads);
#endif
- }
+}
- void
- fft_complex::execute()
- {
- fftwf_execute((fftwf_plan) d_plan);
- }
+void fft_complex::execute() { fftwf_execute((fftwf_plan)d_plan); }
// ----------------------------------------------------------------
- fft_real_fwd::fft_real_fwd (int fft_size, int nthreads)
- {
- // Hold global mutex during plan construction and destruction.
- planner::scoped_lock lock(planner::mutex());
+fft_real_fwd::fft_real_fwd(int fft_size, int nthreads)
+{
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
- assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+ assert(sizeof(fftwf_complex) == sizeof(gr_complex));
- if (fft_size <= 0) {
- throw std::out_of_range ("gr::fft: invalid fft_size");
- }
+ if (fft_size <= 0) {
+ throw std::out_of_range("gr::fft: invalid fft_size");
+ }
- d_fft_size = fft_size;
- d_inbuf = (float *) volk_malloc (sizeof (float) * inbuf_length (), volk_get_alignment ());
- if (d_inbuf == 0) {
- throw std::runtime_error ("volk_malloc");
- }
+ d_fft_size = fft_size;
+ d_inbuf = (float*)volk_malloc(sizeof(float) * inbuf_length(), volk_get_alignment());
+ if (d_inbuf == 0) {
+ throw std::runtime_error("volk_malloc");
+ }
- d_outbuf = (gr_complex *) volk_malloc (sizeof (gr_complex) * outbuf_length (), volk_get_alignment ());
- if (d_outbuf == 0) {
- volk_free (d_inbuf);
- throw std::runtime_error ("volk_malloc");
- }
+ d_outbuf = (gr_complex*)volk_malloc(sizeof(gr_complex) * outbuf_length(),
+ volk_get_alignment());
+ if (d_outbuf == 0) {
+ volk_free(d_inbuf);
+ throw std::runtime_error("volk_malloc");
+ }
- d_nthreads = nthreads;
- config_threading(nthreads);
- lock_wisdom();
- import_wisdom(); // load prior wisdom from disk
+ d_nthreads = nthreads;
+ config_threading(nthreads);
+ lock_wisdom();
+ import_wisdom(); // load prior wisdom from disk
- d_plan = fftwf_plan_dft_r2c_1d (fft_size,
- d_inbuf,
- reinterpret_cast<fftwf_complex *>(d_outbuf),
- FFTW_MEASURE);
+ d_plan = fftwf_plan_dft_r2c_1d(
+ fft_size, d_inbuf, reinterpret_cast<fftwf_complex*>(d_outbuf), FFTW_MEASURE);
- if (d_plan == NULL) {
+ if (d_plan == NULL) {
fprintf(stderr, "gr::fft::fft_real_fwd: error creating plan\n");
- throw std::runtime_error ("fftwf_plan_dft_r2c_1d failed");
- }
- export_wisdom(); // store new wisdom to disk
- unlock_wisdom();
+ throw std::runtime_error("fftwf_plan_dft_r2c_1d failed");
}
-
- fft_real_fwd::~fft_real_fwd()
- {
- // Hold global mutex during plan construction and destruction.
- planner::scoped_lock lock(planner::mutex());
-
- fftwf_destroy_plan ((fftwf_plan) d_plan);
- volk_free (d_inbuf);
- volk_free (d_outbuf);
+ export_wisdom(); // store new wisdom to disk
+ unlock_wisdom();
+}
+
+fft_real_fwd::~fft_real_fwd()
+{
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ fftwf_destroy_plan((fftwf_plan)d_plan);
+ volk_free(d_inbuf);
+ volk_free(d_outbuf);
+}
+
+void fft_real_fwd::set_nthreads(int n)
+{
+ if (n <= 0) {
+ throw std::out_of_range(
+ "gr::fft::fft_real_fwd::set_nthreads: invalid number of threads");
}
-
- void
- fft_real_fwd::set_nthreads(int n)
- {
- if (n <= 0) {
- throw std::out_of_range ("gr::fft::fft_real_fwd::set_nthreads: invalid number of threads");
- }
- d_nthreads = n;
+ d_nthreads = n;
#ifdef FFTW3F_THREADS
- fftwf_plan_with_nthreads(d_nthreads);
+ fftwf_plan_with_nthreads(d_nthreads);
#endif
+}
+
+void fft_real_fwd::execute() { fftwf_execute((fftwf_plan)d_plan); }
+
+// ----------------------------------------------------------------
+
+fft_real_rev::fft_real_rev(int fft_size, int nthreads)
+{
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ assert(sizeof(fftwf_complex) == sizeof(gr_complex));
+
+ if (fft_size <= 0) {
+ throw std::out_of_range("gr::fft::fft_real_rev: invalid fft_size");
}
- void
- fft_real_fwd::execute()
- {
- fftwf_execute ((fftwf_plan) d_plan);
+ d_fft_size = fft_size;
+ d_inbuf = (gr_complex*)volk_malloc(sizeof(gr_complex) * inbuf_length(),
+ volk_get_alignment());
+ if (d_inbuf == 0) {
+ throw std::runtime_error("volk_malloc");
}
- // ----------------------------------------------------------------
-
- fft_real_rev::fft_real_rev(int fft_size, int nthreads)
- {
- // Hold global mutex during plan construction and destruction.
- planner::scoped_lock lock(planner::mutex());
-
- assert (sizeof (fftwf_complex) == sizeof (gr_complex));
-
- if (fft_size <= 0) {
- throw std::out_of_range ("gr::fft::fft_real_rev: invalid fft_size");
- }
-
- d_fft_size = fft_size;
- d_inbuf = (gr_complex *) volk_malloc (sizeof (gr_complex) * inbuf_length (), volk_get_alignment ());
- if (d_inbuf == 0) {
- throw std::runtime_error ("volk_malloc");
- }
-
- d_outbuf = (float *) volk_malloc (sizeof (float) * outbuf_length (), volk_get_alignment ());
- if (d_outbuf == 0) {
- volk_free (d_inbuf);
- throw std::runtime_error ("volk_malloc");
- }
-
- d_nthreads = nthreads;
- config_threading(nthreads);
- lock_wisdom();
- import_wisdom(); // load prior wisdom from disk
-
- // FIXME If there's ever a chance that the planning functions
- // will be called in multiple threads, we've got to ensure single
- // threaded access. They are not thread-safe.
- d_plan = fftwf_plan_dft_c2r_1d (fft_size,
- reinterpret_cast<fftwf_complex *>(d_inbuf),
- d_outbuf,
- FFTW_MEASURE);
-
- if (d_plan == NULL) {
- fprintf(stderr, "gr::fft::fft_real_rev: error creating plan\n");
- throw std::runtime_error ("fftwf_plan_dft_c2r_1d failed");
- }
- export_wisdom (); // store new wisdom to disk
- unlock_wisdom();
+ d_outbuf = (float*)volk_malloc(sizeof(float) * outbuf_length(), volk_get_alignment());
+ if (d_outbuf == 0) {
+ volk_free(d_inbuf);
+ throw std::runtime_error("volk_malloc");
}
- fft_real_rev::~fft_real_rev ()
- {
- // Hold global mutex during plan construction and destruction.
- planner::scoped_lock lock(planner::mutex());
+ d_nthreads = nthreads;
+ config_threading(nthreads);
+ lock_wisdom();
+ import_wisdom(); // load prior wisdom from disk
- fftwf_destroy_plan ((fftwf_plan) d_plan);
- volk_free (d_inbuf);
- volk_free (d_outbuf);
- }
+ // FIXME If there's ever a chance that the planning functions
+ // will be called in multiple threads, we've got to ensure single
+ // threaded access. They are not thread-safe.
+ d_plan = fftwf_plan_dft_c2r_1d(
+ fft_size, reinterpret_cast<fftwf_complex*>(d_inbuf), d_outbuf, FFTW_MEASURE);
- void
- fft_real_rev::set_nthreads(int n)
- {
- if (n <= 0) {
- throw std::out_of_range ("gr::fft::fft_real_rev::set_nthreads: invalid number of threads");
- }
- d_nthreads = n;
+ if (d_plan == NULL) {
+ fprintf(stderr, "gr::fft::fft_real_rev: error creating plan\n");
+ throw std::runtime_error("fftwf_plan_dft_c2r_1d failed");
+ }
+ export_wisdom(); // store new wisdom to disk
+ unlock_wisdom();
+}
+
+fft_real_rev::~fft_real_rev()
+{
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ fftwf_destroy_plan((fftwf_plan)d_plan);
+ volk_free(d_inbuf);
+ volk_free(d_outbuf);
+}
+
+void fft_real_rev::set_nthreads(int n)
+{
+ if (n <= 0) {
+ throw std::out_of_range(
+ "gr::fft::fft_real_rev::set_nthreads: invalid number of threads");
+ }
+ d_nthreads = n;
#ifdef FFTW3F_THREADS
- fftwf_plan_with_nthreads(d_nthreads);
+ fftwf_plan_with_nthreads(d_nthreads);
#endif
- }
+}
- void
- fft_real_rev::execute ()
- {
- fftwf_execute ((fftwf_plan) d_plan);
- }
+void fft_real_rev::execute() { fftwf_execute((fftwf_plan)d_plan); }
- } /* namespace fft */
+} /* namespace fft */
} /* namespace gr */