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 # some of the dimensions can be "skipped". the order
43 # was actually selected above on all 3 dimensions,
44 # e.g. [z][x][y] or [y][z][x]. "skip" allows one of
45 # those to be knocked out
46 if SVSHAPE
.skip
== 0b00:
48 elif SVSHAPE
.skip
== 0b11:
50 elif SVSHAPE
.skip
== 0b01:
52 elif SVSHAPE
.skip
== 0b10:
58 # ok now we can construct the result, using bits of
59 # "order" to say which ones get stacked on
61 lim
, idx
, dbg
= vals
[i
]
63 #print ("select %d %s" % (i, dbg))
64 idx
*= mult
# shifts up by previous dimension(s)
65 result
+= idx
# adds on this dimension
66 mult
*= lim
# for the next dimension
69 ((y_end
and x_end
)<<1) |
70 ((y_end
and x_end
and z_end
)<<2))
72 if hasattr(SVSHAPE
, "postprocess"): # for Indexed mode
73 result
= SVSHAPE
.postprocess(result
, step
)
74 yield result
+ SVSHAPE
.offset
, loopends
77 # set the dimension sizes here
82 # set total (can repeat, e.g. VL=x*y*z*4)
83 VL
= xdim
* ydim
* zdim
89 SVSHAPE0
.lims
= [xdim
, ydim
, zdim
]
90 SVSHAPE0
.order
= [1,0,2] # experiment with different permutations, here
93 SVSHAPE0
.offset
= 0 # experiment with different offset, here
94 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
96 # enumerate over the iterator function, getting new indices
97 for idx
, (new_idx
, end
) in enumerate(iterate_indices(SVSHAPE0
)):
100 print ("%d->%d" % (idx
, new_idx
), "end", bin(end
)[2:])
103 if __name__
== '__main__':