changeset 32369:e0a6dd4f6fef

maint: Merge stable to default.
author Markus Mützel <markus.muetzel@gmx.de>
date Tue, 03 Oct 2023 14:45:22 +0200
parents aeed7db02016 (current diff) 903c9100178b (diff)
children 9155a67023bc
files liboctave/numeric/oct-fftw.cc
diffstat 3 files changed, 103 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/fft.cc	Mon Oct 02 15:00:35 2023 +0200
+++ b/libinterp/corefcn/fft.cc	Tue Oct 03 14:45:22 2023 +0200
@@ -334,6 +334,22 @@
 %! unwind_protect_cleanup
 %!   fftw ('planner', old_planner);
 %! end_unwind_protect
+
+%!testif HAVE_FFTW <*64733>
+%! old_planner = fftw ('planner', 'measure');
+%! unwind_protect
+%!   assert (ifft ([2, 4, 6, 8]), [5, -1-1i, -1, -1+1i]);
+%! unwind_protect_cleanup
+%!   fftw ('planner', old_planner);
+%! end_unwind_protect
+
+%!testif HAVE_FFTW <*64733>
+%! old_planner = fftw ('planner', 'measure');
+%! unwind_protect
+%!   assert (ifft (single ([2, 4, 6, 8])), single ([5, -1-1i, -1, -1+1i]));
+%! unwind_protect_cleanup
+%!   fftw ('planner', old_planner);
+%! end_unwind_protect
 */
 
 OCTAVE_END_NAMESPACE(octave)
--- a/liboctave/numeric/oct-fftw.cc	Mon Oct 02 15:00:35 2023 +0200
+++ b/liboctave/numeric/oct-fftw.cc	Tue Oct 03 14:45:22 2023 +0200
@@ -244,30 +244,28 @@
       if (*cur_plan_p)
         fftw_destroy_plan (*cur_plan_p);
 
+      OCTAVE_SCOPED_BUFFER_ANCHOR (Complex, itmp);
+      itmp = const_cast<Complex *> (in);
+      Complex *otmp = out;
+
       if (plan_destroys_in)
         {
           // Create matrix with the same size and 16-byte alignment as input
-          OCTAVE_LOCAL_BUFFER (Complex, itmp, nn * howmany + 32);
+          OCTAVE_SCOPED_BUFFER (Complex, itmp, nn * howmany + 32);
           itmp = reinterpret_cast<Complex *>
-                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF) +
-                  ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
+                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF)
+                  + ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
 
-          *cur_plan_p
-            = fftw_plan_many_dft (rank, tmp, howmany,
-                                  reinterpret_cast<fftw_complex *> (itmp),
-                                  nullptr, stride, dist,
-                                  reinterpret_cast<fftw_complex *> (out),
-                                  nullptr, stride, dist, dir, plan_flags);
+          if (in == out)
+            otmp = itmp;
         }
-      else
-        {
-          *cur_plan_p
-            = fftw_plan_many_dft (rank, tmp, howmany,
-                                  reinterpret_cast<fftw_complex *> (const_cast<Complex *> (in)),
-                                  nullptr, stride, dist,
-                                  reinterpret_cast<fftw_complex *> (out),
-                                  nullptr, stride, dist, dir, plan_flags);
-        }
+
+      *cur_plan_p
+        = fftw_plan_many_dft (rank, tmp, howmany,
+                              reinterpret_cast<fftw_complex *> (itmp),
+                              nullptr, stride, dist,
+                              reinterpret_cast<fftw_complex *> (otmp),
+                              nullptr, stride, dist, dir, plan_flags);
 
       if (*cur_plan_p == nullptr)
         (*current_liboctave_error_handler) ("Error creating FFTW plan");
@@ -363,29 +361,29 @@
       if (*cur_plan_p)
         fftw_destroy_plan (*cur_plan_p);
 
+      OCTAVE_SCOPED_BUFFER_ANCHOR (double, itmp);
+      itmp = const_cast<double *> (in);
+      Complex *otmp = out;
+
       if (plan_destroys_in)
         {
           // Create matrix with the same size and 16-byte alignment as input
-          OCTAVE_LOCAL_BUFFER (double, itmp, nn * howmany + 32);
+          octave_idx_type in_place = reinterpret_cast<double *> (out) == in;
+          OCTAVE_SCOPED_BUFFER (double, itmp,
+                                nn * howmany * (in_place + 1) + 32);
           itmp = reinterpret_cast<double *>
-                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF) +
-                  ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
+                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF)
+                  + ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
 
-          *cur_plan_p
-            = fftw_plan_many_dft_r2c (rank, tmp, howmany, itmp,
-                                      nullptr, stride, dist,
-                                      reinterpret_cast<fftw_complex *> (out),
-                                      nullptr, stride, dist, plan_flags);
+          if (in_place)
+            otmp = reinterpret_cast<Complex *> (itmp);
         }
-      else
-        {
-          *cur_plan_p
-            = fftw_plan_many_dft_r2c (rank, tmp, howmany,
-                                      (const_cast<double *> (in)),
-                                      nullptr, stride, dist,
-                                      reinterpret_cast<fftw_complex *> (out),
-                                      nullptr, stride, dist, plan_flags);
-        }
+
+      *cur_plan_p
+        = fftw_plan_many_dft_r2c (rank, tmp, howmany, itmp,
+                                  nullptr, stride, dist,
+                                  reinterpret_cast<fftw_complex *> (otmp),
+                                  nullptr, stride, dist, plan_flags);
 
       if (*cur_plan_p == nullptr)
         (*current_liboctave_error_handler) ("Error creating FFTW plan");
@@ -599,30 +597,28 @@
       if (*cur_plan_p)
         fftwf_destroy_plan (*cur_plan_p);
 
+      OCTAVE_SCOPED_BUFFER_ANCHOR (FloatComplex, itmp);
+      itmp = const_cast<FloatComplex *> (in);
+      FloatComplex *otmp = out;
+
       if (plan_destroys_in)
         {
           // Create matrix with the same size and 16-byte alignment as input
-          OCTAVE_LOCAL_BUFFER (FloatComplex, itmp, nn * howmany + 32);
+          OCTAVE_SCOPED_BUFFER (FloatComplex, itmp, nn * howmany + 32);
           itmp = reinterpret_cast<FloatComplex *>
-                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF) +
-                  ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
+                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF)
+                  + ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
 
-          *cur_plan_p
-            = fftwf_plan_many_dft (rank, tmp, howmany,
-                                   reinterpret_cast<fftwf_complex *> (itmp),
-                                   nullptr, stride, dist,
-                                   reinterpret_cast<fftwf_complex *> (out),
-                                   nullptr, stride, dist, dir, plan_flags);
+          if (out == in)
+            otmp = itmp;
         }
-      else
-        {
-          *cur_plan_p
-            = fftwf_plan_many_dft (rank, tmp, howmany,
-                                   reinterpret_cast<fftwf_complex *> (const_cast<FloatComplex *> (in)),
-                                   nullptr, stride, dist,
-                                   reinterpret_cast<fftwf_complex *> (out),
-                                   nullptr, stride, dist, dir, plan_flags);
-        }
+
+      *cur_plan_p
+        = fftwf_plan_many_dft (rank, tmp, howmany,
+                               reinterpret_cast<fftwf_complex *> (itmp),
+                               nullptr, stride, dist,
+                               reinterpret_cast<fftwf_complex *> (otmp),
+                               nullptr, stride, dist, dir, plan_flags);
 
       if (*cur_plan_p == nullptr)
         (*current_liboctave_error_handler) ("Error creating FFTW plan");
@@ -718,29 +714,29 @@
       if (*cur_plan_p)
         fftwf_destroy_plan (*cur_plan_p);
 
+      OCTAVE_SCOPED_BUFFER_ANCHOR (float, itmp);
+      itmp = const_cast<float *> (in);
+      FloatComplex *otmp = out;
+
       if (plan_destroys_in)
         {
           // Create matrix with the same size and 16-byte alignment as input
-          OCTAVE_LOCAL_BUFFER (float, itmp, nn * howmany + 32);
+          octave_idx_type in_place = reinterpret_cast<float *> (out) == in;
+          OCTAVE_SCOPED_BUFFER (float, itmp,
+                                nn * howmany * (in_place + 1) + 32);
           itmp = reinterpret_cast<float *>
-                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF) +
-                  ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
+                 (((reinterpret_cast<std::ptrdiff_t> (itmp) + 15) & ~ 0xF)
+                  + ((reinterpret_cast<std::ptrdiff_t> (in)) & 0xF));
 
-          *cur_plan_p
-            = fftwf_plan_many_dft_r2c (rank, tmp, howmany, itmp,
-                                       nullptr, stride, dist,
-                                       reinterpret_cast<fftwf_complex *> (out),
-                                       nullptr, stride, dist, plan_flags);
+          if (in_place)
+            otmp = reinterpret_cast<FloatComplex *> (itmp);
         }
-      else
-        {
-          *cur_plan_p
-            = fftwf_plan_many_dft_r2c (rank, tmp, howmany,
-                                       (const_cast<float *> (in)),
-                                       nullptr, stride, dist,
-                                       reinterpret_cast<fftwf_complex *> (out),
-                                       nullptr, stride, dist, plan_flags);
-        }
+
+      *cur_plan_p
+        = fftwf_plan_many_dft_r2c (rank, tmp, howmany, itmp,
+                                   nullptr, stride, dist,
+                                   reinterpret_cast<fftwf_complex *> (otmp),
+                                   nullptr, stride, dist, plan_flags);
 
       if (*cur_plan_p == nullptr)
         (*current_liboctave_error_handler) ("Error creating FFTW plan");
--- a/liboctave/util/oct-locbuf.h	Mon Oct 02 15:00:35 2023 +0200
+++ b/liboctave/util/oct-locbuf.h	Tue Oct 03 14:45:22 2023 +0200
@@ -51,4 +51,25 @@
   OCTAVE_LOCAL_BUFFER (T, buf, size);                                   \
   std::fill_n (buf, size, value)
 
+// The following two macros can be used in a pair if the scope of the buffer
+// should be larger than the scope in which the buffer is created.
+
+#define OCTAVE_SCOPED_BUFFER_ANCHOR(T, buf)                             \
+  std::unique_ptr<T []> octave_local_buffer_ ## buf;                    \
+  T *buf
+
+#if __cplusplus >= 201402L
+
+#define OCTAVE_SCOPED_BUFFER(T, buf, size)                              \
+  octave_local_buffer_ ## buf = std::make_unique<T []> (size);          \
+  buf = octave_local_buffer_ ## buf.get ()
+
+#else
+
+#define OCTAVE_SCOPED_BUFFER(T, buf, size)                              \
+  octave_local_buffer_ ## buf = std::unique_ptr<T []> (new T [size]);   \
+  buf = octave_local_buffer_ ## buf.get ()
+
 #endif
+
+#endif