annotate src/fftw-3.3.5/genfft/genutil.ml @ 83:ae30d91d2ffe

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