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 #ifndef __RDFT_H__
|
cannam@127
|
22 #define __RDFT_H__
|
cannam@127
|
23
|
cannam@127
|
24 #include "ifftw.h"
|
cannam@127
|
25 #include "codelet-rdft.h"
|
cannam@127
|
26
|
cannam@127
|
27 #ifdef __cplusplus
|
cannam@127
|
28 extern "C"
|
cannam@127
|
29 {
|
cannam@127
|
30 #endif /* __cplusplus */
|
cannam@127
|
31
|
cannam@127
|
32 /* problem.c: */
|
cannam@127
|
33 typedef struct {
|
cannam@127
|
34 problem super;
|
cannam@127
|
35 tensor *sz, *vecsz;
|
cannam@127
|
36 R *I, *O;
|
cannam@127
|
37 #if defined(STRUCT_HACK_KR)
|
cannam@127
|
38 rdft_kind kind[1];
|
cannam@127
|
39 #elif defined(STRUCT_HACK_C99)
|
cannam@127
|
40 rdft_kind kind[];
|
cannam@127
|
41 #else
|
cannam@127
|
42 rdft_kind *kind;
|
cannam@127
|
43 #endif
|
cannam@127
|
44 } problem_rdft;
|
cannam@127
|
45
|
cannam@127
|
46 void X(rdft_zerotens)(tensor *sz, R *I);
|
cannam@127
|
47 problem *X(mkproblem_rdft)(const tensor *sz, const tensor *vecsz,
|
cannam@127
|
48 R *I, R *O, const rdft_kind *kind);
|
cannam@127
|
49 problem *X(mkproblem_rdft_d)(tensor *sz, tensor *vecsz,
|
cannam@127
|
50 R *I, R *O, const rdft_kind *kind);
|
cannam@127
|
51 problem *X(mkproblem_rdft_0_d)(tensor *vecsz, R *I, R *O);
|
cannam@127
|
52 problem *X(mkproblem_rdft_1)(const tensor *sz, const tensor *vecsz,
|
cannam@127
|
53 R *I, R *O, rdft_kind kind);
|
cannam@127
|
54 problem *X(mkproblem_rdft_1_d)(tensor *sz, tensor *vecsz,
|
cannam@127
|
55 R *I, R *O, rdft_kind kind);
|
cannam@127
|
56
|
cannam@127
|
57 const char *X(rdft_kind_str)(rdft_kind kind);
|
cannam@127
|
58
|
cannam@127
|
59 /* solve.c: */
|
cannam@127
|
60 void X(rdft_solve)(const plan *ego_, const problem *p_);
|
cannam@127
|
61
|
cannam@127
|
62 /* plan.c: */
|
cannam@127
|
63 typedef void (*rdftapply) (const plan *ego, R *I, R *O);
|
cannam@127
|
64
|
cannam@127
|
65 typedef struct {
|
cannam@127
|
66 plan super;
|
cannam@127
|
67 rdftapply apply;
|
cannam@127
|
68 } plan_rdft;
|
cannam@127
|
69
|
cannam@127
|
70 plan *X(mkplan_rdft)(size_t size, const plan_adt *adt, rdftapply apply);
|
cannam@127
|
71
|
cannam@127
|
72 #define MKPLAN_RDFT(type, adt, apply) \
|
cannam@127
|
73 (type *)X(mkplan_rdft)(sizeof(type), adt, apply)
|
cannam@127
|
74
|
cannam@127
|
75 /* various solvers */
|
cannam@127
|
76
|
cannam@127
|
77 solver *X(mksolver_rdft_r2c_direct)(kr2c k, const kr2c_desc *desc);
|
cannam@127
|
78 solver *X(mksolver_rdft_r2c_directbuf)(kr2c k, const kr2c_desc *desc);
|
cannam@127
|
79 solver *X(mksolver_rdft_r2r_direct)(kr2r k, const kr2r_desc *desc);
|
cannam@127
|
80
|
cannam@127
|
81 void X(rdft_rank0_register)(planner *p);
|
cannam@127
|
82 void X(rdft_vrank3_transpose_register)(planner *p);
|
cannam@127
|
83 void X(rdft_rank_geq2_register)(planner *p);
|
cannam@127
|
84 void X(rdft_indirect_register)(planner *p);
|
cannam@127
|
85 void X(rdft_vrank_geq1_register)(planner *p);
|
cannam@127
|
86 void X(rdft_buffered_register)(planner *p);
|
cannam@127
|
87 void X(rdft_generic_register)(planner *p);
|
cannam@127
|
88 void X(rdft_rader_hc2hc_register)(planner *p);
|
cannam@127
|
89 void X(rdft_dht_register)(planner *p);
|
cannam@127
|
90 void X(dht_r2hc_register)(planner *p);
|
cannam@127
|
91 void X(dht_rader_register)(planner *p);
|
cannam@127
|
92 void X(dft_r2hc_register)(planner *p);
|
cannam@127
|
93 void X(rdft_nop_register)(planner *p);
|
cannam@127
|
94 void X(hc2hc_generic_register)(planner *p);
|
cannam@127
|
95
|
cannam@127
|
96 /****************************************************************************/
|
cannam@127
|
97 /* problem2.c: */
|
cannam@127
|
98 /*
|
cannam@127
|
99 An RDFT2 problem transforms a 1d real array r[n] with stride is/os
|
cannam@127
|
100 to/from an "unpacked" complex array {rio,iio}[n/2 + 1] with stride
|
cannam@127
|
101 os/is. R0 points to the first even element of the real array.
|
cannam@127
|
102 R1 points to the first odd element of the real array.
|
cannam@127
|
103
|
cannam@127
|
104 Strides on the real side of the transform express distances
|
cannam@127
|
105 between consecutive elements of the same array (even or odd).
|
cannam@127
|
106 E.g., for a contiguous input
|
cannam@127
|
107
|
cannam@127
|
108 R0 R1 R2 R3 ...
|
cannam@127
|
109
|
cannam@127
|
110 the input stride would be 2, not 1. This convention is necessary
|
cannam@127
|
111 for hc2c codelets to work, since they transpose even/odd with
|
cannam@127
|
112 real/imag.
|
cannam@127
|
113
|
cannam@127
|
114 Multidimensional transforms use complex DFTs for the
|
cannam@127
|
115 noncontiguous dimensions. vecsz has the usual interpretation.
|
cannam@127
|
116 */
|
cannam@127
|
117 typedef struct {
|
cannam@127
|
118 problem super;
|
cannam@127
|
119 tensor *sz;
|
cannam@127
|
120 tensor *vecsz;
|
cannam@127
|
121 R *r0, *r1;
|
cannam@127
|
122 R *cr, *ci;
|
cannam@127
|
123 rdft_kind kind; /* assert(kind < DHT) */
|
cannam@127
|
124 } problem_rdft2;
|
cannam@127
|
125
|
cannam@127
|
126 problem *X(mkproblem_rdft2)(const tensor *sz, const tensor *vecsz,
|
cannam@127
|
127 R *r0, R *r1, R *cr, R *ci, rdft_kind kind);
|
cannam@127
|
128 problem *X(mkproblem_rdft2_d)(tensor *sz, tensor *vecsz,
|
cannam@127
|
129 R *r0, R *r1, R *cr, R *ci, rdft_kind kind);
|
cannam@127
|
130 problem *X(mkproblem_rdft2_d_3pointers)(tensor *sz, tensor *vecsz,
|
cannam@127
|
131 R *r, R *cr, R *ci, rdft_kind kind);
|
cannam@127
|
132 int X(rdft2_inplace_strides)(const problem_rdft2 *p, int vdim);
|
cannam@127
|
133 INT X(rdft2_tensor_max_index)(const tensor *sz, rdft_kind k);
|
cannam@127
|
134 void X(rdft2_strides)(rdft_kind kind, const iodim *d, INT *rs, INT *cs);
|
cannam@127
|
135 INT X(rdft2_complex_n)(INT real_n, rdft_kind kind);
|
cannam@127
|
136
|
cannam@127
|
137 /* verify.c: */
|
cannam@127
|
138 void X(rdft2_verify)(plan *pln, const problem_rdft2 *p, int rounds);
|
cannam@127
|
139
|
cannam@127
|
140 /* solve.c: */
|
cannam@127
|
141 void X(rdft2_solve)(const plan *ego_, const problem *p_);
|
cannam@127
|
142
|
cannam@127
|
143 /* plan.c: */
|
cannam@127
|
144 typedef void (*rdft2apply) (const plan *ego, R *r0, R *r1, R *cr, R *ci);
|
cannam@127
|
145
|
cannam@127
|
146 typedef struct {
|
cannam@127
|
147 plan super;
|
cannam@127
|
148 rdft2apply apply;
|
cannam@127
|
149 } plan_rdft2;
|
cannam@127
|
150
|
cannam@127
|
151 plan *X(mkplan_rdft2)(size_t size, const plan_adt *adt, rdft2apply apply);
|
cannam@127
|
152
|
cannam@127
|
153 #define MKPLAN_RDFT2(type, adt, apply) \
|
cannam@127
|
154 (type *)X(mkplan_rdft2)(sizeof(type), adt, apply)
|
cannam@127
|
155
|
cannam@127
|
156 /* various solvers */
|
cannam@127
|
157
|
cannam@127
|
158 solver *X(mksolver_rdft2_direct)(kr2c k, const kr2c_desc *desc);
|
cannam@127
|
159
|
cannam@127
|
160 void X(rdft2_vrank_geq1_register)(planner *p);
|
cannam@127
|
161 void X(rdft2_buffered_register)(planner *p);
|
cannam@127
|
162 void X(rdft2_rdft_register)(planner *p);
|
cannam@127
|
163 void X(rdft2_nop_register)(planner *p);
|
cannam@127
|
164 void X(rdft2_rank0_register)(planner *p);
|
cannam@127
|
165 void X(rdft2_rank_geq2_register)(planner *p);
|
cannam@127
|
166
|
cannam@127
|
167 /****************************************************************************/
|
cannam@127
|
168
|
cannam@127
|
169 /* configurations */
|
cannam@127
|
170 void X(rdft_conf_standard)(planner *p);
|
cannam@127
|
171
|
cannam@127
|
172 #ifdef __cplusplus
|
cannam@127
|
173 } /* extern "C" */
|
cannam@127
|
174 #endif /* __cplusplus */
|
cannam@127
|
175
|
cannam@127
|
176 #endif /* __RDFT_H__ */
|