1 # a "yield" version of the Parallel Reduction REMAP algorithm.
2 # the algorithm is in-place. it does not perform "MV" operations.
3 # instead, where a masked-out value *should* be read from is tracked
4 from copy
import deepcopy
7 # python "yield" can be iterated. use this to make it clear how
8 # the indices are generated by using natural-looking nested loops
9 def iterate_indices(SVSHAPE
, pred
=None):
10 # get indices to iterate over, in the required order
12 # create lists of indices to iterate over in each dimension
14 # invert the indices if needed
15 if SVSHAPE
.invxyz
[0]: ix
.reverse()
16 # start a loop from the lowest step
22 # invert the indices if needed
23 if SVSHAPE
.invxyz
[1]: steps
.reverse()
25 stepend
= (step
== steps
[-1]) # note end of steps
26 idxs
= list(range(0, xd
, step
))
31 oi
= ix
[other
] if other
< xd
else None
32 other_pred
= other
< xd
and (pred
is None or pred
[oi
])
33 if (pred
is None or pred
[ci
]) and other_pred
:
34 if SVSHAPE
.skip
== 0b00: # submode 00
36 elif SVSHAPE
.skip
== 0b01: # submode 01
38 results
.append([result
+ SVSHAPE
.offset
, 0])
42 results
[-1][1] = (stepend
<<1) |
1 # notify end of loops
46 # set the dimension sizes here
53 SVSHAPE0
.lims
= [xdim
, 0, 0]
54 SVSHAPE0
.order
= [0,1,2]
57 SVSHAPE0
.offset
= 0 # experiment with different offset, here
58 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
61 SVSHAPE1
.lims
= [xdim
, 0, 0]
62 SVSHAPE1
.order
= [0,1,2]
65 SVSHAPE1
.offset
= 0 # experiment with different offset, here
66 SVSHAPE1
.invxyz
= [0,0,0] # inversion if desired
68 # enumerate over the iterator function, getting new indices
69 shapes
= list(iterate_indices(SVSHAPE0
)), \
70 list(iterate_indices(SVSHAPE1
))
71 for idx
in range(len(shapes
[0])):
76 print ("%d->%d:%d" % (idx
, l_idx
, r_idx
),
77 "end", bin(lend
)[2:], bin(rend
)[2:])
80 def preduce_y(vec
, pred
=None, operation
=None):
82 operation
= operator
.add
90 SVSHAPE0
.lims
= [xdim
, 0, 0]
91 SVSHAPE0
.order
= [0,1,2]
94 SVSHAPE0
.offset
= 0 # experiment with different offset, here
95 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
98 SVSHAPE1
.lims
= [xdim
, 0, 0]
99 SVSHAPE1
.order
= [0,1,2]
102 SVSHAPE1
.offset
= 0 # experiment with different offset, here
103 SVSHAPE1
.invxyz
= [0,0,0] # inversion if desired
105 # enumerate over the iterator function, getting new indices
106 shapes
= list(iterate_indices(SVSHAPE0
)), \
107 list(iterate_indices(SVSHAPE1
))
108 for idx
in range(len(shapes
[0])):
113 res
[l_idx
] = operation(res
[l_idx
], res
[r_idx
])
117 if __name__
== '__main__':
119 vec
= [1, 2, 3, 4, 9, 5, 6]