diff options
author | Tom Rondeau | 2012-02-06 14:48:13 -0500 |
---|---|---|
committer | Tom Rondeau | 2012-02-06 14:48:13 -0500 |
commit | c4d0b47fdbbbfee18d6dfc87c501731a0591fa57 (patch) | |
tree | 99e8c564bfa7f717ecba0f62bb356b92034d2efc /gnuradio-core/src/lib/general | |
parent | f49facf71cd1b31a8553de85377d956a3299f2d7 (diff) | |
parent | 7e10a26470d638afec9db3bd89ae3243fe0abd83 (diff) | |
download | gnuradio-c4d0b47fdbbbfee18d6dfc87c501731a0591fa57.tar.gz gnuradio-c4d0b47fdbbbfee18d6dfc87c501731a0591fa57.tar.bz2 gnuradio-c4d0b47fdbbbfee18d6dfc87c501731a0591fa57.zip |
Merge branch 'master' into next
Diffstat (limited to 'gnuradio-core/src/lib/general')
-rw-r--r-- | gnuradio-core/src/lib/general/gr_fft_vcc.cc | 20 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_fft_vcc.h | 11 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_fft_vcc.i | 10 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc | 27 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h | 15 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gri_fft.cc | 70 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gri_fft.h | 39 |
7 files changed, 170 insertions, 22 deletions
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.cc b/gnuradio-core/src/lib/general/gr_fft_vcc.cc index d07f6fa07..64dda2491 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.cc @@ -32,9 +32,12 @@ #include <string.h> gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> &window, bool shift) +gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads) { - return gr_make_fft_vcc_fftw(fft_size, forward, window, shift); + return gr_make_fft_vcc_fftw(fft_size, forward, + window, shift, nthreads); } gr_fft_vcc::gr_fft_vcc (const std::string &name, @@ -62,3 +65,16 @@ gr_fft_vcc::set_window(const std::vector<float> &window) else return false; } + +void +gr_fft_vcc::set_nthreads(int n) +{ + throw std::runtime_error("gr_fft_vcc::set_nthreads not implemented."); +} + +int +gr_fft_vcc::nthreads() const +{ + throw std::runtime_error("gr_fft_vcc::nthreads not implemented."); + return 0; +} diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.h b/gnuradio-core/src/lib/general/gr_fft_vcc.h index a7c8e1162..6c3985987 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.h +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.h @@ -30,7 +30,9 @@ class gr_fft_vcc; typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr; GR_CORE_API gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); +gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift=false, int nthreads=1); /*! * \brief Compute forward or reverse FFT. complex vector in / complex vector out. @@ -42,7 +44,9 @@ class GR_CORE_API gr_fft_vcc : public gr_sync_block { protected: friend GR_CORE_API gr_fft_vcc_sptr - gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift); unsigned int d_fft_size; std::vector<float> d_window; @@ -55,6 +59,9 @@ protected: public: ~gr_fft_vcc (); + virtual void set_nthreads(int n); + virtual int nthreads() const; + bool set_window(const std::vector<float> &window); }; diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.i b/gnuradio-core/src/lib/general/gr_fft_vcc.i index f35316e70..0dc5353b2 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.i +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.i @@ -23,13 +23,19 @@ GR_SWIG_BLOCK_MAGIC(gr, fft_vcc) gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); +gr_make_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift=false, int nthreads=1); class gr_fft_vcc : public gr_sync_block { protected: - gr_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_fft_vcc (int fft_size, bool forward, + const std::vector<float> &window, + bool shift); public: bool set_window(const std::vector<float> &window); + void set_nthreads(int n); + int nthreads() const; }; diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc index 948ab20b9..e6032ad9e 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc @@ -31,16 +31,21 @@ #include <string.h> gr_fft_vcc_sptr -gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift) +gr_make_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads) { - return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw (fft_size, forward, window, shift)); + return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw + (fft_size, forward, window, + shift, nthreads)); } gr_fft_vcc_fftw::gr_fft_vcc_fftw (int fft_size, bool forward, - const std::vector<float> &window, bool shift) + const std::vector<float> &window, + bool shift, int nthreads) : gr_fft_vcc("fft_vcc_fftw", fft_size, forward, window, shift) { - d_fft = new gri_fft_complex (d_fft_size, forward); + d_fft = new gri_fft_complex (d_fft_size, forward, nthreads); } gr_fft_vcc_fftw::~gr_fft_vcc_fftw () @@ -48,6 +53,18 @@ gr_fft_vcc_fftw::~gr_fft_vcc_fftw () delete d_fft; } +void +gr_fft_vcc_fftw::set_nthreads(int n) +{ + d_fft->set_nthreads(n); +} + +int +gr_fft_vcc_fftw::nthreads() const +{ + return d_fft->nthreads(); +} + int gr_fft_vcc_fftw::work (int noutput_items, gr_vector_const_void_star &input_items, @@ -70,7 +87,7 @@ gr_fft_vcc_fftw::work (int noutput_items, if(!d_forward && d_shift){ int offset = (!d_forward && d_shift)?(d_fft_size/2):0; int fft_m_offset = d_fft_size - offset; - for (unsigned int i = 0; i < offset; i++) // apply window + for (int i = 0; i < offset; i++) // apply window dst[i+fft_m_offset] = in[i] * d_window[i]; for (unsigned int i = offset; i < d_fft_size; i++) // apply window dst[i-offset] = in[i] * d_window[i]; diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h index 8535d133c..82b7512d7 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h +++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h @@ -29,7 +29,9 @@ class gri_fft_complex; GR_CORE_API gr_fft_vcc_sptr -gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); +gr_make_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift=false, int nthreads=1); /*! * \brief Compute forward or reverse FFT. complex vector in / complex vector out. @@ -40,15 +42,22 @@ gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &wind class GR_CORE_API gr_fft_vcc_fftw : public gr_fft_vcc { friend GR_CORE_API gr_fft_vcc_sptr - gr_make_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_make_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads); gri_fft_complex *d_fft; - gr_fft_vcc_fftw (int fft_size, bool forward, const std::vector<float> &window, bool shift); + gr_fft_vcc_fftw (int fft_size, bool forward, + const std::vector<float> &window, + bool shift, int nthreads=1); public: ~gr_fft_vcc_fftw (); + void set_nthreads(int n); + int nthreads() const; + int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc index 0df1af25d..63e307776 100644 --- a/gnuradio-core/src/lib/general/gri_fft.cc +++ b/gnuradio-core/src/lib/general/gri_fft.cc @@ -78,6 +78,22 @@ gri_fftw_import_wisdom () } static void +gri_fftw_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(); + } + + fftwf_plan_with_nthreads(nthreads); +#endif +} + +static void gri_fftw_export_wisdom () { const char *filename = wisdom_filename (); @@ -94,7 +110,7 @@ gri_fftw_export_wisdom () // ---------------------------------------------------------------- -gri_fft_complex::gri_fft_complex (int fft_size, bool forward) +gri_fft_complex::gri_fft_complex (int fft_size, bool forward, int nthreads) { // Hold global mutex during plan construction and destruction. gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); @@ -115,7 +131,10 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward) throw std::runtime_error ("fftwf_malloc"); } + d_nthreads = nthreads; + gri_fftw_config_threading (nthreads); gri_fftw_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), @@ -139,6 +158,18 @@ gri_fft_complex::~gri_fft_complex () fftwf_free (d_outbuf); } +void +gri_fft_complex::set_nthreads(int n) +{ + if (n <= 0) + throw std::out_of_range ("gri_fftw: invalid number of threads"); + d_nthreads = n; + +#ifdef FFTW3F_THREADS + fftwf_plan_with_nthreads(d_nthreads); +#endif +} + void gri_fft_complex::execute () { @@ -147,7 +178,7 @@ gri_fft_complex::execute () // ---------------------------------------------------------------- -gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) +gri_fft_real_fwd::gri_fft_real_fwd (int fft_size, int nthreads) { // Hold global mutex during plan construction and destruction. gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); @@ -168,7 +199,10 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) throw std::runtime_error ("fftwf_malloc"); } + d_nthreads = nthreads; + gri_fftw_config_threading (nthreads); gri_fftw_import_wisdom (); // load prior wisdom from disk + d_plan = fftwf_plan_dft_r2c_1d (fft_size, d_inbuf, reinterpret_cast<fftwf_complex *>(d_outbuf), @@ -191,6 +225,18 @@ gri_fft_real_fwd::~gri_fft_real_fwd () fftwf_free (d_outbuf); } +void +gri_fft_real_fwd::set_nthreads(int n) +{ + if (n <= 0) + throw std::out_of_range ("gri_fftw: invalid number of threads"); + d_nthreads = n; + +#ifdef FFTW3F_THREADS + fftwf_plan_with_nthreads(d_nthreads); +#endif +} + void gri_fft_real_fwd::execute () { @@ -199,7 +245,7 @@ gri_fft_real_fwd::execute () // ---------------------------------------------------------------- -gri_fft_real_rev::gri_fft_real_rev (int fft_size) +gri_fft_real_rev::gri_fft_real_rev (int fft_size, int nthreads) { // Hold global mutex during plan construction and destruction. gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex()); @@ -220,11 +266,13 @@ gri_fft_real_rev::gri_fft_real_rev (int fft_size) throw std::runtime_error ("fftwf_malloc"); } + d_nthreads = nthreads; + gri_fftw_config_threading (nthreads); + gri_fftw_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. - - gri_fftw_import_wisdom (); // load prior wisdom from disk d_plan = fftwf_plan_dft_c2r_1d (fft_size, reinterpret_cast<fftwf_complex *>(d_inbuf), d_outbuf, @@ -244,6 +292,18 @@ gri_fft_real_rev::~gri_fft_real_rev () fftwf_free (d_outbuf); } +void +gri_fft_real_rev::set_nthreads(int n) +{ + if (n <= 0) + throw std::out_of_range ("gri_fftw: invalid number of threads"); + d_nthreads = n; + +#ifdef FFTW3F_THREADS + fftwf_plan_with_nthreads(d_nthreads); +#endif +} + void gri_fft_real_rev::execute () { diff --git a/gnuradio-core/src/lib/general/gri_fft.h b/gnuradio-core/src/lib/general/gri_fft.h index 91a82fb55..ed80badf1 100644 --- a/gnuradio-core/src/lib/general/gri_fft.h +++ b/gnuradio-core/src/lib/general/gri_fft.h @@ -49,12 +49,13 @@ public: */ class GR_CORE_API gri_fft_complex { int d_fft_size; + int d_nthreads; gr_complex *d_inbuf; gr_complex *d_outbuf; void *d_plan; public: - gri_fft_complex (int fft_size, bool forward = true); + gri_fft_complex (int fft_size, bool forward = true, int nthreads=1); virtual ~gri_fft_complex (); /* @@ -69,6 +70,16 @@ public: int outbuf_length () const { return d_fft_size; } /*! + * Set the number of threads to use for caclulation. + */ + void set_nthreads(int n); + + /*! + * Get the number of threads being used by FFTW + */ + int nthreads() const { return d_nthreads; } + + /*! * compute FFT. The input comes from inbuf, the output is placed in outbuf. */ void execute (); @@ -80,12 +91,13 @@ public: */ class GR_CORE_API gri_fft_real_fwd { int d_fft_size; + int d_nthreads; float *d_inbuf; gr_complex *d_outbuf; void *d_plan; public: - gri_fft_real_fwd (int fft_size); + gri_fft_real_fwd (int fft_size, int nthreads=1); virtual ~gri_fft_real_fwd (); /* @@ -100,6 +112,16 @@ public: int outbuf_length () const { return d_fft_size / 2 + 1; } /*! + * Set the number of threads to use for caclulation. + */ + void set_nthreads(int n); + + /*! + * Get the number of threads being used by FFTW + */ + int nthreads() const { return d_nthreads; } + + /*! * compute FFT. The input comes from inbuf, the output is placed in outbuf. */ void execute (); @@ -111,12 +133,13 @@ public: */ class GR_CORE_API gri_fft_real_rev { int d_fft_size; + int d_nthreads; gr_complex *d_inbuf; float *d_outbuf; void *d_plan; public: - gri_fft_real_rev (int fft_size); + gri_fft_real_rev (int fft_size, int nthreads=1); virtual ~gri_fft_real_rev (); /* @@ -131,6 +154,16 @@ public: int outbuf_length () const { return d_fft_size; } /*! + * Set the number of threads to use for caclulation. + */ + void set_nthreads(int n); + + /*! + * Get the number of threads being used by FFTW + */ + int nthreads() const { return d_nthreads; } + + /*! * compute FFT. The input comes from inbuf, the output is placed in outbuf. */ void execute (); |