src/Loops.jl

Wed, 22 Dec 2021 11:14:38 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 22 Dec 2021 11:14:38 +0200
changeset 35
d881275c6564
child 37
f8be66557e0f
permissions
-rw-r--r--

Add metaprogramming tools and fast multidimensional loops.

35
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 ###############################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 # Fast multi-dimensional loops
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 ###############################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 `module AlgTools.Loops`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 This module implements `for_zip`, `for_indices`, and `for_linspace` generated
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 functions for loops amenable to a high level of optimisation by the compiler.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 module Loops
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 using ..Metaprogramming
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 ##############
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 # Our exports
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 ##############
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 export Box,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 Grid,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 @Grid_str,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 for_zip,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 for_indices,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 for_linspace
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 #####################################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 # Looping over many iterators/arrays
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 #####################################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 `for_zip(f, a...)`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 With `dims` of type `Dims{N}`, loop over all `(i_1,…,i_N)` with `i_j ∈ 1:dims[j]`.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 Typically to be used as
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 ```julia
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 for_zip(a, b) do x, y
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 # do something
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 ```
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 @generated function for_zip(f :: Function, a...)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 # Generate reference variables to avoid execution of potential
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 # code inputs several times.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 aref = [gensym("aref_$(j)") for j ∈ 1:length(a)]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 # Generate length-checking asserts
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 asserts = ( :( length($b)==M ) for b ∈ aref[2:end] )
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 quote
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 # Assign input expressions to reference variables
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 local $(lift_exprs(aref)) = (a...,)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 # Check that all inputs are of equal length
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 M = length($(aref[1]))
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 @assert $(all_exprs(asserts)) "Parameter lengths have to be equal"
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 # Do the loop
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 for i = 1:M
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 f($([ :( $c[i] ) for c ∈ aref]...))
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 #######################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 # Looping over indices
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 #######################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 `for_indices(f, N, dims)`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 With `dims` of type `Dims{N}`, loop over all `(i_1,…,i_N)` with `i_j ∈ 1:dims[j]`.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 Typically to be used as
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 ```julia
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 for_indices(N, dims) do i_1, …, i_N
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 # do something
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 ```
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 @generated function for_indices(f :: Function, dims :: Dims{N}) where N
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 # This depends on numbers being passed as numbers, not Exprs!
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 local i = [gensym("i_$(j)") for j ∈ 1:N]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 local di = [gensym("di_$(j)") for j ∈ 1:N]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 local expr = :( f($(i...),) )
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 for j = 1:N
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 expr = quote
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 for $(i[j]) = 1:$(di[j])
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 $expr
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 quote
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 $(lift_exprs(di)) = dims
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 $expr
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 ##########################################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 # Looping over indices and transformation
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 ##########################################
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 Box{N, T} = NTuple{N, Tuple{T, T}}
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 struct Grid{R} end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 `@Grid_str`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 A convenience macro for writing Grid{:gridtype} as Grid"gridtype" for use with `for_linspace`.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
110 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 macro Grid_str(s)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 :(Grid{$(Expr(:quote, Symbol(s)))})
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 # For type-checking user's code, it would be better to wrap `for_linspace`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 # with a multiple dispatch type-case selector. However, the approach of
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 # avoiding a wrapper and calling `gridalign` from `for_linspace` to get
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 # the grid parements helps with inlining the code.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 @inline gridalign(:: Type{Type{Grid{:midpoint}}}) = (0.5, 0)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 @inline gridalign(:: Type{Type{Grid{:firstpoint}}}) = (1.0, 0)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 @inline gridalign(:: Type{Type{Grid{:lastpoint}}}) = (0.0, 0)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 @inline gridalign(:: Type{Type{Grid{:linspace}}}) = (1.0, 1)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 `for_linspace(f :: Function, dims :: Dims{N} , box :: Box{N, T}, grid :: Type{Grid{G}} = Grid"linspace")`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 With `box` of type `Box{N, T} = NTuple{N, Tuple{T, T}}` with `T <: AbstractFloat`,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 loop over all `((i_1,…,i_N), (x_1,…,x_N))` with `i_j ∈ 1:dims[j]` and each `x_i`
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 sampled in equal-length subintervals of the interval `box[i]`.
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 If `grid` is `Grid"midpoint"`, `Grid"firstpoint"`, `Grid"lastpoint"`, the point `x_i` is
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 the mid-point, first point, or last point of the corresponding subinterval, and there
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 are `dims[j]` subintervals. If `grid` is `Grid"linspace"`, there are `dims[j]-1` subintervals,
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 and all the endpoints are generated. Typically to be used as
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 ```julia
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 for_linspace(dims, box) do (i_1, …, i_N), (x_1, …, x_N)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 # do something
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 ```
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 """
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 @inline @generated function
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 for_linspace(f :: Function, dims :: Dims{N}, box :: Box{N, T},
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 grid :: Type{Grid{G}} = Grid"linspace") where {N, T <: AbstractFloat, G}
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 shift, extrapoints = gridalign(grid)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 # Generate some local variables of primitive types, storable in registers
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 i = [gensym("i_$j") for j ∈ 1:N]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 c = [gensym("c_$j") for j ∈ 1:N]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 d = [gensym("d_$j") for j ∈ 1:N]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 n = [gensym("n_$j") for j ∈ 1:N]
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 # Function call
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 x = (:( $(i[j])*$(c[j])+$(d[j]) ) for j ∈ 1:N)
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 expr = :( f( ($(i...),), ($(x...),) ) )
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 # Main recursion
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158 for j = 1:N
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
159 expr = quote
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
160 for $(i[j]) = 1:$(n[j])
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 $expr
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 # Initialisation of linear transformation and variable references
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 asserts = ( :( @assert ($(n[j]) > extrapoints) "Dimension $j too small" ) for j ∈ 1:N )
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168 scales = ( :( (box[$j][2]-box[$j][1])/($(n[j])-extrapoints) ) for j ∈ 1:N )
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169 translates = ( :( box[$j][1] - shift*$(c[j]) ) for j ∈ 1:N )
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170 expr = quote
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171 # Set up local (register-storable) variables for dims, needed in the loop above
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 local $(lift_exprs(n)) = dims
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 # Check everything is ok
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174 $(sequence_exprs(asserts))
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 # Set up linear transformation, needed in the loop above
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 local $(lift_exprs(c)) = $(lift_exprs(scales))
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177 local $(lift_exprs(d)) = $(lift_exprs(translates))
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 # Execute the loop
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 $expr
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 end
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
182
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
183
d881275c6564 Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 end # module

mercurial