Mercurial > hg > sv-dependency-builds
comparison src/fftw-3.3.3/genfft/genutil.ml @ 10:37bf6b4a2645
Add FFTW3
author | Chris Cannam |
---|---|
date | Wed, 20 Mar 2013 15:35:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9:c0fb53affa76 | 10:37bf6b4a2645 |
---|---|
1 (* | |
2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology | |
3 * Copyright (c) 2003, 2007-11 Matteo Frigo | |
4 * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 * | |
20 *) | |
21 | |
22 (* utilities common to all generators *) | |
23 open Util | |
24 | |
25 let choose_simd a b = if !Simdmagic.simd_mode then b else a | |
26 | |
27 let unique_array n = array n (fun _ -> Unique.make ()) | |
28 let unique_array_c n = | |
29 array n (fun _ -> | |
30 (Unique.make (), Unique.make ())) | |
31 | |
32 let unique_v_array_c veclen n = | |
33 array veclen (fun _ -> | |
34 unique_array_c n) | |
35 | |
36 let locative_array_c n rarr iarr loc vs = | |
37 array n (fun i -> | |
38 let klass = Unique.make () in | |
39 let (rloc, iloc) = loc i in | |
40 (Variable.make_locative rloc klass rarr i vs, | |
41 Variable.make_locative iloc klass iarr i vs)) | |
42 | |
43 let locative_v_array_c veclen n rarr iarr loc vs = | |
44 array veclen (fun v -> | |
45 array n (fun i -> | |
46 let klass = Unique.make () in | |
47 let (rloc, iloc) = loc v i in | |
48 (Variable.make_locative rloc klass (rarr v) i vs, | |
49 Variable.make_locative iloc klass (iarr v) i vs))) | |
50 | |
51 let temporary_array n = | |
52 array n (fun i -> Variable.make_temporary ()) | |
53 | |
54 let temporary_array_c n = | |
55 let tmpr = temporary_array n | |
56 and tmpi = temporary_array n | |
57 in | |
58 array n (fun i -> (tmpr i, tmpi i)) | |
59 | |
60 let temporary_v_array_c veclen n = | |
61 array veclen (fun v -> temporary_array_c n) | |
62 | |
63 let temporary_array_c n = | |
64 let tmpr = temporary_array n | |
65 and tmpi = temporary_array n | |
66 in | |
67 array n (fun i -> (tmpr i, tmpi i)) | |
68 | |
69 let load_c (vr, vi) = Complex.make (Expr.Load vr, Expr.Load vi) | |
70 let load_r (vr, vi) = Complex.make (Expr.Load vr, Expr.Num (Number.zero)) | |
71 | |
72 let twiddle_array nt w = | |
73 array (nt/2) (fun i -> | |
74 let stride = choose_simd (C.SInteger 1) (C.SConst "TWVL") | |
75 and klass = Unique.make () in | |
76 let (refr, refi) = (C.array_subscript w stride (2 * i), | |
77 C.array_subscript w stride (2 * i + 1)) | |
78 in | |
79 let (kr, ki) = (Variable.make_constant klass refr, | |
80 Variable.make_constant klass refi) | |
81 in | |
82 load_c (kr, ki)) | |
83 | |
84 | |
85 let load_array_c n var = array n (fun i -> load_c (var i)) | |
86 let load_array_r n var = array n (fun i -> load_r (var i)) | |
87 let load_array_hc n var = | |
88 array n (fun i -> | |
89 if (i < n - i) then | |
90 load_c (var i) | |
91 else if (i > n - i) then | |
92 Complex.times Complex.i (load_c (var (n - i))) | |
93 else | |
94 load_r (var i)) | |
95 | |
96 let load_v_array_c veclen n var = | |
97 array veclen (fun v -> load_array_c n (var v)) | |
98 | |
99 let store_c (vr, vi) x = [Complex.store_real vr x; Complex.store_imag vi x] | |
100 let store_r (vr, vi) x = Complex.store_real vr x | |
101 let store_i (vr, vi) x = Complex.store_imag vi x | |
102 | |
103 let assign_array_c n dst src = | |
104 List.flatten | |
105 (rmap (iota n) | |
106 (fun i -> | |
107 let (ar, ai) = Complex.assign (dst i) (src i) | |
108 in [ar; ai])) | |
109 let assign_v_array_c veclen n dst src = | |
110 List.flatten | |
111 (rmap (iota veclen) | |
112 (fun v -> | |
113 assign_array_c n (dst v) (src v))) | |
114 | |
115 let vassign_v_array_c veclen n dst src = | |
116 List.flatten | |
117 (rmap (iota n) (fun i -> | |
118 List.flatten | |
119 (rmap (iota veclen) | |
120 (fun v -> | |
121 let (ar, ai) = Complex.assign (dst v i) (src v i) | |
122 in [ar; ai])))) | |
123 | |
124 let store_array_r n dst src = | |
125 rmap (iota n) | |
126 (fun i -> store_r (dst i) (src i)) | |
127 | |
128 let store_array_c n dst src = | |
129 List.flatten | |
130 (rmap (iota n) | |
131 (fun i -> store_c (dst i) (src i))) | |
132 | |
133 let store_array_hc n dst src = | |
134 List.flatten | |
135 (rmap (iota n) | |
136 (fun i -> | |
137 if (i < n - i) then | |
138 store_c (dst i) (src i) | |
139 else if (i > n - i) then | |
140 [] | |
141 else | |
142 [store_r (dst i) (Complex.real (src i))])) | |
143 | |
144 | |
145 let store_v_array_c veclen n dst src = | |
146 List.flatten | |
147 (rmap (iota veclen) | |
148 (fun v -> | |
149 store_array_c n (dst v) (src v))) | |
150 | |
151 | |
152 let elementwise f n a = array n (fun i -> f (a i)) | |
153 let conj_array_c = elementwise Complex.conj | |
154 let real_array_c = elementwise Complex.real | |
155 let imag_array_c = elementwise Complex.imag | |
156 | |
157 let elementwise_v f veclen n a = | |
158 array veclen (fun v -> | |
159 array n (fun i -> f (a v i))) | |
160 let conj_v_array_c = elementwise_v Complex.conj | |
161 let real_v_array_c = elementwise_v Complex.real | |
162 let imag_v_array_c = elementwise_v Complex.imag | |
163 | |
164 | |
165 let transpose f i j = f j i | |
166 let symmetrize f i j = if i <= j then f i j else f j i | |
167 | |
168 (* utilities for command-line parsing *) | |
169 let standard_arg_parse_fail _ = failwith "too many arguments" | |
170 | |
171 let dump_dag alist = | |
172 let fnam = !Magic.dag_dump_file in | |
173 if (String.length fnam > 0) then | |
174 let ochan = open_out fnam in | |
175 begin | |
176 To_alist.dump (output_string ochan) alist; | |
177 close_out ochan; | |
178 end | |
179 | |
180 let dump_alist alist = | |
181 let fnam = !Magic.alist_dump_file in | |
182 if (String.length fnam > 0) then | |
183 let ochan = open_out fnam in | |
184 begin | |
185 Expr.dump (output_string ochan) alist; | |
186 close_out ochan; | |
187 end | |
188 | |
189 let dump_asched asched = | |
190 let fnam = !Magic.asched_dump_file in | |
191 if (String.length fnam > 0) then | |
192 let ochan = open_out fnam in | |
193 begin | |
194 Annotate.dump (output_string ochan) asched; | |
195 close_out ochan; | |
196 end | |
197 | |
198 (* utilities for optimization *) | |
199 let standard_scheduler dag = | |
200 let optim = Algsimp.algsimp dag in | |
201 let alist = To_alist.to_assignments optim in | |
202 let _ = dump_alist alist in | |
203 let _ = dump_dag alist in | |
204 if !Magic.precompute_twiddles then | |
205 Schedule.isolate_precomputations_and_schedule alist | |
206 else | |
207 Schedule.schedule alist | |
208 | |
209 let standard_optimizer dag = | |
210 let sched = standard_scheduler dag in | |
211 let annot = Annotate.annotate [] sched in | |
212 let _ = dump_asched annot in | |
213 annot | |
214 | |
215 let size = ref None | |
216 let sign = ref (-1) | |
217 | |
218 let speclist = [ | |
219 "-n", Arg.Int(fun i -> size := Some i), " generate a codelet of size <n>"; | |
220 "-sign", | |
221 Arg.Int(fun i -> | |
222 if (i > 0) then | |
223 sign := 1 | |
224 else | |
225 sign := (-1)), | |
226 " sign of transform"; | |
227 ] | |
228 | |
229 let check_size () = | |
230 match !size with | |
231 | Some i -> i | |
232 | None -> failwith "must specify -n" | |
233 | |
234 let expand_name name = if name = "" then "noname" else name | |
235 | |
236 let declare_register_fcn name = | |
237 if name = "" then | |
238 "void NAME(planner *p)\n" | |
239 else | |
240 "void " ^ (choose_simd "X" "XSIMD") ^ | |
241 "(codelet_" ^ name ^ ")(planner *p)\n" | |
242 | |
243 let stringify name = | |
244 if name = "" then "STRINGIZE(NAME)" else | |
245 choose_simd ("\"" ^ name ^ "\"") | |
246 ("XSIMD_STRING(\"" ^ name ^ "\")") | |
247 | |
248 let parse user_speclist usage = | |
249 Arg.parse | |
250 (user_speclist @ speclist @ Magic.speclist @ Simdmagic.speclist) | |
251 standard_arg_parse_fail | |
252 usage | |
253 | |
254 let rec list_to_c = function | |
255 [] -> "" | |
256 | [a] -> (string_of_int a) | |
257 | a :: b -> (string_of_int a) ^ ", " ^ (list_to_c b) | |
258 | |
259 let rec list_to_comma = function | |
260 | [a; b] -> C.Comma (a, b) | |
261 | a :: b -> C.Comma (a, list_to_comma b) | |
262 | _ -> failwith "list_to_comma" | |
263 | |
264 | |
265 type stride = Stride_variable | Fixed_int of int | Fixed_string of string | |
266 | |
267 let either_stride a b = | |
268 match a with | |
269 Fixed_int x -> C.SInteger x | |
270 | Fixed_string x -> C.SConst x | |
271 | _ -> b | |
272 | |
273 let stride_fixed = function | |
274 Stride_variable -> false | |
275 | _ -> true | |
276 | |
277 let arg_to_stride s = | |
278 try | |
279 Fixed_int (int_of_string s) | |
280 with Failure "int_of_string" -> | |
281 Fixed_string s | |
282 | |
283 let stride_to_solverparm = function | |
284 Stride_variable -> "0" | |
285 | Fixed_int x -> string_of_int x | |
286 | Fixed_string x -> x | |
287 | |
288 let stride_to_string s = function | |
289 Stride_variable -> s | |
290 | Fixed_int x -> string_of_int x | |
291 | Fixed_string x -> x | |
292 | |
293 (* output the command line *) | |
294 let cmdline () = | |
295 List.fold_right (fun a b -> a ^ " " ^ b) (Array.to_list Sys.argv) "" | |
296 | |
297 let unparse tree = | |
298 "/* Generated by: " ^ (cmdline ()) ^ "*/\n\n" ^ | |
299 (C.print_cost tree) ^ | |
300 (if String.length !Magic.inklude > 0 | |
301 then | |
302 (Printf.sprintf "#include \"%s\"\n\n" !Magic.inklude) | |
303 else "") ^ | |
304 (if !Simdmagic.simd_mode then | |
305 Simd.unparse_function tree | |
306 else | |
307 C.unparse_function tree) | |
308 | |
309 let finalize_fcn ast = | |
310 let mergedecls = function | |
311 C.Block (d1, [C.Block (d2, s)]) -> C.Block (d1 @ d2, s) | |
312 | x -> x | |
313 and extract_constants = | |
314 if !Simdmagic.simd_mode then | |
315 Simd.extract_constants | |
316 else | |
317 C.extract_constants | |
318 | |
319 in mergedecls (C.Block (extract_constants ast, [ast; C.Simd_leavefun])) | |
320 | |
321 let twinstr_to_string vl x = | |
322 if !Simdmagic.simd_mode then | |
323 Twiddle.twinstr_to_simd_string vl x | |
324 else | |
325 Twiddle.twinstr_to_c_string x | |
326 | |
327 let make_volatile_stride n x = | |
328 C.CCall ("MAKE_VOLATILE_STRIDE", C.Comma((C.Integer n), x)) |