annotate src/fftw-3.3.8/genfft/genutil.ml @ 168:ceec0dd9ec9c

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