# HG changeset patch # User dbateman # Date 1168037397 0 # Node ID aa5df9ba98d5450664bd79a69ff7542508930782 # Parent 4c252a611d4768e533d445412f3be4e8e766762f [project @ 2007-01-05 22:49:03 by dbateman] diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,14 @@ +2007-01-05 David Bateman + + * oct-fftw.cc: (octave_fftw_planner::method (void), + octave_fftw_planner (FftwMethod)): New methods to interrogate and + set the FFTW wisdom method used. + (octave_fftw_planner::create_plan) Modify to allow different + methods to be used. + (octave_fftw_planner): Move class definition from here. + * oct-fftw.h (octave_fftw_planner): To here. Add method methods + and FftwMethod enum. + 2007-01-03 David Bateman * MSparse.cc (SPARSE_A2A2_OP, SPARSE_A2A2_FCN_1, diff --git a/liboctave/oct-fftw.cc b/liboctave/oct-fftw.cc --- a/liboctave/oct-fftw.cc +++ b/liboctave/oct-fftw.cc @@ -33,15 +33,16 @@ #include "quit.h" // Helper class to create and cache fftw plans for both 1d and -// 2d. This implementation uses FFTW_ESTIMATE to create the plans, -// which in theory is suboptimal, but provides quite reasonable -// performance. +// 2d. This implementation defaults to using FFTW_ESTIMATE to create +// the plans, which in theory is suboptimal, but provides quit +// reasonable performance. // Also note that if FFTW_ESTIMATE is not used the planner in FFTW3 -// destroys the input and output arrays. So with the form of the -// current code we definitely want FFTW_ESTIMATE!! However, we use any -// wsidom that is available, either in a FFTW3 system wide file or as -// supplied by the user. +// destroys the input and output arrays. We must therefore create a +// temporary input array with the same size and 16-byte alignment as +// the original array and use that for the planner. Note that we also +// use any wisdom that is available, either in a FFTW3 system wide file +// or as supplied by the user. // FIXME -- if we can ensure 16 byte alignment in Array // ( *data) the FFTW3 can use SIMD instructions for further @@ -50,72 +51,9 @@ // Note that it is profitable to store the FFTW3 plans, for small // ffts. -class -octave_fftw_planner -{ -public: - - octave_fftw_planner (void); - - fftw_plan create_plan (int dir, const int rank, const dim_vector dims, - octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, - const Complex *in, Complex *out); - - fftw_plan create_plan (const int rank, const dim_vector dims, - octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, - const double *in, Complex *out); - -private: - - int plan_flags; - - // FIXME -- perhaps this should be split into two classes? - - // Plan for fft and ifft of complex values - fftw_plan plan[2]; - - // dist - octave_idx_type d[2]; - - // stride - octave_idx_type s[2]; - - // rank - int r[2]; - - // howmany - octave_idx_type h[2]; - - // dims - dim_vector n[2]; - - bool simd_align[2]; - bool inplace[2]; - - // Plan for fft of real values - fftw_plan rplan; - - // dist - octave_idx_type rd; - - // stride - octave_idx_type rs; - - // rank - int rr; - - // howmany - octave_idx_type rh; - - // dims - dim_vector rn; - - bool rsimd_align; -}; - octave_fftw_planner::octave_fftw_planner (void) { - plan_flags = FFTW_ESTIMATE; + meth = ESTIMATE; plan[0] = plan[1] = 0; d[0] = d[1] = s[0] = s[1] = r[0] = r[1] = h[0] = h[1] = 0; @@ -132,6 +70,37 @@ fftw_import_system_wisdom (); } +octave_fftw_planner::FftwMethod +octave_fftw_planner::method (void) +{ + return meth; +} + +octave_fftw_planner::FftwMethod +octave_fftw_planner::method (FftwMethod _meth) +{ + FftwMethod ret = meth; + if (_meth == ESTIMATE || _meth == MEASURE || + _meth == PATIENT || _meth == EXHAUSTIVE || + _meth == HYBRID) + { + if (meth != _meth) + { + meth = _meth; + if (rplan) + fftw_destroy_plan (rplan); + if (plan[0]) + fftw_destroy_plan (plan[0]); + if (plan[1]) + fftw_destroy_plan (plan[1]); + rplan = plan[0] = plan[1] = 0; + } + } + else + ret = UNKNOWN; + return ret; +} + #define CHECK_SIMD_ALIGNMENT(x) \ ((reinterpret_cast (x)) & 0xF == 0) @@ -178,6 +147,46 @@ inplace[which] = ioinplace; n[which] = dims; + // Note reversal of dimensions for column major storage in FFTW. + octave_idx_type nn = 1; + OCTAVE_LOCAL_BUFFER (int, tmp, rank); + + for (int i = 0, j = rank-1; i < rank; i++, j--) + { + tmp[i] = dims(j); + nn *= dims(j); + } + + int plan_flags = 0; + bool plan_destroys_in = true; + + switch (meth) + { + case UNKNOWN: + case ESTIMATE: + plan_flags |= FFTW_ESTIMATE; + plan_destroys_in = false; + break; + case MEASURE: + plan_flags |= FFTW_MEASURE; + break; + case PATIENT: + plan_flags |= FFTW_PATIENT; + break; + case EXHAUSTIVE: + plan_flags |= FFTW_EXHAUSTIVE; + break; + case HYBRID: + if (nn < 8193) + plan_flags |= FFTW_MEASURE; + else + { + plan_flags |= FFTW_ESTIMATE; + plan_destroys_in = false; + } + break; + } + if (ioalign) plan_flags &= ~FFTW_UNALIGNED; else @@ -186,18 +195,28 @@ if (*cur_plan_p) fftw_destroy_plan (*cur_plan_p); - // Note reversal of dimensions for column major storage in FFTW. - - OCTAVE_LOCAL_BUFFER (int, tmp, rank); + if (plan_destroys_in) + { + // Create matrix with the same size and 16-byte alignment as input + OCTAVE_LOCAL_BUFFER (Complex, itmp, nn * howmany + 32); + itmp = reinterpret_cast + (((reinterpret_cast(itmp) + 15) & ~ 0xF) + + ((reinterpret_cast (in)) & 0xF)); - for (int i = 0, j = rank-1; i < rank; i++, j--) - tmp[i] = dims(j); - - *cur_plan_p = - fftw_plan_many_dft (rank, tmp, howmany, + *cur_plan_p = + fftw_plan_many_dft (rank, tmp, howmany, + reinterpret_cast (itmp), + 0, stride, dist, reinterpret_cast (out), + 0, stride, dist, dir, plan_flags); + } + else + { + *cur_plan_p = + fftw_plan_many_dft (rank, tmp, howmany, reinterpret_cast (const_cast (in)), 0, stride, dist, reinterpret_cast (out), 0, stride, dist, dir, plan_flags); + } if (*cur_plan_p == 0) (*current_liboctave_error_handler) ("Error creating fftw plan"); @@ -243,6 +262,46 @@ rsimd_align = ioalign; rn = dims; + // Note reversal of dimensions for column major storage in FFTW. + octave_idx_type nn = 1; + OCTAVE_LOCAL_BUFFER (int, tmp, rank); + + for (int i = 0, j = rank-1; i < rank; i++, j--) + { + tmp[i] = dims(j); + nn *= dims(j); + } + + int plan_flags = 0; + bool plan_destroys_in = true; + + switch (meth) + { + case UNKNOWN: + case ESTIMATE: + plan_flags |= FFTW_ESTIMATE; + plan_destroys_in = false; + break; + case MEASURE: + plan_flags |= FFTW_MEASURE; + break; + case PATIENT: + plan_flags |= FFTW_PATIENT; + break; + case EXHAUSTIVE: + plan_flags |= FFTW_EXHAUSTIVE; + break; + case HYBRID: + if (nn < 8193) + plan_flags |= FFTW_MEASURE; + else + { + plan_flags |= FFTW_ESTIMATE; + plan_destroys_in = false; + } + break; + } + if (ioalign) plan_flags &= ~FFTW_UNALIGNED; else @@ -251,18 +310,27 @@ if (*cur_plan_p) fftw_destroy_plan (*cur_plan_p); - // Note reversal of dimensions for column major storage in FFTW. - - OCTAVE_LOCAL_BUFFER (int, tmp, rank); + if (plan_destroys_in) + { + // Create matrix with the same size and 16-byte alignment as input + OCTAVE_LOCAL_BUFFER (double, itmp, nn + 32); + itmp = reinterpret_cast + (((reinterpret_cast(itmp) + 15) & ~ 0xF) + + ((reinterpret_cast (in)) & 0xF)); - for (int i = 0, j = rank-1; i < rank; i++, j--) - tmp[i] = dims(j); - - *cur_plan_p = - fftw_plan_many_dft_r2c (rank, tmp, howmany, + *cur_plan_p = + fftw_plan_many_dft_r2c (rank, tmp, howmany, itmp, + 0, stride, dist, reinterpret_cast (out), + 0, stride, dist, plan_flags); + } + else + { + *cur_plan_p = + fftw_plan_many_dft_r2c (rank, tmp, howmany, (const_cast (in)), 0, stride, dist, reinterpret_cast (out), 0, stride, dist, plan_flags); + } if (*cur_plan_p == 0) (*current_liboctave_error_handler) ("Error creating fftw plan"); @@ -271,7 +339,7 @@ return *cur_plan_p; } -static octave_fftw_planner fftw_planner; +octave_fftw_planner fftw_planner; static inline void convert_packcomplex_1d (Complex *out, size_t nr, size_t nc, diff --git a/liboctave/oct-fftw.h b/liboctave/oct-fftw.h --- a/liboctave/oct-fftw.h +++ b/liboctave/oct-fftw.h @@ -29,6 +29,82 @@ #include "dim-vector.h" class +octave_fftw_planner +{ +public: + + octave_fftw_planner (void); + + fftw_plan create_plan (int dir, const int rank, const dim_vector dims, + octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, + const Complex *in, Complex *out); + + fftw_plan create_plan (const int rank, const dim_vector dims, + octave_idx_type howmany, octave_idx_type stride, octave_idx_type dist, + const double *in, Complex *out); + + enum FftwMethod { + UNKNOWN = -1, + ESTIMATE, + MEASURE, + PATIENT, + EXHAUSTIVE, + HYBRID + }; + + FftwMethod method (void); + + FftwMethod method (FftwMethod _meth); + +private: + + FftwMethod meth; + + // FIXME -- perhaps this should be split into two classes? + + // Plan for fft and ifft of complex values + fftw_plan plan[2]; + + // dist + octave_idx_type d[2]; + + // stride + octave_idx_type s[2]; + + // rank + int r[2]; + + // howmany + octave_idx_type h[2]; + + // dims + dim_vector n[2]; + + bool simd_align[2]; + bool inplace[2]; + + // Plan for fft of real values + fftw_plan rplan; + + // dist + octave_idx_type rd; + + // stride + octave_idx_type rs; + + // rank + int rr; + + // howmany + octave_idx_type rh; + + // dims + dim_vector rn; + + bool rsimd_align; +}; + +class octave_fftw { public: diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2007-01-05 David Bateman + + * Makefile.in (DLD_XSRC): Add fftw.cc and remove fftw_wisdom.cc + * DLD-FUNCTIONS/fftw.cc: New file. + * DLD-FUNCTIONS/fftw_wisdom.cc: Delete. + * defaults.cc (Vfftw_wisdom_program): Delete variable. + (set_default_fftw_wisdom_prog): Delete function that sets it. + (install_defaults): Delete set_default_fftw_prog from defaults. + (Ffftw_wisdom_program): Delete. + 2007-01-04 David Bateman * ov-fcn-handle.cc (octave_fcn_handle::load_ascii, diff --git a/src/DLD-FUNCTIONS/fftw.cc b/src/DLD-FUNCTIONS/fftw.cc new file mode 100644 --- /dev/null +++ b/src/DLD-FUNCTIONS/fftw.cc @@ -0,0 +1,240 @@ +/* + +Copyright (C) 2006 David Bateman + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "ov.h" +#include "defun-dld.h" +#include "error.h" + +#if defined (HAVE_FFTW3) +#include "oct-fftw.h" +#endif + +extern octave_fftw_planner fftw_planner; + +DEFUN_DLD (fftw, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{method} =} fftw ('planner')\n\ +@deftypefnx {Loadable Function} {} fftw ('planner', @var{method})\n\ +@deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom')\n\ +@deftypefnx {Loadable Function} {@var{wisdom} =} fftw ('dwisdom', @var{wisdom})\n\ +\n\ +Manage FFTW wisdom data. Wisdom data can be used to significantly\n\ +accelerate the calculation of the FFTs but implies a initial cost\n\ +in its calculation. The wisdom used by Octave can be imported directly,\n\ +usually from a file /etc/fftw/wisdom, or @dfn{fftw} can be used\n\ +to import wisdom. For example\n\ +\n\ +@example\n\ +@var{wisdom} = fftw ('dwisdom')\n\ +@end example\n\ +\n\ +will save the existing wisdom used by Octave to the string @var{wisdom}.\n\ +This string can then be saved in the usual manner. This existing wisdom\n\ +can be reimported as follows\n\ +\n\ +@example\n\ +fftw ('dwisdom', @var{wisdom})\n\ +@end example \n\ +\n\ +If @var{wisdom} is an empty matrix, then the wisdom used is cleared.\n\ +\n\ +During the calculation of fourier transforms further wisdom is generated.\n\ +The fashion in which this wisdom is generated is equally controlled by\n\ +the @dfn{fftw} function. There are five different manners in which the\n\ +wisdom can be treated, these being\n\ +\n\ +@table @asis\n\ +@item 'estimate'\n\ +This specifies that no run-time measurement of the optimal means of\n\ +calculating a particular is performed, and a simple heuristic is used\n\ +to pick a (probably sub-optimal) plan. The advantage of this method is\n\ +that there is little or no overhead in the generation of the plan, which\n\ +is appropriate for a fourier transform that will be calculated once.\n\ +\n\ +@item 'measure'\n\ +In this case a range of algorithms to perform the transform is considered\n\ +and the best is selected based on their execution time.\n\ +\n\ +@item 'patient'\n\ +This is like 'measure', but a wider range of algorithms is considered.\n\ +\n\ +@item 'exhasutive'\n\ +This is like 'meaure', but all possible algorithms that may be used to\n\ +treat the transform are considered.\n\ +\n\ +@item 'hybrid'\n\ +As run-time measurement of the algorithm can be expensive, this is a\n\ +compromise where 'measure' is used for transforms upto the size of 8192\n\ +and beyond that the 'estimate' method is used.\n\ +@end table\n\ +\n\ +The default method is 'estimate', and the method currently being used can\n\ +be probed with\n\ +\n\ +@example\n\ +@var{method} = fftw ('planner')\n\ +@end example\n\ +\n\ +and the method used can be set using\n\ +\n\ +@example\n\ +fftw ('planner', @var{method})\n\ +@end example\n\ +\n\ +Note that calculated wisdom will be lost when restarting Octave. However,\n\ +the wisdom data can be reloaded if it is saved to a file as described\n\ +above. Also, any system-wide wisdom file that has been found will\n\ +also be used. Saved wisdom files should not be used on different\n\ +platforms since they will not be efficient and the point of calculating\n\ +the wisdom is lost.\n\ +@seealso{fft, ifft, fft2, ifft2, fftn, ifftn}\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length(); + + if (nargin < 1 || nargin > 2) + { + print_usage (); + return retval; + } + +#if defined (HAVE_FFTW3) + if (args(0).is_string ()) + { + std::string arg0 = args(0).string_value (); + + if (!error_state) + { + // Use STL function to convert to lower case + std::transform (arg0.begin (), arg0.end (), arg0.begin (), tolower); + + if (nargin == 2) + { + std::string arg1 = args(1).string_value (); + if (!error_state) + { + if (arg0 == "planner") + { + std::transform (arg1.begin (), arg1.end (), + arg1.begin (), tolower); + octave_fftw_planner::FftwMethod meth; + + if (arg1 == "estimate") + meth = fftw_planner.method + (octave_fftw_planner::ESTIMATE); + else if (arg1 == "measure") + meth = fftw_planner.method + (octave_fftw_planner::MEASURE); + else if (arg1 == "patient") + meth = fftw_planner.method + (octave_fftw_planner::PATIENT); + else if (arg1 == "exhaustive") + meth = fftw_planner.method + (octave_fftw_planner::EXHAUSTIVE); + else if (arg1 == "hybrid") + meth = fftw_planner.method + (octave_fftw_planner::HYBRID); + else + error ("unrecognized planner method"); + + if (!error_state) + { + if (meth == octave_fftw_planner::MEASURE) + retval = octave_value ("measure"); + else if (meth == octave_fftw_planner::PATIENT) + retval = octave_value ("patient"); + else if (meth == octave_fftw_planner::EXHAUSTIVE) + retval = octave_value ("exhaustive"); + else if (meth == octave_fftw_planner::HYBRID) + retval = octave_value ("hybrid"); + else + retval = octave_value ("estimate"); + } + } + else if (arg0 == "dwisdom") + { + char *str = fftw_export_wisdom_to_string (); + + if (arg1.length() < 1) + fftw_forget_wisdom (); + else if (! fftw_import_wisdom_from_string (arg1.c_str())) + error ("could not import supplied wisdom"); + + if (!error_state) + retval = octave_value (std::string (str)); + + free (str); + } + else if (arg0 == "swisdom") + error ("single precision wisdom is not supported"); + else + error ("unrecognized argument"); + } + } + else + { + if (arg0 == "planner") + { + octave_fftw_planner::FftwMethod meth = + fftw_planner.method (); + + if (meth == octave_fftw_planner::MEASURE) + retval = octave_value ("measure"); + else if (meth == octave_fftw_planner::PATIENT) + retval = octave_value ("patient"); + else if (meth == octave_fftw_planner::EXHAUSTIVE) + retval = octave_value ("exhaustive"); + else if (meth == octave_fftw_planner::HYBRID) + retval = octave_value ("hybrid"); + else + retval = octave_value ("estimate"); + } + else if (arg0 == "dwisdom") + { + char *str = fftw_export_wisdom_to_string (); + retval = octave_value (std::string (str)); + free (str); + } + else if (arg0 == "swisdom") + error ("single precision wisdom is not supported"); + else + error ("unrecognized argument"); + } + } + } +#else + + warning ("fftw: this copy of Octave was not configured to use FFTW3"); + +#endif + + return retval; +} + diff --git a/src/DLD-FUNCTIONS/fftw_wisdom.cc b/src/DLD-FUNCTIONS/fftw_wisdom.cc deleted file mode 100644 --- a/src/DLD-FUNCTIONS/fftw_wisdom.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* - -Copyright (C) 2004 David Bateman - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#if defined (HAVE_FFTW3) -#include -#endif - -#include - -#include "file-stat.h" - -#include "defaults.h" -#include "defun-dld.h" -#include "error.h" -#include "file-ops.h" -#include "gripes.h" -#include "lo-mappers.h" -#include "load-path.h" -#include "oct-env.h" -#include "oct-obj.h" -#include "sighandlers.h" -#include "utils.h" - -DEFUN_DLD (fftw_wisdom, args, , - "-*- texinfo -*-\n\ -@deftypefn {Loadable Function} {} fftw_wisdom (@var{file}, @var{mode})\n\ -Save or load FFTW wisdom data to @var{file}. The optional argument\n\ -@var{mode} may be either @samp{\"r\"} or @samp{\"w\"}. The default\n\ -value is @samp{\"r\"}.\n\ -\n\ -@deftypefnx {Loadable Function} {} fftw_wisdom (@var{n})\n\ -Pre-calculate FFTW wisdom data for an FFT of size @var{n}.\n\ -Each row of @var{n} represents the size of an FFT for\n\ -which it is desired to pre-calculate the wisdom needed to accelerate it.\n\ -Any value of the matrix that is less than 1, is assumed to indicate an\n\ -absent dimension. For example,\n\ -\n\ -@example\n\ -fftw_wisdom ([102, 0, 0; 103, 103, 0; 102, 103, 105]);\n\ -a = fft (rand (1,102));\n\ -b = fft (rand (103,103));\n\ -c = fftn (rand ([102, 103, 105]));\n\ -@end example\n\ -\n\ -calculates the wisdom necessary to accelerate the 103, 102x102 and\n\ -the 102x103x105 FFTs. Note that calculated wisdom will be lost when\n\ -restarting Octave. However, the wisdom data can be reloaded if it is\n\ -saved to a file as described above. Also, any system-wide wisdom\n\ -file that has been found will also be used. Saved wisdom files\n\ -should not be used on different platforms since they will not be\n\ -efficient and the point of calculating the wisdom is lost.\n\ -\n\ -Wisdom data can be used to significantly accelerate the calculation\n\ -of the FFTs but is only profitable if the same FFT is called many\n\ -times due to the overhead in calculating the wisdom data.\n\ -\n\ -Note that the program @code{fftw-wisdom} supplied with FFTW can equally\n\ -be used to create a file containing wisdom that can be imported into\n\ -Octave.\n\ -@seealso{fft, ifft, fft2, ifft2, fftn, ifftn}\n\ -@end deftypefn") -{ - octave_value retval; - - int nargin = args.length(); - - if (nargin < 1 || nargin > 2) - { - print_usage (); - return retval; - } - -#if defined (HAVE_FFTW3) - - if (args(0).is_string ()) - { - bool write_wisdom = false; - - if (nargin == 2) - { - std::string mode = args(1).string_value (); - - if (! error_state && (mode == "r" || mode == "w")) - write_wisdom = mode == "w"; - else - { - error ("fftw_wisdom: expecting second argument to be \"r\" or \"w\""); - return retval; - } - } - - std::string name = args(0).string_value (); - - std::string wisdom = file_ops::tilde_expand (name); - - if (! (write_wisdom || octave_env::absolute_pathname (wisdom))) - { - file_stat fs (wisdom); - - if (! fs.exists ()) - { - std::string tmp = octave_env::make_absolute - (load_path::find_file (wisdom), octave_env::getcwd ()); - - if (! tmp.empty ()) - { - warning_with_id ("Octave:fftw-wisdom-file-in-path", - "fftw_wisdom: file found in load path"); - wisdom = tmp; - } - } - } - - if (write_wisdom) - { - FILE *ofile = fopen (wisdom.c_str (), "wb"); - - if (! ofile) - error ("fftw_wisdom: unable to open file `%s' for writing", - wisdom.c_str()); - else - { - fftw_export_wisdom_to_file (ofile); - fclose (ofile); - } - } - else - { - FILE *ifile = fopen (wisdom.c_str (), "r"); - - if (! ifile) - error ("fftw_wisdom: unable to open file `%s' for reading", - wisdom.c_str ()); - else - { - if (! fftw_import_wisdom_from_file (ifile)) - error ("fftw_wisdom: can not import wisdom from file"); - - fclose (ifile); - } - } - } - else - { - Matrix m = args (0).matrix_value (); - - if (error_state) - { - error ("fftw_wisdom: argument must be a matrix or a string"); - return retval; - } - - std::string name = file_ops::tempnam ("", "oct-"); - - if (name.empty ()) - { - error ("fftw_wisdom: can not open temporary file"); - return retval; - } - - std::ostringstream cmd_buf; - cmd_buf << Vfftw_wisdom_program << " -n -o \"" << name << "\""; - - for (octave_idx_type k = 0; k < m.rows (); k++) - { - bool first = true; - - cmd_buf << " "; - - // Note reversal of dimensions for column major storage in FFTW - for (octave_idx_type j = m.columns()-1; j >= 0; j--) - if (NINTbig(m(k,j)) > 0) - { - if (first) - first = false; - else - cmd_buf << "x"; - cmd_buf << NINTbig(m(k,j)) ; - } - } - - volatile octave_interrupt_handler old_interrupt_handler - = octave_ignore_interrupts (); - - std::string cmd_buf_str = cmd_buf.str (); - - int status = system (cmd_buf_str.c_str ()); - - octave_set_interrupt_handler (old_interrupt_handler); - - if (WIFEXITED (status)) - { - FILE *ifile = fopen (name.c_str (), "r"); - if (! fftw_import_wisdom_from_file (ifile)) - error ("fftw_wisdom: can not import wisdom from temporary file"); - fclose (ifile); - } - else - error ("fftw_wisdom: error running %s", Vfftw_wisdom_program.c_str ()); - } - -#else - - warning ("fftw_wisdom: this copy of Octave was not configured to use FFTW3"); - -#endif - - return retval; -} diff --git a/src/Makefile.in b/src/Makefile.in --- a/src/Makefile.in +++ b/src/Makefile.in @@ -50,7 +50,7 @@ DLD_XSRC := balance.cc besselj.cc betainc.cc cellfun.cc chol.cc \ ccolamd.cc colamd.cc colloc.cc conv2.cc daspk.cc dasrt.cc \ dassl.cc det.cc dispatch.cc eig.cc expm.cc fft.cc fft2.cc \ - fftn.cc fftw_wisdom.cc filter.cc find.cc fsolve.cc \ + fftn.cc fftw.cc fftw_wisdom.cc filter.cc find.cc fsolve.cc \ gammainc.cc gcd.cc getgrent.cc getpwent.cc getrusage.cc \ givens.cc hess.cc inv.cc kron.cc lpsolve.cc lsode.cc \ lu.cc luinc.cc matrix_type.cc minmax.cc pinv.cc qr.cc \ diff --git a/src/defaults.cc b/src/defaults.cc --- a/src/defaults.cc +++ b/src/defaults.cc @@ -96,9 +96,6 @@ std::string Vlocal_site_defaults_file; std::string Vsite_defaults_file; -// Name of the FFTW wisdom program. -std::string Vfftw_wisdom_program; - static std::string subst_octave_home (const std::string& s) { @@ -304,17 +301,6 @@ } static void -set_default_fftw_wisdom_prog (void) -{ - std::string oct_wisdom_prog = octave_env::getenv ("OCTAVE_FFTW_WISDOM_PROGRAM"); - - if (oct_wisdom_prog.empty ()) - Vfftw_wisdom_program = "fftw-wisdom"; - else - Vfftw_wisdom_program = std::string (oct_wisdom_prog); -} - -static void set_default_editor (void) { VEDITOR = "emacs"; @@ -395,8 +381,6 @@ set_default_info_prog (); - set_default_fftw_wisdom_prog (); - set_default_editor (); set_local_site_defaults_file (); @@ -445,20 +429,6 @@ return retval; } -DEFUN (fftw_wisdom_program, args, nargout, - "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {@var{val} =} FFTW_WISDOM_PROGRAM ()\n\ -@deftypefnx {Built-in Function} {@var{old_val} =} FFTW_WISDOM_PROGRAM (@var{new_val})\n\ -Query or set the internal variable that specifies the FFTW wisdom\n\ -program to use to create wisdom data to accelerate Fourier transforms.\n\ -If the environment variable @code{OCTAVE_WISDOM_PROGRAM} is set when\n\ -Octave starts, its value is used as the default. Otherwise,\n\ -@code{WISDOM_PROGRAM} is set to @code{\"fftw-wisdom\"}.\n\ -@end deftypefn") -{ - return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (fftw_wisdom_program); -} - DEFUN (IMAGE_PATH, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} IMAGE_PATH ()\n\