mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fftwEnvironment.hpp
Go to the documentation of this file.
1 /** \file fftwEnvironment.hpp
2  * \brief Declares and defines the fftwEnvironment manager
3  * \ingroup fft_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 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 
35 #include "fftwTemplates.hpp"
36 
37 namespace mx
38 {
39 namespace math
40 {
41 namespace fft
42 {
43 
44 ///Return a string corresponding the fftw real floating point type.
45 /** This is used for wisdom filenames.
46  *
47  * \tparam realT the real floating point type.
48  *
49  * \ingroup fft
50  */
51 template<typename realT>
52 std::string fftw_typename();
53 
54 template<>
55 std::string fftw_typename<float>();
56 
57 template<>
58 std::string fftw_typename<double>();
59 
60 template<>
61 std::string fftw_typename<long double>();
62 
63 #ifdef HASQUAD
64 template<>
65 std::string fftw_typename<__float128>();
66 #endif
67 
68 ///Create the mxlib standard wisdom filename for the type.
69 /** Looks for the environment variable MXFFTW_WISDOM. If not found, then pwd "./" is used.
70  *
71  * \tparam realT is the real floating point type.
72  *
73  * \ingroup fft
74  */
75 template<typename realT>
76 std::string fftw_wisdom_filename()
77 {
78  std::string path = sys::getEnv("MXFFTW_WISDOM");
79  std::string sub = "fftw_wisdom.";
80 
81  if(path == "")
82  {
83  path = ".";
84  sub = ".fftw_wisdom.";
85  }
86 
87  std::string filename = path + "/" + sub + fftw_typename<realT>();
88 
89  return filename;
90 }
91 
92 /// Manage the FFTW environment and wisdom using RAII
93 /** This class manages the FFTW environment. On construction, wisdom is imported from the
94  * mxlib standard location, and if threads are used threading is initialized and planners are made thread safe.
95  *
96  * \note the fftw docs recommend against using fftw_make_planner_thread_safe. It does seem to play poorly with omp.
97  *
98  * On destruction, wisdom is exported and the fftw_cleanup[_threads] function is called.
99  *
100  * Typically, an object of this type should be created in the main function. Nothing else needs to be done with it,
101  * as it will be destructed on program termination. Example:
102  \code
103 
104  #include <mx/fft/fftwEnvironment.hpp>
105 
106  int main()
107  {
108  typedef double realT;
109  mx::fftwEnvironment<realT> fftwEnv;
110 
111  //do stuff . . .
112 
113  return 0;
114  }
115  \endcode
116  * Note that there is no need to explicitly destroy the object fftwEnv.
117  *
118  * \ingroup fft
119  */
120 template< typename realT, bool threads=false>
122 {
123  /// Constructor
124  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() */)
125  {
126  static_cast<void>(nThreads);
127  errno = 0;
128  int rv = fftw_import_wisdom_from_filename<realT>(fftw_wisdom_filename<realT>().c_str());
129 
130  }
131 
132  /// Destructor
134  {
135  errno = 0;
136  int rv = fftw_export_wisdom_to_filename<realT>(fftw_wisdom_filename<realT>().c_str());
137 
138  fftw_cleanup<realT>();
139  }
140 };
141 
142 
143 
144 //Partial specialization for threads.
145 template< typename realT>
146 struct fftwEnvironment<realT, true>
147 {
148  /// Constructor
149  explicit fftwEnvironment(unsigned nThreads = 1 /**< [in] [optional] the number of threads to use. This can be changed any time by the program by calling \ref fftw_plan_with_nthreads() */)
150  {
151  fftw_make_planner_thread_safe<realT>();
152 
153  if(nThreads == 0) nThreads = 1; //Just to be safe, 1 disables threads but the fftw docs don't say what happens for 0.
154  fftw_plan_with_nthreads<realT>(nThreads);
155 
156  fftw_import_wisdom_from_filename<realT>(fftw_wisdom_filename<realT>().c_str());
157  }
158 
159  /// Destructor
161  {
162  fftw_export_wisdom_to_filename<realT>(fftw_wisdom_filename<realT>().c_str());
163 
164  fftw_cleanup_threads<realT>();
165  }
166 };
167 
168 }//namespace fft
169 }//namespace math
170 }//namespace mx
171 
172 #endif // fftwEnvironment_hpp
173 
Declares and defines templatized wrappers for the fftw library.
std::string fftw_wisdom_filename()
Create the mxlib standard wisdom filename for the type.
std::string fftw_typename()
Return a string corresponding the fftw real floating point type.
std::string getEnv(const std::string &estr)
Return the value of an environment variable.
Definition: environment.cpp:33
The mxlib c++ namespace.
Definition: mxError.hpp:107
Manage the FFTW environment and wisdom using RAII.
fftwEnvironment(unsigned nThreads=0)
Constructor.