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

« back to all changes in this revision

Viewing changes to threads/hc2hc.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
#include "threads.h"
 
22
 
 
23
typedef struct {
 
24
     plan_rdft super;
 
25
     plan *cld;
 
26
     plan **cldws;
 
27
     int nthr;
 
28
     INT r;
 
29
} P;
 
30
 
 
31
typedef struct {
 
32
     plan **cldws;
 
33
     R *IO;
 
34
} PD;
 
35
 
 
36
static void *spawn_apply(spawn_data *d)
 
37
WITH_ALIGNED_STACK({
 
38
     PD *ego = (PD *) d->data;
 
39
     
 
40
     plan_hc2hc *cldw = (plan_hc2hc *) (ego->cldws[d->thr_num]);
 
41
     cldw->apply((plan *) cldw, ego->IO);
 
42
     return 0;
 
43
})
 
44
 
 
45
static void apply_dit(const plan *ego_, R *I, R *O)
 
46
{
 
47
     const P *ego = (const P *) ego_;
 
48
     plan_rdft *cld;
 
49
 
 
50
     cld = (plan_rdft *) ego->cld;
 
51
     cld->apply((plan *) cld, I, O);
 
52
 
 
53
     {
 
54
          PD d;
 
55
          
 
56
          d.IO = O;
 
57
          d.cldws = ego->cldws;
 
58
 
 
59
          X(spawn_loop)(ego->nthr, ego->nthr, spawn_apply, (void*)&d);
 
60
     }
 
61
}
 
62
 
 
63
static void apply_dif(const plan *ego_, R *I, R *O)
 
64
{
 
65
     const P *ego = (const P *) ego_;
 
66
     plan_rdft *cld;
 
67
 
 
68
     {
 
69
          PD d;
 
70
          
 
71
          d.IO = I;
 
72
          d.cldws = ego->cldws;
 
73
 
 
74
          X(spawn_loop)(ego->nthr, ego->nthr, spawn_apply, (void*)&d);
 
75
     }
 
76
 
 
77
     cld = (plan_rdft *) ego->cld;
 
78
     cld->apply((plan *) cld, I, O);
 
79
}
 
80
 
 
81
static void awake(plan *ego_, enum wakefulness wakefulness)
 
82
{
 
83
     P *ego = (P *) ego_;
 
84
     int i;
 
85
     X(plan_awake)(ego->cld, wakefulness);
 
86
     for (i = 0; i < ego->nthr; ++i)
 
87
          X(plan_awake)(ego->cldws[i], wakefulness);
 
88
}
 
89
 
 
90
static void destroy(plan *ego_)
 
91
{
 
92
     P *ego = (P *) ego_;
 
93
     int i;
 
94
     X(plan_destroy_internal)(ego->cld);
 
95
     for (i = 0; i < ego->nthr; ++i)
 
96
          X(plan_destroy_internal)(ego->cldws[i]);
 
97
     X(ifree)(ego->cldws);
 
98
}
 
99
 
 
100
static void print(const plan *ego_, printer *p)
 
101
{
 
102
     const P *ego = (const P *) ego_;
 
103
     int i;
 
104
     p->print(p, "(rdft-thr-ct-%s-x%d/%D",
 
105
              ego->super.apply == apply_dit ? "dit" : "dif",
 
106
              ego->nthr, ego->r);
 
107
     for (i = 0; i < ego->nthr; ++i)
 
108
          if (i == 0 || (ego->cldws[i] != ego->cldws[i-1] &&
 
109
                         (i <= 1 || ego->cldws[i] != ego->cldws[i-2])))
 
110
               p->print(p, "%(%p%)", ego->cldws[i]);
 
111
     p->print(p, "%(%p%))", ego->cld);
 
112
}
 
113
 
 
114
static plan *mkplan(const solver *ego_, const problem *p_, planner *plnr)
 
115
{
 
116
     const hc2hc_solver *ego = (const hc2hc_solver *) ego_;
 
117
     const problem_rdft *p;
 
118
     P *pln = 0;
 
119
     plan *cld = 0, **cldws = 0;
 
120
     INT n, r, m, vl, ivs, ovs, mcount;
 
121
     int i, nthr, plnr_nthr_save;
 
122
     INT block_size;
 
123
     iodim *d;
 
124
     tensor *t1, *t2;
 
125
 
 
126
     static const plan_adt padt = {
 
127
          X(rdft_solve), awake, print, destroy
 
128
     };
 
129
 
 
130
     if (plnr->nthr <= 1 || !X(hc2hc_applicable)(ego, p_, plnr))
 
131
          return (plan *) 0;
 
132
 
 
133
     p = (const problem_rdft *) p_;
 
134
     d = p->sz->dims;
 
135
     n = d[0].n;
 
136
     r = X(choose_radix)(ego->r, n);
 
137
     m = n / r;
 
138
     mcount = (m + 2) / 2;
 
139
 
 
140
     X(tensor_tornk1)(p->vecsz, &vl, &ivs, &ovs);
 
141
 
 
142
     block_size = (mcount + plnr->nthr - 1) / plnr->nthr;
 
143
     nthr = (int)((mcount + block_size - 1) / block_size);
 
144
     plnr_nthr_save = plnr->nthr;
 
145
     plnr->nthr = (plnr->nthr + nthr - 1) / nthr;
 
146
 
 
147
     cldws = (plan **) MALLOC(sizeof(plan *) * nthr, PLANS);
 
148
     for (i = 0; i < nthr; ++i) cldws[i] = (plan *) 0;
 
149
 
 
150
     switch (p->kind[0]) {
 
151
         case R2HC:
 
152
              for (i = 0; i < nthr; ++i) {
 
153
                   cldws[i] = ego->mkcldw(ego, 
 
154
                                          R2HC, r, m, d[0].os, vl, ovs, 
 
155
                                          i*block_size, 
 
156
                                          (i == nthr - 1) ? 
 
157
                                          (mcount - i*block_size) : block_size,
 
158
                                          p->O, plnr);
 
159
                   if (!cldws[i]) goto nada;
 
160
              }
 
161
 
 
162
              t1 = X(mktensor_1d)(r, d[0].is, m * d[0].os);
 
163
              t2 = X(tensor_append)(t1, p->vecsz);
 
164
              X(tensor_destroy)(t1);
 
165
 
 
166
              plnr->nthr = plnr_nthr_save;
 
167
 
 
168
              cld = X(mkplan_d)(plnr, 
 
169
                                X(mkproblem_rdft_d)(
 
170
                                     X(mktensor_1d)(m, r * d[0].is, d[0].os),
 
171
                                     t2, p->I, p->O, p->kind)
 
172
                   );
 
173
              if (!cld) goto nada;
 
174
 
 
175
              pln = MKPLAN_RDFT(P, &padt, apply_dit);
 
176
              break;
 
177
 
 
178
         case HC2R:
 
179
              for (i = 0; i < nthr; ++i) {
 
180
                   cldws[i] = ego->mkcldw(ego, 
 
181
                                          HC2R, r, m, d[0].is, vl, ivs, 
 
182
                                          i*block_size, 
 
183
                                          (i == nthr - 1) ? 
 
184
                                          (mcount - i*block_size) : block_size,
 
185
                                          p->I, plnr);
 
186
                   if (!cldws[i]) goto nada;
 
187
              }
 
188
 
 
189
              t1 = X(mktensor_1d)(r, m * d[0].is, d[0].os);
 
190
              t2 = X(tensor_append)(t1, p->vecsz);
 
191
              X(tensor_destroy)(t1);
 
192
 
 
193
              plnr->nthr = plnr_nthr_save;
 
194
 
 
195
              cld = X(mkplan_d)(plnr, 
 
196
                                X(mkproblem_rdft_d)(
 
197
                                     X(mktensor_1d)(m, d[0].is, r * d[0].os),
 
198
                                     t2, p->I, p->O, p->kind)
 
199
                   );
 
200
              if (!cld) goto nada;
 
201
              
 
202
              pln = MKPLAN_RDFT(P, &padt, apply_dif);
 
203
              break;
 
204
 
 
205
         default: 
 
206
              A(0);
 
207
              
 
208
     }
 
209
 
 
210
     pln->cld = cld;
 
211
     pln->cldws = cldws;
 
212
     pln->nthr = nthr;
 
213
     pln->r = r;
 
214
     X(ops_zero)(&pln->super.super.ops);
 
215
     for (i = 0; i < nthr; ++i)
 
216
          X(ops_add2)(&cldws[i]->ops, &pln->super.super.ops);
 
217
     X(ops_add2)(&cld->ops, &pln->super.super.ops);
 
218
     return &(pln->super.super);
 
219
 
 
220
 nada:
 
221
     if (cldws) {
 
222
          for (i = 0; i < nthr; ++i)
 
223
               X(plan_destroy_internal)(cldws[i]);
 
224
          X(ifree)(cldws);
 
225
     }
 
226
     X(plan_destroy_internal)(cld);
 
227
     return (plan *) 0;
 
228
}
 
229
 
 
230
hc2hc_solver *X(mksolver_hc2hc_threads)(size_t size, INT r, hc2hc_mkinferior mkcldw)
 
231
{
 
232
     static const solver_adt sadt = { PROBLEM_RDFT, mkplan };
 
233
     hc2hc_solver *slv = (hc2hc_solver *)X(mksolver)(size, &sadt);
 
234
     slv->r = r;
 
235
     slv->mkcldw = mkcldw;
 
236
     return slv;
 
237
}