[Scipy-svn] r4260 - branches/refactor_fft/scipy/fftpack/src/fftw

scipy-svn at scipy.org scipy-svn at scipy.org
Sun May 11 06:57:18 EDT 2008


Author: cdavid
Date: 2008-05-11 05:57:14 -0500 (Sun, 11 May 2008)
New Revision: 4260

Modified:
   branches/refactor_fft/scipy/fftpack/src/fftw/zfftnd.cxx
Log:
fftw (2) backend for zfftnd now uses c++ cycle cache.

Modified: branches/refactor_fft/scipy/fftpack/src/fftw/zfftnd.cxx
===================================================================
--- branches/refactor_fft/scipy/fftpack/src/fftw/zfftnd.cxx	2008-05-11 10:31:22 UTC (rev 4259)
+++ branches/refactor_fft/scipy/fftpack/src/fftw/zfftnd.cxx	2008-05-11 10:57:14 UTC (rev 4260)
@@ -3,9 +3,150 @@
  *
  * Original code by Pearu Peaterson
  *
- * Last Change: Thu Sep 06 05:00 PM 2007 J
+ * Last Change: Sun May 11 07:00 PM 2008 J
  */
+#include <new>
+#include <cassert>
 
+#include <cycliccache.h>
+
+using namespace fft;
+
+class NDFFTWCacheId {
+        public:
+                NDFFTWCacheId(int rank, int *dims, int dir, int flags);
+                virtual ~NDFFTWCacheId();
+
+                NDFFTWCacheId(const NDFFTWCacheId &);
+
+                virtual bool operator==(const NDFFTWCacheId & other) const {
+                        return is_equal(other);
+                };
+
+                virtual bool is_equal(const NDFFTWCacheId & other) const;
+
+        public:
+                int m_dir;
+                int m_rank;
+                int *m_dims;
+                int m_flags;
+
+        private:
+                int init(int rank, int *dims);
+};
+
+int NDFFTWCacheId::init(int rank, int *dims)
+{
+	m_dims = (int *) malloc(sizeof(int) * rank);
+	if (m_dims == NULL) {
+		return -1;
+	}
+	memcpy(m_dims, dims, rank * sizeof(*m_dims));
+
+	return 0;
+
+}
+
+NDFFTWCacheId::NDFFTWCacheId(int rank, int *dims, int dir, int flags) :
+        m_dir(dir),
+        m_rank(rank), 
+        m_flags(flags)
+{
+        if (init(rank, dims)) {
+                goto fail;
+        }
+
+fail:
+        std::bad_alloc();
+}
+
+NDFFTWCacheId::NDFFTWCacheId(const NDFFTWCacheId & copy) : 
+        m_dir(copy.m_dir),
+        m_rank(copy.m_rank),
+        m_flags(copy.m_flags)
+{
+	if (init(copy.m_rank, copy.m_dims)) {
+		goto fail;
+	}
+
+fail:
+	std::bad_alloc();
+}
+
+NDFFTWCacheId::~NDFFTWCacheId()
+{
+	free(m_dims);
+}
+
+bool NDFFTWCacheId::is_equal(const NDFFTWCacheId & other) const
+{
+	bool res;
+
+	res = (other.m_dir == m_dir);
+	res = res && (other.m_flags == m_flags);
+
+	if (m_rank == other.m_rank) {
+                res = res && equal_dims(m_rank, m_dims, other.m_dims);
+	} else {
+		return false;
+	}
+
+	return res;
+}
+
+class NDFFTWCache : public Cache < NDFFTWCacheId > {
+        public:
+                NDFFTWCache(const NDFFTWCacheId & id);
+                virtual ~ NDFFTWCache();
+
+                int compute(fftw_complex * inout) const 
+                {
+                        fftwnd_one(m_plan, inout, NULL);
+                        return 0;
+                };
+
+        protected:
+                fftwnd_plan m_plan;
+};
+
+NDFFTWCache::NDFFTWCache(const NDFFTWCacheId & id)
+:  Cache < NDFFTWCacheId > (id)
+{
+	int flags = FFTW_ESTIMATE | FFTW_IN_PLACE;
+#if 0
+	int sz;
+	int i;
+
+	sz = 1;
+	for (i = 0; i < m_id.m_rank; ++i) {
+		sz *= m_id.m_dims[i];
+	}
+#endif
+
+	m_plan = fftwnd_create_plan(m_id.m_rank,
+				    m_id.m_dims,
+				    (id.m_dir > 0 ? 
+                                     FFTW_FORWARD : FFTW_BACKWARD),
+				    flags);
+
+	if (m_plan == NULL) {
+		goto fail;
+	}
+
+	return;
+
+fail:
+        throw std::bad_alloc();
+}
+
+NDFFTWCache::~NDFFTWCache()
+{
+	fftwnd_destroy_plan(m_plan);
+}
+
+static CacheManager < NDFFTWCacheId, NDFFTWCache > fftwnd_cmgr(10);
+
+#if 0
 GEN_CACHE(zfftnd_fftw, (int n, int *dims, int d, int flags)
 	  , int direction;
 	  int *dims;
@@ -23,31 +164,39 @@
 			     flags);,
 	  fftwnd_destroy_plan(caches_zfftnd_fftw[id].plan);
 	  free(caches_zfftnd_fftw[id].dims);, 10)
+#endif
 
+/* stub to make GEN_PUBLIC_API happy */
+static void destroy_zfftnd_fftw_caches()
+{
+}
 
 extern void zfftnd_fftw(complex_double * inout, int rank,
 		       int *dims, int direction, int howmany,
 		       int normalize)
 {
-    int i, sz;
-    complex_double *ptr = inout;
-    fftwnd_plan plan = NULL;
+        int i, sz;
+        complex_double *ptr = inout;
+        NDFFTWCache *cache;
 
-    sz = 1;
-    for (i = 0; i < rank; ++i) {
-	sz *= dims[i];
-    }
-    i = get_cache_id_zfftnd_fftw(rank, dims, direction,
-				 FFTW_IN_PLACE | FFTW_ESTIMATE);
-    plan = caches_zfftnd_fftw[i].plan;
-    for (i = 0; i < howmany; ++i, ptr += sz) {
-	fftwnd_one(plan, (fftw_complex *) ptr, NULL);
-    }
-    if (normalize) {
-	ptr = inout;
-	for (i = sz * howmany - 1; i >= 0; --i) {
-	    *((double *) (ptr)) /= sz;
-	    *((double *) (ptr++) + 1) /= sz;
-	}
-    }
+        sz = 1;
+        for (i = 0; i < rank; ++i) {
+                sz *= dims[i];
+        }
+
+        cache = fftwnd_cmgr.get_cache(
+                        NDFFTWCacheId(rank, dims, direction, 
+                                      FFTW_IN_PLACE | FFTW_ESTIMATE));
+
+        for (i = 0; i < howmany; ++i, ptr += sz) {
+                cache->compute((fftw_complex*)ptr);
+        }
+
+        if (normalize) {
+                ptr = inout;
+                for (i = sz * howmany - 1; i >= 0; --i) {
+                        *((double *) (ptr)) /= sz;
+                        *((double *) (ptr++) + 1) /= sz;
+                }
+        }
 }




More information about the Scipy-svn mailing list