Mercurial > hg > sv-dependency-builds
comparison src/fftw-3.3.8/rdft/ct-hc2c.c @ 167:bd3cc4d1df30
Add FFTW 3.3.8 source, and a Linux build
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Tue, 19 Nov 2019 14:52:55 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
166:cbd6d7e562c7 | 167:bd3cc4d1df30 |
---|---|
1 /* | |
2 * Copyright (c) 2003, 2007-14 Matteo Frigo | |
3 * Copyright (c) 2003, 2007-14 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
18 * | |
19 */ | |
20 | |
21 #include "ct-hc2c.h" | |
22 #include "dft/dft.h" | |
23 | |
24 typedef struct { | |
25 plan_rdft2 super; | |
26 plan *cld; | |
27 plan *cldw; | |
28 INT r; | |
29 } P; | |
30 | |
31 static void apply_dit(const plan *ego_, R *r0, R *r1, R *cr, R *ci) | |
32 { | |
33 const P *ego = (const P *) ego_; | |
34 plan_rdft *cld; | |
35 plan_hc2c *cldw; | |
36 UNUSED(r1); | |
37 | |
38 cld = (plan_rdft *) ego->cld; | |
39 cld->apply(ego->cld, r0, cr); | |
40 | |
41 cldw = (plan_hc2c *) ego->cldw; | |
42 cldw->apply(ego->cldw, cr, ci); | |
43 } | |
44 | |
45 static void apply_dif(const plan *ego_, R *r0, R *r1, R *cr, R *ci) | |
46 { | |
47 const P *ego = (const P *) ego_; | |
48 plan_rdft *cld; | |
49 plan_hc2c *cldw; | |
50 UNUSED(r1); | |
51 | |
52 cldw = (plan_hc2c *) ego->cldw; | |
53 cldw->apply(ego->cldw, cr, ci); | |
54 | |
55 cld = (plan_rdft *) ego->cld; | |
56 cld->apply(ego->cld, cr, r0); | |
57 } | |
58 | |
59 static void apply_dit_dft(const plan *ego_, R *r0, R *r1, R *cr, R *ci) | |
60 { | |
61 const P *ego = (const P *) ego_; | |
62 plan_dft *cld; | |
63 plan_hc2c *cldw; | |
64 | |
65 cld = (plan_dft *) ego->cld; | |
66 cld->apply(ego->cld, r0, r1, cr, ci); | |
67 | |
68 cldw = (plan_hc2c *) ego->cldw; | |
69 cldw->apply(ego->cldw, cr, ci); | |
70 } | |
71 | |
72 static void apply_dif_dft(const plan *ego_, R *r0, R *r1, R *cr, R *ci) | |
73 { | |
74 const P *ego = (const P *) ego_; | |
75 plan_dft *cld; | |
76 plan_hc2c *cldw; | |
77 | |
78 cldw = (plan_hc2c *) ego->cldw; | |
79 cldw->apply(ego->cldw, cr, ci); | |
80 | |
81 cld = (plan_dft *) ego->cld; | |
82 cld->apply(ego->cld, ci, cr, r1, r0); | |
83 } | |
84 | |
85 static void awake(plan *ego_, enum wakefulness wakefulness) | |
86 { | |
87 P *ego = (P *) ego_; | |
88 X(plan_awake)(ego->cld, wakefulness); | |
89 X(plan_awake)(ego->cldw, wakefulness); | |
90 } | |
91 | |
92 static void destroy(plan *ego_) | |
93 { | |
94 P *ego = (P *) ego_; | |
95 X(plan_destroy_internal)(ego->cldw); | |
96 X(plan_destroy_internal)(ego->cld); | |
97 } | |
98 | |
99 static void print(const plan *ego_, printer *p) | |
100 { | |
101 const P *ego = (const P *) ego_; | |
102 p->print(p, "(rdft2-ct-%s/%D%(%p%)%(%p%))", | |
103 (ego->super.apply == apply_dit || | |
104 ego->super.apply == apply_dit_dft) | |
105 ? "dit" : "dif", | |
106 ego->r, ego->cldw, ego->cld); | |
107 } | |
108 | |
109 static int applicable0(const hc2c_solver *ego, const problem *p_, planner *plnr) | |
110 { | |
111 const problem_rdft2 *p = (const problem_rdft2 *) p_; | |
112 INT r; | |
113 | |
114 return (1 | |
115 && p->sz->rnk == 1 | |
116 && p->vecsz->rnk <= 1 | |
117 | |
118 && (/* either the problem is R2HC, which is solved by DIT */ | |
119 (p->kind == R2HC) | |
120 || | |
121 /* or the problem is HC2R, in which case it is solved | |
122 by DIF, which destroys the input */ | |
123 (p->kind == HC2R && | |
124 (p->r0 == p->cr || !NO_DESTROY_INPUTP(plnr)))) | |
125 | |
126 && ((r = X(choose_radix)(ego->r, p->sz->dims[0].n)) > 0) | |
127 && p->sz->dims[0].n > r); | |
128 } | |
129 | |
130 static int hc2c_applicable(const hc2c_solver *ego, const problem *p_, | |
131 planner *plnr) | |
132 { | |
133 const problem_rdft2 *p; | |
134 | |
135 if (!applicable0(ego, p_, plnr)) | |
136 return 0; | |
137 | |
138 p = (const problem_rdft2 *) p_; | |
139 | |
140 return (0 | |
141 || p->vecsz->rnk == 0 | |
142 || !NO_VRECURSEP(plnr) | |
143 ); | |
144 } | |
145 | |
146 static plan *mkplan(const solver *ego_, const problem *p_, planner *plnr) | |
147 { | |
148 const hc2c_solver *ego = (const hc2c_solver *) ego_; | |
149 const problem_rdft2 *p; | |
150 P *pln = 0; | |
151 plan *cld = 0, *cldw = 0; | |
152 INT n, r, m, v, ivs, ovs; | |
153 iodim *d; | |
154 | |
155 static const plan_adt padt = { | |
156 X(rdft2_solve), awake, print, destroy | |
157 }; | |
158 | |
159 if (!hc2c_applicable(ego, p_, plnr)) | |
160 return (plan *) 0; | |
161 | |
162 p = (const problem_rdft2 *) p_; | |
163 d = p->sz->dims; | |
164 n = d[0].n; | |
165 r = X(choose_radix)(ego->r, n); | |
166 A((r % 2) == 0); | |
167 m = n / r; | |
168 | |
169 X(tensor_tornk1)(p->vecsz, &v, &ivs, &ovs); | |
170 | |
171 switch (p->kind) { | |
172 case R2HC: | |
173 cldw = ego->mkcldw(ego, R2HC, | |
174 r, m * d[0].os, | |
175 m, d[0].os, | |
176 v, ovs, | |
177 p->cr, p->ci, plnr); | |
178 if (!cldw) goto nada; | |
179 | |
180 switch (ego->hc2ckind) { | |
181 case HC2C_VIA_RDFT: | |
182 cld = X(mkplan_d)( | |
183 plnr, | |
184 X(mkproblem_rdft_1_d)( | |
185 X(mktensor_1d)(m, (r/2)*d[0].is, d[0].os), | |
186 X(mktensor_3d)( | |
187 2, p->r1 - p->r0, p->ci - p->cr, | |
188 r / 2, d[0].is, m * d[0].os, | |
189 v, ivs, ovs), | |
190 p->r0, p->cr, R2HC) | |
191 ); | |
192 if (!cld) goto nada; | |
193 | |
194 pln = MKPLAN_RDFT2(P, &padt, apply_dit); | |
195 break; | |
196 | |
197 case HC2C_VIA_DFT: | |
198 cld = X(mkplan_d)( | |
199 plnr, | |
200 X(mkproblem_dft_d)( | |
201 X(mktensor_1d)(m, (r/2)*d[0].is, d[0].os), | |
202 X(mktensor_2d)( | |
203 r / 2, d[0].is, m * d[0].os, | |
204 v, ivs, ovs), | |
205 p->r0, p->r1, p->cr, p->ci) | |
206 ); | |
207 if (!cld) goto nada; | |
208 | |
209 pln = MKPLAN_RDFT2(P, &padt, apply_dit_dft); | |
210 break; | |
211 } | |
212 break; | |
213 | |
214 case HC2R: | |
215 cldw = ego->mkcldw(ego, HC2R, | |
216 r, m * d[0].is, | |
217 m, d[0].is, | |
218 v, ivs, | |
219 p->cr, p->ci, plnr); | |
220 if (!cldw) goto nada; | |
221 | |
222 switch (ego->hc2ckind) { | |
223 case HC2C_VIA_RDFT: | |
224 cld = X(mkplan_d)( | |
225 plnr, | |
226 X(mkproblem_rdft_1_d)( | |
227 X(mktensor_1d)(m, d[0].is, (r/2)*d[0].os), | |
228 X(mktensor_3d)( | |
229 2, p->ci - p->cr, p->r1 - p->r0, | |
230 r / 2, m * d[0].is, d[0].os, | |
231 v, ivs, ovs), | |
232 p->cr, p->r0, HC2R) | |
233 ); | |
234 if (!cld) goto nada; | |
235 | |
236 pln = MKPLAN_RDFT2(P, &padt, apply_dif); | |
237 break; | |
238 | |
239 case HC2C_VIA_DFT: | |
240 cld = X(mkplan_d)( | |
241 plnr, | |
242 X(mkproblem_dft_d)( | |
243 X(mktensor_1d)(m, d[0].is, (r/2)*d[0].os), | |
244 X(mktensor_2d)( | |
245 r / 2, m * d[0].is, d[0].os, | |
246 v, ivs, ovs), | |
247 p->ci, p->cr, p->r1, p->r0) | |
248 ); | |
249 if (!cld) goto nada; | |
250 | |
251 pln = MKPLAN_RDFT2(P, &padt, apply_dif_dft); | |
252 break; | |
253 } | |
254 break; | |
255 | |
256 default: | |
257 A(0); | |
258 } | |
259 | |
260 pln->cld = cld; | |
261 pln->cldw = cldw; | |
262 pln->r = r; | |
263 X(ops_add)(&cld->ops, &cldw->ops, &pln->super.super.ops); | |
264 | |
265 /* inherit could_prune_now_p attribute from cldw */ | |
266 pln->super.super.could_prune_now_p = cldw->could_prune_now_p; | |
267 | |
268 return &(pln->super.super); | |
269 | |
270 nada: | |
271 X(plan_destroy_internal)(cldw); | |
272 X(plan_destroy_internal)(cld); | |
273 return (plan *) 0; | |
274 } | |
275 | |
276 hc2c_solver *X(mksolver_hc2c)(size_t size, INT r, | |
277 hc2c_kind hc2ckind, | |
278 hc2c_mkinferior mkcldw) | |
279 { | |
280 static const solver_adt sadt = { PROBLEM_RDFT2, mkplan, 0 }; | |
281 hc2c_solver *slv = (hc2c_solver *)X(mksolver)(size, &sadt); | |
282 slv->r = r; | |
283 slv->hc2ckind = hc2ckind; | |
284 slv->mkcldw = mkcldw; | |
285 return slv; | |
286 } | |
287 | |
288 plan *X(mkplan_hc2c)(size_t size, const plan_adt *adt, hc2capply apply) | |
289 { | |
290 plan_hc2c *ego; | |
291 | |
292 ego = (plan_hc2c *) X(mkplan)(size, adt); | |
293 ego->apply = apply; | |
294 | |
295 return &(ego->super); | |
296 } |