add remapyield.py version of remap.py
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 1 Jul 2021 12:18:30 +0000 (13:18 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 1 Jul 2021 12:18:33 +0000 (13:18 +0100)
openpower/sv/remap.mdwn
openpower/sv/remapyield.py [new file with mode: 0644]

index 0086f4520baee3645728eeff8dc6902c5cda423c..1aa3df513d08dd7377a8f6506ba0ff53f46c86df 100644 (file)
@@ -41,6 +41,11 @@ executed as a python program:
 [[!inline quick="yes" raw="yes" pages="openpower/sv/remap.py" ]]
 ```
 
+An easier-to-read version (using python iterators) shows the loop nesting:
+```
+[[!inline quick="yes" raw="yes" pages="openpower/sv/remapyield.py" ]]
+```
+
 Each element index from the for-loop `0..VL-1`
 is run through the above algorithm to work out the **actual** element
 index, instead.  Given that there are four possible SHAPE entries, up to
diff --git a/openpower/sv/remapyield.py b/openpower/sv/remapyield.py
new file mode 100644 (file)
index 0000000..ff492f4
--- /dev/null
@@ -0,0 +1,50 @@
+# a "yield" version of the REMAP algorithm. a little easier to read
+# than the Finite State Machine version
+
+# set the dimension sizes here
+xdim = 3
+ydim = 2
+zdim = 1
+
+# set total (can repeat, e.g. VL=x*y*z*4)
+VL = xdim * ydim * zdim
+
+lims = [xdim, ydim, zdim]
+idxs = [0,0,0]   # starting indices
+order = [1,0,2]  # experiment with different permutations, here
+offset = 0       # experiment with different offset, here
+invxyz = [0,1,0] # inversion if desired
+
+
+# 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():
+    # get indices to iterate over, in the required order
+    xd = lims[order[2]]
+    yd = lims[order[1]]
+    zd = lims[order[0]]
+    # create lists of indices to iterate over in each dimension
+    x_r = list(range(xd))
+    y_r = list(range(yd))
+    z_r = list(range(zd))
+    # invert the indices if needed
+    if invxyz[order[2]]: x_r.reverse()
+    if invxyz[order[1]]: y_r.reverse()
+    if invxyz[order[0]]: z_r.reverse()
+    # start an infinite (wrapping) loop
+    while True:
+        for x in x_r:           # loop over 3rd order dimension
+            for y in y_r:       # loop over 2nd order dimension
+                for z in z_r:   # loop over 1st order dimension
+                    # construct the (up to) 3D remap schedule
+                    yield (x + y * xd + z * xd * yd)
+
+
+# enumerate over the iterator function, getting new indices
+for idx, new_idx in enumerate(iterate_indices()):
+    if idx < offset:
+        continue
+    if idx >= offset + VL:
+        break
+    print ("%d->%d" % (idx, new_idx))
+