| cannam@127 | 1 /* | 
| cannam@127 | 2  * Copyright (c) 2003, 2007-14 Matteo Frigo | 
| cannam@127 | 3  * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology | 
| cannam@127 | 4  * | 
| cannam@127 | 5  * This program is free software; you can redistribute it and/or modify | 
| cannam@127 | 6  * it under the terms of the GNU General Public License as published by | 
| cannam@127 | 7  * the Free Software Foundation; either version 2 of the License, or | 
| cannam@127 | 8  * (at your option) any later version. | 
| cannam@127 | 9  * | 
| cannam@127 | 10  * This program is distributed in the hope that it will be useful, | 
| cannam@127 | 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| cannam@127 | 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| cannam@127 | 13  * GNU General Public License for more details. | 
| cannam@127 | 14  * | 
| cannam@127 | 15  * You should have received a copy of the GNU General Public License | 
| cannam@127 | 16  * along with this program; if not, write to the Free Software | 
| cannam@127 | 17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA | 
| cannam@127 | 18  * | 
| cannam@127 | 19  */ | 
| cannam@127 | 20 | 
| cannam@127 | 21 /* routines shared by the various buffered solvers */ | 
| cannam@127 | 22 | 
| cannam@127 | 23 #include "ifftw.h" | 
| cannam@127 | 24 | 
| cannam@127 | 25 #define DEFAULT_MAXNBUF ((INT)256) | 
| cannam@127 | 26 | 
| cannam@127 | 27 /* approx. 512KB of buffers for complex data */ | 
| cannam@127 | 28 #define MAXBUFSZ (256 * 1024 / (INT)(sizeof(R))) | 
| cannam@127 | 29 | 
| cannam@127 | 30 INT X(nbuf)(INT n, INT vl, INT maxnbuf) | 
| cannam@127 | 31 { | 
| cannam@127 | 32      INT i, nbuf, lb; | 
| cannam@127 | 33 | 
| cannam@127 | 34      if (!maxnbuf) | 
| cannam@127 | 35 	  maxnbuf = DEFAULT_MAXNBUF; | 
| cannam@127 | 36 | 
| cannam@127 | 37      nbuf = X(imin)(maxnbuf, | 
| cannam@127 | 38 		    X(imin)(vl, X(imax)((INT)1, MAXBUFSZ / n))); | 
| cannam@127 | 39 | 
| cannam@127 | 40      /* | 
| cannam@127 | 41       * Look for a buffer number (not too small) that divides the | 
| cannam@127 | 42       * vector length, in order that we only need one child plan: | 
| cannam@127 | 43       */ | 
| cannam@127 | 44      lb = X(imax)(1, nbuf / 4); | 
| cannam@127 | 45      for (i = nbuf; i >= lb; --i) | 
| cannam@127 | 46           if (vl % i == 0) | 
| cannam@127 | 47                return i; | 
| cannam@127 | 48 | 
| cannam@127 | 49      /* whatever... */ | 
| cannam@127 | 50      return nbuf; | 
| cannam@127 | 51 } | 
| cannam@127 | 52 | 
| cannam@127 | 53 #define SKEW 6 /* need to be even for SIMD */ | 
| cannam@127 | 54 #define SKEWMOD 8 | 
| cannam@127 | 55 | 
| cannam@127 | 56 INT X(bufdist)(INT n, INT vl) | 
| cannam@127 | 57 { | 
| cannam@127 | 58      if (vl == 1) | 
| cannam@127 | 59 	  return n; | 
| cannam@127 | 60      else | 
| cannam@127 | 61 	  /* return smallest X such that X >= N and X == SKEW (mod SKEWMOD) */ | 
| cannam@127 | 62 	  return n + X(modulo)(SKEW - n, SKEWMOD); | 
| cannam@127 | 63 } | 
| cannam@127 | 64 | 
| cannam@127 | 65 int X(toobig)(INT n) | 
| cannam@127 | 66 { | 
| cannam@127 | 67      return n > MAXBUFSZ; | 
| cannam@127 | 68 } | 
| cannam@127 | 69 | 
| cannam@127 | 70 /* TRUE if there exists i < which such that maxnbuf[i] and | 
| cannam@127 | 71    maxnbuf[which] yield the same value, in which case we canonicalize | 
| cannam@127 | 72    on the minimum value */ | 
| cannam@127 | 73 int X(nbuf_redundant)(INT n, INT vl, size_t which, | 
| cannam@127 | 74 		      const INT *maxnbuf, size_t nmaxnbuf) | 
| cannam@127 | 75 { | 
| cannam@127 | 76      size_t i; | 
| cannam@127 | 77      (void)nmaxnbuf; /* UNUSED */ | 
| cannam@127 | 78      for (i = 0; i < which; ++i) | 
| cannam@127 | 79 	  if (X(nbuf)(n, vl, maxnbuf[i]) == X(nbuf)(n, vl, maxnbuf[which])) | 
| cannam@127 | 80 	       return 1; | 
| cannam@127 | 81      return 0; | 
| cannam@127 | 82 } |