LCOV - code coverage report
Current view: top level - include/math/ft - fftwEnvironment.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 96.6 % 29 28
Test Date: 2026-08-30 22:23:37 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /** \file fftwEnvironment.hpp
       2              :  * \brief Declares and defines the fftwEnvironment manager
       3              :  * \ingroup ft_files
       4              :  * \author Jared R. Males (jaredmales@gmail.com)
       5              :  *
       6              :  */
       7              : 
       8              : //***********************************************************************//
       9              : // Copyright 2015-2015 Jared R. Males (jaredmales@gmail.com)
      10              : //
      11              : // This file is part of mxlib.
      12              : //
      13              : // mxlib is free software: you can redistribute it and/or modify
      14              : // it under the terms of the GNU General Public License as published by
      15              : // the Free Software Foundation, either version 3 of the License, or
      16              : // (at your option) any later version.
      17              : //
      18              : // mxlib is distributed in the hope that it will be useful,
      19              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      20              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21              : // GNU General Public License for more details.
      22              : //
      23              : // You should have received a copy of the GNU General Public License
      24              : // along with mxlib.  If not, see <http://www.gnu.org/licenses/>.
      25              : //***********************************************************************//
      26              : 
      27              : #ifndef fftwEnvironment_hpp
      28              : #define fftwEnvironment_hpp
      29              : 
      30              : #include <string>
      31              : 
      32              : #include "../../sys/environment.hpp"
      33              : 
      34              : #include "fftwTemplates.hpp"
      35              : 
      36              : namespace mx
      37              : {
      38              : namespace math
      39              : {
      40              : namespace ft
      41              : {
      42              : 
      43              : /** \addtogroup fftw_env
      44              : 
      45              : mxlib will manage the FFTW environment for you, which really means importing and exporting
      46              : wisdom and cleaning up memory.  This can be done in a simple way using
      47              : \ref mx::math::ft::fftwEnvironment.
      48              : To make the best use of this, create a directory to store FFTW wisdom.  The typical choice is
      49              : `$(HOME)/.fftw`
      50              : 
      51              : Then add the environment variable to your bash profile (i.e. in `.bash_profile` or `.bash_aliases`) as so
      52              : \verbatim
      53              : export MXFFTW_WISDOM=/path/to/.fftw
      54              : \endverbatim
      55              : 
      56              : Using this facility requires only that you create an object of type \ref mx::math::ft::fftwEnvironment
      57              : at the beginning of the program for the real floating point type you are using. E.g.:
      58              : \code
      59              : 
      60              :    #include <mx/fft/fftwEnvironment.hpp>
      61              : 
      62              :    int main()
      63              :    {
      64              :       typedef double realT;
      65              :       mx::math::ft::fftwEnvironment<realT> fftwEnv;
      66              : 
      67              :       //do stuff . . .
      68              : 
      69              :       return 0;
      70              :    }
      71              :    \endcode
      72              : 
      73              : See the documentation for \ref mx::math::ft::fftwEnvironment for details.
      74              : 
      75              : */
      76              : 
      77              : /// Return a string corresponding the fftw real floating point type.
      78              : /** This is used for wisdom filenames.
      79              :  *
      80              :  * \tparam realT the real floating point type.
      81              :  *
      82              :  * \ingroup fftw_env
      83              :  */
      84              : template <typename realT>
      85              : std::string fftw_typename();
      86              : 
      87              : template <>
      88              : std::string fftw_typename<float>();
      89              : 
      90              : template <>
      91              : std::string fftw_typename<double>();
      92              : 
      93              : template <>
      94              : std::string fftw_typename<long double>();
      95              : 
      96              : #ifdef HASQUAD
      97              : template <>
      98              : std::string fftw_typename<__float128>();
      99              : #endif
     100              : 
     101              : /// Create the mxlib standard wisdom filename for the type.
     102              : /** Looks for the environment variable MXFFTW_WISDOM.  If not found, then pwd "./" is used.
     103              :  *
     104              :  * \tparam realT is the real floating point type.
     105              :  *
     106              :  * \ingroup fftw_env
     107              :  */
     108              : template <typename realT>
     109           36 : std::string fftw_wisdom_filename()
     110              : {
     111           72 :     std::string path = sys::getEnv( "MXFFTW_WISDOM" );
     112           36 :     std::string sub = "fftw_wisdom.";
     113              : 
     114           36 :     if( path == "" )
     115              :     {
     116           18 :         path = ".";
     117           18 :         sub = ".fftw_wisdom.";
     118              :     }
     119              : 
     120           36 :     std::string filename = path + "/" + sub + fftw_typename<realT>();
     121              : 
     122           36 :     return filename;
     123           36 : }
     124              : 
     125              : /// Manage the FFTW environment and wisdom using RAII
     126              : /** This class manages the FFTW environment.  On construction, wisdom is imported from the
     127              :   * mxlib standard location, and if threads are used threading is initialized and planners are made thread safe.
     128              :   *
     129              :   * \note the fftw docs recommend against using fftw_make_planner_thread_safe.  It does seem to play poorly with omp.
     130              :   *
     131              :   * On destruction, wisdom is exported and the fftw_cleanup[_threads] function is called.
     132              :   *
     133              :   * Typically, an object of this type should be created in the main function.  Nothing else needs to be done with it,
     134              :   * as it will be destructed on program termination. Example:
     135              :    \code
     136              : 
     137              :    #include <mx/fft/fftwEnvironment.hpp>
     138              : 
     139              :    int main()
     140              :    {
     141              :       typedef double realT;
     142              :       mx::math::ft::fftwEnvironment<realT> fftwEnv;
     143              : 
     144              :       //do stuff . . .
     145              : 
     146              :       return 0;
     147              :    }
     148              :    \endcode
     149              :   * Note that there is no need to explicitly destroy the object fftwEnv.
     150              :   *
     151              :   * \ingroup fftw_env
     152              :   */
     153              : template <typename realT, bool threads = false>
     154              : struct fftwEnvironment
     155              : {
     156              :     /// Constructor
     157            6 :     explicit fftwEnvironment(unsigned nThreads = 0 /**< [in] [optional] the number of threads to use.  This can be changed any time by the program by calling \ref fftw_plan_with_nthreads() */)
     158              :     {
     159              :         static_cast<void>( nThreads );
     160            6 :         errno = 0;
     161            6 :         int rv = fftw_import_wisdom_from_filename<realT>( fftw_wisdom_filename<realT>().c_str() );
     162            6 :     }
     163              : 
     164              :     /// Destructor
     165            6 :     ~fftwEnvironment()
     166              :     {
     167            6 :         errno = 0;
     168            6 :         int rv = fftw_export_wisdom_to_filename<realT>( fftw_wisdom_filename<realT>().c_str() );
     169              : 
     170            6 :         fftw_cleanup<realT>();
     171            6 :     }
     172              : };
     173              : 
     174              : // Partial specialization for threads.
     175              : template <typename realT>
     176              : struct fftwEnvironment<realT, true>
     177              : {
     178              :     /// Constructor
     179            6 :     explicit fftwEnvironment(unsigned nThreads = 1 /**< [in] [optional] the number of threads to use.
     180              :                                                    This can be changed any time by the program by calling
     181              :                                                    \ref fftw_plan_with_nthreads() */)
     182              :     {
     183            6 :         fftw_make_planner_thread_safe<realT>();
     184              : 
     185            6 :         if( nThreads == 0 )
     186              :         {
     187            0 :             nThreads = 1; // Just to be safe, 1 disables threads but the fftw docs don't say what happens for 0.
     188              :         }
     189              : 
     190            6 :         fftw_plan_with_nthreads<realT>( nThreads );
     191              : 
     192            6 :         fftw_import_wisdom_from_filename<realT>( fftw_wisdom_filename<realT>().c_str() );
     193            6 :     }
     194              : 
     195              :     /// Destructor
     196            6 :     ~fftwEnvironment()
     197              :     {
     198            6 :         fftw_export_wisdom_to_filename<realT>( fftw_wisdom_filename<realT>().c_str() );
     199              : 
     200            6 :         fftw_cleanup_threads<realT>();
     201            6 :     }
     202              : };
     203              : 
     204              : } // namespace ft
     205              : } // namespace math
     206              : } // namespace mx
     207              : 
     208              : #endif // fftwEnvironment_hpp
        

Generated by: LCOV version 2.0-1