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)) | 
