1 # a "yield" version of the REMAP algorithm. a little easier to read
2 # than the Finite State Machine version
4 # python "yield" can be iterated. use this to make it clear how
5 # the indices are generated by using natural-looking nested loops
6 def iterate_indices(SVSHAPE
):
7 # get indices to iterate over, in the required order
11 # create lists of indices to iterate over in each dimension
15 # invert the indices if needed
16 if SVSHAPE
.invxyz
[0]: x_r
.reverse()
17 if SVSHAPE
.invxyz
[1]: y_r
.reverse()
18 if SVSHAPE
.invxyz
[2]: z_r
.reverse()
19 # start an infinite (wrapping) loop
20 step
= 0 # track src/dst step
22 for z
in z_r
: # loop over 1st order dimension
24 for y
in y_r
: # loop over 2nd order dimension
26 for x
in x_r
: # loop over 3rd order dimension
28 # ok work out which order to construct things in.
29 # start by creating a list of tuples of the dimension
31 vals
= [(SVSHAPE
.lims
[0], x
, "x"),
32 (SVSHAPE
.lims
[1], y
, "y"),
33 (SVSHAPE
.lims
[2], z
, "z")
35 # now select those by order. this allows us to
36 # create schedules for [z][x], [x][y], or [y][z]
37 # for matrix multiply.
38 vals
= [vals
[SVSHAPE
.order
[0]],
39 vals
[SVSHAPE
.order
[1]],
40 vals
[SVSHAPE
.order
[2]]
42 # ok now we can construct the result, using bits of
43 # "order" to say which ones get stacked on
47 lim
, idx
, dbg
= vals
[i
]
48 # some of the dimensions can be "skipped". the order
49 # was actually selected above on all 3 dimensions,
50 # e.g. [z][x][y] or [y][z][x]. "skip" allows one of
51 # those to be knocked out
52 if SVSHAPE
.skip
== i
+1: continue
53 #print ("select %d %s" % (i, dbg))
54 idx
*= mult
# shifts up by previous dimension(s)
55 result
+= idx
# adds on this dimension
56 mult
*= lim
# for the next dimension
59 ((y_end
and x_end
)<<1) |
60 ((y_end
and x_end
and z_end
)<<2))
62 if hasattr(SVSHAPE
, "postprocess"): # for Indexed mode
63 result
= SVSHAPE
.postprocess(result
, step
)
64 yield result
+ SVSHAPE
.offset
, loopends
67 # set the dimension sizes here
72 # set total (can repeat, e.g. VL=x*y*z*4)
73 VL
= xdim
* ydim
* zdim
79 SVSHAPE0
.lims
= [xdim
, ydim
, zdim
]
80 SVSHAPE0
.order
= [1,0,2] # experiment with different permutations, here
83 SVSHAPE0
.offset
= 0 # experiment with different offset, here
84 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
86 # enumerate over the iterator function, getting new indices
87 for idx
, (new_idx
, end
) in enumerate(iterate_indices(SVSHAPE0
)):
90 print ("%d->%d" % (idx
, new_idx
), "end", bin(end
)[2:])
93 if __name__
== '__main__':