~ubuntu-branches/ubuntu/raring/fftw3/raring-proposed

« back to all changes in this revision

Viewing changes to dft/ctsq.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Brossier
  • Date: 2006-05-31 13:44:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060531134405-ol9hrbg6bh81sg0c
Tags: 3.1.1-1
* New upstream release (closes: #350327, #338487, #338501)
* Add --enable-portable-binary to use -mtune instead of -march
* Use --with-gcc-arch=G5 / pentium4 on powerpc / i386
* Updated Standards-Version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2003, 2006 Matteo Frigo
 
3
 * Copyright (c) 2003, 2006 Massachusetts Institute of Technology
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 *
 
19
 */
 
20
 
 
21
/* $Id: ctsq.c,v 1.12 2006-01-27 02:10:50 athena Exp $ */
 
22
 
 
23
/* special ``square transpose'' cooley-tukey solver for in-place problems */
 
24
#include "ct.h"
 
25
 
 
26
typedef struct {
 
27
     solver super;
 
28
     const ct_desc *desc;
 
29
     kdftwsq k;
 
30
     int dec;
 
31
} S;
 
32
 
 
33
typedef struct {
 
34
     plan_dft super;
 
35
     kdftwsq k;
 
36
     twid *td;
 
37
     plan *cld;
 
38
     stride ios, vs;
 
39
     INT m, r, dist;
 
40
     const S *slv;
 
41
} P;
 
42
 
 
43
static void apply_dif(const plan *ego_, R *ri, R *ii, R *ro, R *io)
 
44
{
 
45
     const P *ego = (const P *) ego_;
 
46
     plan_dft *cld;
 
47
 
 
48
     UNUSED(ro);  /* == ri */
 
49
     UNUSED(io);  /* == ii */
 
50
     ego->k(ri, ii, ego->td->W, ego->ios, ego->vs, ego->m, ego->dist);
 
51
 
 
52
     cld = (plan_dft *) ego->cld;
 
53
     cld->apply(ego->cld, ri, ii, ri, ii);
 
54
}
 
55
 
 
56
static void awake(plan *ego_, enum wakefulness wakefulness)
 
57
{
 
58
     P *ego = (P *) ego_;
 
59
     X(plan_awake)(ego->cld, wakefulness);
 
60
     X(twiddle_awake)(wakefulness, &ego->td, ego->slv->desc->tw, 
 
61
                      ego->r * ego->m, ego->r, ego->m);
 
62
}
 
63
 
 
64
static void destroy(plan *ego_)
 
65
{
 
66
     P *ego = (P *) ego_;
 
67
     X(plan_destroy_internal)(ego->cld);
 
68
     X(stride_destroy)(ego->ios);
 
69
     X(stride_destroy)(ego->vs);
 
70
}
 
71
 
 
72
static void print(const plan *ego_, printer *p)
 
73
{
 
74
     const P *ego = (const P *) ego_;
 
75
     const S *slv = ego->slv;
 
76
     const ct_desc *e = slv->desc;
 
77
 
 
78
     p->print(p, "(dft-ctsq-%s/%D \"%s\"%(%p%))",
 
79
              slv->dec == DECDIT ? "dit" : "dif",
 
80
              ego->r, e->nam, ego->cld);
 
81
}
 
82
 
 
83
#define divides(a, b) (((b) % (a)) == 0)
 
84
static int applicable(const S *ego, const problem *p_, planner *plnr)
 
85
{
 
86
     const problem_dft *p = (const problem_dft *) p_;
 
87
     const ct_desc *e = ego->desc;
 
88
     iodim *d = p->sz->dims, *vd = p->vecsz->dims;
 
89
 
 
90
     return (1
 
91
             && p->ri == p->ro  /* inplace only */
 
92
             && p->sz->rnk == 1
 
93
             && p->vecsz->rnk == 1
 
94
 
 
95
             && d[0].n > e->radix
 
96
             && divides(e->radix, d[0].n)
 
97
 
 
98
             /* conditions for transposition */
 
99
             && vd[0].n == e->radix
 
100
             && d[0].os == vd[0].is
 
101
             && d[0].is == e->radix * vd[0].is
 
102
             && vd[0].os == d[0].n * vd[0].is
 
103
 
 
104
             /* SIMD strides etc. */
 
105
             && (e->genus->okp(e, p->ri, p->ii, vd[0].os, vd[0].is, 
 
106
                               d[0].n / e->radix, 0, d[0].n / e->radix,
 
107
                               d[0].is, plnr))
 
108
          );
 
109
}
 
110
 
 
111
 
 
112
static plan *mkplan(const solver *ego_, const problem *p_, planner *plnr)
 
113
{
 
114
     const S *ego = (const S *) ego_;
 
115
     const problem_dft *p;
 
116
     P *pln = 0;
 
117
     plan *cld = 0;
 
118
     iodim *d, *vd;
 
119
     const ct_desc *e = ego->desc;
 
120
 
 
121
     static const plan_adt padt = {
 
122
          X(dft_solve), awake, print, destroy
 
123
     };
 
124
 
 
125
     if (!applicable(ego, p_, plnr))
 
126
          return (plan *) 0;
 
127
 
 
128
     p = (const problem_dft *) p_;
 
129
     d = p->sz->dims;
 
130
     vd = p->vecsz->dims;
 
131
 
 
132
     switch (ego->dec) {
 
133
         case DECDIT:
 
134
         {
 
135
              A(0); /* not implemented */
 
136
         }
 
137
         case DECDIF:
 
138
         {
 
139
              cld = X(mkplan_d)(plnr, 
 
140
                                X(mkproblem_dft_d)(
 
141
                                     X(mktensor_1d)(d[0].n / e->radix, 
 
142
                                                    d[0].is, d[0].is),
 
143
                                     X(mktensor_2d)(vd[0].n, 
 
144
                                                    vd[0].os, vd[0].os,
 
145
                                                    e->radix, 
 
146
                                                    vd[0].is,vd[0].is),
 
147
                                     p->ro, p->io, p->ro, p->io));
 
148
              if (!cld) goto nada;
 
149
              
 
150
              pln = MKPLAN_DFT(P, &padt, apply_dif);
 
151
              pln->ios = X(mkstride)(e->radix, vd[0].os);
 
152
              pln->vs = X(mkstride)(e->radix, vd[0].is);
 
153
              pln->dist = d[0].is;
 
154
              break;
 
155
         }
 
156
 
 
157
         default: A(0);
 
158
     }
 
159
 
 
160
     pln->cld = cld;
 
161
     pln->slv = ego;
 
162
     pln->r = e->radix;
 
163
     pln->m = d[0].n / pln->r;
 
164
     pln->td = 0;
 
165
     pln->k = ego->k;
 
166
 
 
167
     X(ops_madd)(pln->m / e->genus->vl, &e->ops, &cld->ops,
 
168
                 &pln->super.super.ops);
 
169
     return &(pln->super.super);
 
170
 
 
171
 nada:
 
172
     X(plan_destroy_internal)(cld);
 
173
     return (plan *) 0;
 
174
}
 
175
 
 
176
solver *X(mksolver_ctsq)(kdftwsq codelet, const ct_desc *desc, int dec)
 
177
{
 
178
     static const solver_adt sadt = { PROBLEM_DFT, mkplan };
 
179
     S *slv = MKSOLVER(S, &sadt);
 
180
     slv->k = codelet;
 
181
     slv->desc = desc;
 
182
     slv->dec = dec;
 
183
     return &(slv->super);
 
184
}
 
185