casacore
FFTW.h
Go to the documentation of this file.
1 //# Copyright (C) 1993,1994,1995,1997,1999,2000,2001
2 //# Associated Universities, Inc. Washington DC, USA.
3 //#
4 //# This library is free software; you can redistribute it and/or modify it
5 //# under the terms of the GNU Library General Public License as published by
6 //# the Free Software Foundation; either version 2 of the License, or (at your
7 //# option) any later version.
8 //#
9 //# This library is distributed in the hope that it will be useful, but WITHOUT
10 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 //# License for more details.
13 //#
14 //# You should have received a copy of the GNU Library General Public License
15 //# along with this library; if not, write to the Free Software Foundation,
16 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
17 //#
18 //# Correspondence concerning AIPS++ should be addressed as follows:
19 //# Internet email: aips2-request@nrao.edu.
20 //# Postal address: AIPS++ Project Office
21 //# National Radio Astronomy Observatory
22 //# 520 Edgemont Road
23 //# Charlottesville, VA 22903-2475 USA
24 //#
25 
26 //# $Id$
27 
28 #ifndef SCIMATH_FFTW_H
29 #define SCIMATH_FFTW_H
30 
31 #include <casacore/casa/aips.h>
32 #include <casacore/casa/Arrays/IPosition.h>
33 
34 #include <complex>
35 #include <memory>
36 #include <mutex>
37 
38 namespace casacore {
39 
40 //# Forward Declarations.
41 class FFTWPlan;
42 class FFTWPlanf;
43 
44 // <summary> C++ interface to the FFTWw library </summary>
45 // <reviewed reviewer="NONE" date="" tests="" demos="">
46 // </reviewed>
47 // <synopsis>
48 // This is a wrapper of FFTW3.
49 // It is only active if FFTW3 was found during the build.
50 // If not found, all functions won't do anything at all.
51 //
52 // The interface is such that the presence of FFTW3 is only visible
53 // in the implementation. The header file does not need to know.
54 // In this way external code using this class does not need to set HAVE_FFTW.
55 // </synopsis>
56 
57 class FFTW
58 {
59 public:
60  FFTW() ;
61 
62  ~FFTW() ;
63 
64  // overloaded interface to fftw[f]_plan...
65  void plan_r2c(const IPosition &size, float *in, std::complex<float> *out) ;
66  void plan_r2c(const IPosition &size, double *in, std::complex<double> *out) ;
67  void plan_c2r(const IPosition &size, std::complex<float> *in, float *out) ;
68  void plan_c2r(const IPosition &size, std::complex<double> *in, double *out) ;
69  void plan_c2c_forward(const IPosition &size, std::complex<double> *in) ;
70  void plan_c2c_forward(const IPosition &size, std::complex<float> *in) ;
71  void plan_c2c_backward(const IPosition &size, std::complex<double> *in) ;
72  void plan_c2c_backward(const IPosition &size, std::complex<float> *in) ;
73 
74  // TODO These overloads do not use their parameters at all. This should
75  // be written to use an interface like plan_redft00().
76  // overloaded interface to fftw[f]_execute...
77  void r2c(const IPosition &size, float *in, std::complex<float> *out) ;
78  void r2c(const IPosition &size, double *in, std::complex<double> *out) ;
79  void c2r(const IPosition &size, std::complex<float> *in, float *out);
80  void c2r(const IPosition &size, std::complex<double> *in, double *out);
81  void c2c(const IPosition &size, std::complex<float> *in, bool forward);
82  void c2c(const IPosition &size, std::complex<double> *in, bool forward);
83 
84  class Plan
85  {
86  public:
87  ~Plan() noexcept;
88  Plan(const Plan&) = delete;
89  Plan(Plan&&);
90  Plan& operator=(const Plan&) = delete;
91  Plan& operator=(Plan&&);
92 
93  // Perform the FFT associated with this plan with the given
94  // in data, and store it in the given out data.
95  // <group>
96  void Execute(float* in, float* out);
97  void Execute(double* in, double* out);
98  // </group>
99  private:
100  friend FFTW;
101  Plan(FFTWPlan* plan);
102  Plan(FFTWPlanf* plan);
103  std::unique_ptr<FFTWPlan> _plan;
104  std::unique_ptr<FFTWPlanf> _planf;
105  };
106 
107  static Plan plan_redft00(const IPosition &size, float *in, float *out);
108  static Plan plan_redft00(const IPosition &size, double *in, double *out);
109 
110 private:
111  static void initialize_fftw();
112 
113  std::unique_ptr<FFTWPlanf> itsPlanR2Cf;
114  std::unique_ptr<FFTWPlan> itsPlanR2C;
115 
116  std::unique_ptr<FFTWPlanf> itsPlanC2Rf;
117  std::unique_ptr<FFTWPlan> itsPlanC2R;
118 
119  std::unique_ptr<FFTWPlanf> itsPlanC2CFf; // forward
120  std::unique_ptr<FFTWPlan> itsPlanC2CF;
121 
122  std::unique_ptr<FFTWPlanf> itsPlanC2CBf; // backward
123  std::unique_ptr<FFTWPlan> itsPlanC2CB;
124 
125  std::unique_ptr<FFTWPlanf> itsPlanR2Rf;
126  std::unique_ptr<FFTWPlan> itsPlanR2R;
127 
128  unsigned flags;
129 
130  static bool is_initialized_fftw; // FFTW needs initialization
131  // only once per process,
132  // not once per object
133 
134  // TODO this mutex does not make FFTW thread safe, because
135  // planning an FFT with FFTW is not thread safe either.
136  // So either the plan..() methods should take the mutex, or
137  // FFTW should leave synchronization fully to the user of
138  // this class: currently it's halfway in between.
139  static std::mutex theirMutex; // Initialization mutex
140 };
141 
142 } //# NAMESPACE CASACORE - END
143 
144 #endif
std::unique_ptr< FFTWPlan > _plan
Definition: FFTW.h:103
std::unique_ptr< FFTWPlanf > _planf
Definition: FFTW.h:104
void Execute(float *in, float *out)
Perform the FFT associated with this plan with the given in data, and store it in the given out data.
std::unique_ptr< FFTWPlan > itsPlanR2C
Definition: FFTW.h:114
void plan_c2r(const IPosition &size, std::complex< double > *in, double *out)
std::unique_ptr< FFTWPlanf > itsPlanC2CBf
Definition: FFTW.h:122
void plan_c2c_backward(const IPosition &size, std::complex< double > *in)
std::unique_ptr< FFTWPlanf > itsPlanR2Rf
Definition: FFTW.h:125
void plan_c2c_forward(const IPosition &size, std::complex< float > *in)
std::unique_ptr< FFTWPlan > itsPlanC2CB
Definition: FFTW.h:123
void r2c(const IPosition &size, double *in, std::complex< double > *out)
void c2c(const IPosition &size, std::complex< float > *in, bool forward)
void c2c(const IPosition &size, std::complex< double > *in, bool forward)
std::unique_ptr< FFTWPlan > itsPlanR2R
Definition: FFTW.h:126
void plan_r2c(const IPosition &size, float *in, std::complex< float > *out)
overloaded interface to fftw[f]_plan...
unsigned flags
Definition: FFTW.h:128
void plan_c2c_forward(const IPosition &size, std::complex< double > *in)
void r2c(const IPosition &size, float *in, std::complex< float > *out)
TODO These overloads do not use their parameters at all.
void plan_r2c(const IPosition &size, double *in, std::complex< double > *out)
std::unique_ptr< FFTWPlan > itsPlanC2R
Definition: FFTW.h:117
void plan_c2c_backward(const IPosition &size, std::complex< float > *in)
void plan_c2r(const IPosition &size, std::complex< float > *in, float *out)
std::unique_ptr< FFTWPlanf > itsPlanR2Cf
Definition: FFTW.h:113
static Plan plan_redft00(const IPosition &size, float *in, float *out)
static std::mutex theirMutex
only once per process, not once per object
Definition: FFTW.h:139
std::unique_ptr< FFTWPlan > itsPlanC2CF
Definition: FFTW.h:120
std::unique_ptr< FFTWPlanf > itsPlanC2Rf
Definition: FFTW.h:116
void c2r(const IPosition &size, std::complex< double > *in, double *out)
void c2r(const IPosition &size, std::complex< float > *in, float *out)
std::unique_ptr< FFTWPlanf > itsPlanC2CFf
Definition: FFTW.h:119
static void initialize_fftw()
static bool is_initialized_fftw
Definition: FFTW.h:130
this file contains all the compiler specific defines
Definition: mainpage.dox:28
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition: Complex.h:352