-# a "yield" version of the Parallel Reduction REMAP algorithm.
+# a "yield" version of the Parallel Reduction REMAP algorithm.
# the algorithm is in-place. it does not perform "MV" operations.
# instead, where a masked-out value *should* be read from is tracked
from copy import deepcopy
import operator
+
# python "yield" can be iterated. use this to make it clear how
# the indices are generated by using natural-looking nested loops
def iterate_indices(SVSHAPE, pred=None):
# create lists of indices to iterate over in each dimension
ix = list(range(xd))
# invert the indices if needed
- if SVSHAPE.invxyz[0]: ix.reverse()
+ if SVSHAPE.invxyz[0]:
+ ix.reverse()
# start a loop from the lowest step
- step = 1
+ step = 1
steps = []
while step < xd:
step *= 2
steps.append(step)
# invert the indices if needed
- if SVSHAPE.invxyz[1]: steps.reverse()
+ if SVSHAPE.invxyz[1]:
+ steps.reverse()
for step in steps:
- stepend = (step == steps[-1]) # note end of steps
+ stepend = (step == steps[-1]) # note end of steps
idxs = list(range(0, xd, step))
results = []
for i in idxs:
oi = ix[other] if other < xd else None
other_pred = other < xd and (pred is None or pred[oi])
if (pred is None or pred[ci]) and other_pred:
- if SVSHAPE.skip == 0b00: # submode 00
+ if SVSHAPE.skip == 0b00: # submode 00
result = ci
- elif SVSHAPE.skip == 0b01: # submode 01
+ elif SVSHAPE.skip == 0b01: # submode 01
result = oi
results.append([result + SVSHAPE.offset, 0])
elif other_pred:
ix[i] = oi
if results:
- results[-1][1] = (stepend<<1) | 1 # notify end of loops
+ results[-1][1] = (stepend << 1) | 1 # notify end of loops
yield from results
+
def demo():
# set the dimension sizes here
xdim = 9
pass
SVSHAPE0 = SVSHAPE()
SVSHAPE0.lims = [xdim, 0, 0]
- SVSHAPE0.order = [0,1,2]
+ SVSHAPE0.order = [0, 1, 2]
SVSHAPE0.mode = 0b10
SVSHAPE0.skip = 0b00
SVSHAPE0.offset = 0 # experiment with different offset, here
- SVSHAPE0.invxyz = [0,0,0] # inversion if desired
+ SVSHAPE0.invxyz = [0, 0, 0] # inversion if desired
SVSHAPE1 = SVSHAPE()
SVSHAPE1.lims = [xdim, 0, 0]
- SVSHAPE1.order = [0,1,2]
+ SVSHAPE1.order = [0, 1, 2]
SVSHAPE1.mode = 0b10
SVSHAPE1.skip = 0b01
SVSHAPE1.offset = 0 # experiment with different offset, here
- SVSHAPE1.invxyz = [0,0,0] # inversion if desired
+ SVSHAPE1.invxyz = [0, 0, 0] # inversion if desired
# enumerate over the iterator function, getting new indices
- shapes = list(iterate_indices(SVSHAPE0)), \
- list(iterate_indices(SVSHAPE1))
+ shapes = list(iterate_indices(SVSHAPE0)), list(iterate_indices(SVSHAPE1))
for idx in range(len(shapes[0])):
l = shapes[0][idx]
r = shapes[1][idx]
(l_idx, lend) = l
(r_idx, rend) = r
- print ("%d->%d:%d" % (idx, l_idx, r_idx),
- "end", bin(lend)[2:], bin(rend)[2:])
+ print("%d->%d:%d" % (idx, l_idx, r_idx),
+ "end", bin(lend)[2:], bin(rend)[2:])
def preduce_y(vec, pred=None, operation=None):
res = deepcopy(vec)
xdim = len(vec)
# set up an SVSHAPE
+
class SVSHAPE:
pass
SVSHAPE0 = SVSHAPE()
SVSHAPE0.lims = [xdim, 0, 0]
- SVSHAPE0.order = [0,1,2]
+ SVSHAPE0.order = [0, 1, 2]
SVSHAPE0.mode = 0b10
SVSHAPE0.skip = 0b00
SVSHAPE0.offset = 0 # experiment with different offset, here
- SVSHAPE0.invxyz = [0,0,0] # inversion if desired
+ SVSHAPE0.invxyz = [0, 0, 0] # inversion if desired
SVSHAPE1 = SVSHAPE()
SVSHAPE1.lims = [xdim, 0, 0]
- SVSHAPE1.order = [0,1,2]
+ SVSHAPE1.order = [0, 1, 2]
SVSHAPE1.mode = 0b10
SVSHAPE1.skip = 0b01
SVSHAPE1.offset = 0 # experiment with different offset, here
- SVSHAPE1.invxyz = [0,0,0] # inversion if desired
+ SVSHAPE1.invxyz = [0, 0, 0] # inversion if desired
# enumerate over the iterator function, getting new indices
- shapes = list(iterate_indices(SVSHAPE0)), \
- list(iterate_indices(SVSHAPE1))
+ shapes = list(iterate_indices(SVSHAPE0)), list(iterate_indices(SVSHAPE1))
for idx in range(len(shapes[0])):
l = shapes[0][idx]
r = shapes[1][idx]
res[l_idx] = operation(res[l_idx], res[r_idx])
return res
+
# run the demo
if __name__ == '__main__':
demo()
vec = [1, 2, 3, 4, 9, 5, 6]
res = preduce_y(vec)
- print (vec)
- print (res)
+ print(vec)
+ print(res)