set up submodes for SVSHAPE, to include DCT butterfly yielders
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 23 Jul 2021 10:09:53 +0000 (11:09 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 23 Jul 2021 10:09:53 +0000 (11:09 +0100)
src/openpower/decoder/isa/fastdct-test.py
src/openpower/decoder/isa/remap_dct_yield.py
src/openpower/decoder/isa/svshape.py

index b1db7803b8728c9fae52bba3e6f2daa1fee3f8f3..fab45e37e08df267b98e151097ee76ae80ab380a 100644 (file)
@@ -50,7 +50,7 @@ class FastDctTest(unittest.TestCase):
             actual = fastdctlee.inverse_transform(vector)
             self.assertListAlmostEqual(actual, expect)
 
-    def notest_fast_dct_lee_invertibility(self):
+    def test_fast_dct_lee_invertibility(self):
         for i in range(1, 10):
             n = 2**i
             vector = FastDctTest.random_vector(n)
@@ -59,6 +59,15 @@ class FastDctTest(unittest.TestCase):
             temp = [(val * 2.0 / n) for val in temp]
             self.assertListAlmostEqual(vector, temp)
 
+    def test_yield_fast_dct_lee_invertibility(self):
+        for i in range(1, 10):
+            n = 2**i
+            vector = FastDctTest.random_vector(n)
+            temp = remap_dct_yield.transform2(vector)
+            temp = fastdctlee.inverse_transform(temp)
+            temp = [(val * 2.0 / n) for val in temp]
+            self.assertListAlmostEqual(vector, temp)
+
     def assertListAlmostEqual(self, actual, expect):
         self.assertEqual(len(actual), len(expect))
         for (x, y) in zip(actual, expect):
index b88b67268335d0e9db43f76777e72ecd63541ebe..d4a973be3d6455fbbb2ff6f45ed4ccf18833c520 100644 (file)
@@ -63,7 +63,7 @@ def iterate_dct_inner_butterfly_indices(SVSHAPE):
 
     # reference (read/write) the in-place data in *reverse-bit-order*
     ri = list(range(n))
-    if SVSHAPE.mode == 0b01:
+    if SVSHAPE.submode2 == 0b01:
         levels = n.bit_length() - 1
         ri = [ri[reverse_bits(i, levels)] for i in range(n)]
 
@@ -71,7 +71,7 @@ def iterate_dct_inner_butterfly_indices(SVSHAPE):
     # *indices* are referenced (two levels of indirection at the moment)
     # pre-reverse the data-swap list so that it *ends up* in the order 0123..
     ji = list(range(n))
-    inplace_mode = SVSHAPE.mode == 0b01 and SVSHAPE.skip not in [0b10, 0b11]
+    inplace_mode = SVSHAPE.submode2 == 0b01 and SVSHAPE.skip not in [0b10, 0b11]
     if inplace_mode:
         #print ("inplace mode")
         ji = halfrev2(ji, True)
@@ -102,24 +102,17 @@ def iterate_dct_inner_butterfly_indices(SVSHAPE):
                 hz2 = halfsize // 2 # zero stops reversing 1-item lists
                 # if you *really* want to do the in-place swapping manually,
                 # this allows you to do it.  good luck...
-                if SVSHAPE.mode == 0b01 and not inplace_mode:
+                if SVSHAPE.submode2 == 0b01 and not inplace_mode:
                     #print ("swap mode")
                     jr = j_r[:hz2]
                 #print ("xform jr", jr)
                 for jl, jh in zip(j, jr):   # loop over 1st order dimension
                     z_end = jl == j[-1]
                     # now depending on MODE return the index.  inner butterfly
-                    if SVSHAPE.mode == 0b01:
-                        if SVSHAPE.skip in [0b00, 0b10]:
-                            result = ri[ji[jl]]        # lower half
-                        elif SVSHAPE.skip in [0b01, 0b11]:
-                            result = ri[ji[jh]] # upper half, reverse order
-                    # outer butterfly
-                    elif SVSHAPE.mode == 0b10:
-                        if SVSHAPE.skip == 0b00:
-                            result = ri[ji[jl]]        # lower half
-                        elif SVSHAPE.skip == 0b01:
-                            result = ri[ji[jl+size]]   # upper half
+                    if SVSHAPE.skip in [0b00, 0b10]:
+                        result = ri[ji[jl]]        # lower half
+                    elif SVSHAPE.skip in [0b01, 0b11]:
+                        result = ri[ji[jh]] # upper half, reverse order
                     loopends = (z_end |
                                ((y_end and z_end)<<1) |
                                 ((y_end and x_end and z_end)<<2))
@@ -127,7 +120,7 @@ def iterate_dct_inner_butterfly_indices(SVSHAPE):
                     yield result + SVSHAPE.offset, loopends
 
                 # now in-place swap
-                if SVSHAPE.mode == 0b01 and inplace_mode:
+                if inplace_mode:
                     for ci, (jl, jh) in enumerate(zip(j[:hz2], jr[:hz2])):
                         jlh = jl+halfsize
                         #print ("inplace swap", jh, jlh)
@@ -159,7 +152,7 @@ def iterate_dct_outer_butterfly_indices(SVSHAPE):
 
     # reference (read/write) the in-place data in *reverse-bit-order*
     ri = list(range(n))
-    if SVSHAPE.mode == 0b11:
+    if SVSHAPE.submode2 == 0b11:
         levels = n.bit_length() - 1
         ri = [ri[reverse_bits(i, levels)] for i in range(n)]
 
@@ -207,7 +200,7 @@ def iterate_dct_outer_butterfly_indices(SVSHAPE):
                     yield result + SVSHAPE.offset, loopends
 
                 # now in-place swap
-                if SVSHAPE.mode == 0b11 and inplace_mode:
+                if SVSHAPE.submode2 == 0b11 and inplace_mode:
                     j = list(range(i, i + halfsize))
                     jr = list(range(i+halfsize, i + size))
                     jr.reverse()
@@ -309,6 +302,7 @@ def transform2(vec):
     SVSHAPE0.lims = [xdim, ydim, zdim]
     SVSHAPE0.order = [0,1,2]  # experiment with different permutations, here
     SVSHAPE0.mode = 0b01
+    SVSHAPE0.submode2 = 0b01
     SVSHAPE0.skip = 0b00
     SVSHAPE0.offset = 0       # experiment with different offset, here
     SVSHAPE0.invxyz = [1,0,0] # inversion if desired
@@ -317,6 +311,7 @@ def transform2(vec):
     SVSHAPE1.lims = [xdim, ydim, zdim]
     SVSHAPE1.order = [0,1,2]  # experiment with different permutations, here
     SVSHAPE1.mode = 0b01
+    SVSHAPE1.submode2 = 0b01
     SVSHAPE1.skip = 0b01
     SVSHAPE1.offset = 0       # experiment with different offset, here
     SVSHAPE1.invxyz = [1,0,0] # inversion if desired
@@ -345,7 +340,8 @@ def transform2(vec):
     SVSHAPE0 = SVSHAPE()
     SVSHAPE0.lims = [xdim, ydim, zdim]
     SVSHAPE0.order = [0,1,2]  # experiment with different permutations, here
-    SVSHAPE0.mode = 0b10
+    SVSHAPE0.submode2 = 0b10
+    SVSHAPE0.mode = 0b01
     SVSHAPE0.skip = 0b00
     SVSHAPE0.offset = 0       # experiment with different offset, here
     SVSHAPE0.invxyz = [0,0,0] # inversion if desired
@@ -353,7 +349,8 @@ def transform2(vec):
     SVSHAPE1 = SVSHAPE()
     SVSHAPE1.lims = [xdim, ydim, zdim]
     SVSHAPE1.order = [0,1,2]  # experiment with different permutations, here
-    SVSHAPE1.mode = 0b10
+    SVSHAPE1.mode = 0b01
+    SVSHAPE1.submode2 = 0b10
     SVSHAPE1.skip = 0b01
     SVSHAPE1.offset = 0       # experiment with different offset, here
     SVSHAPE1.invxyz = [0,0,0] # inversion if desired
@@ -429,6 +426,7 @@ def demo():
     SVSHAPE0.lims = [xdim, ydim, zdim]
     SVSHAPE0.order = [0,1,2]  # experiment with different permutations, here
     SVSHAPE0.mode = 0b10
+    SVSHAPE0.submode2 = 0b100
     SVSHAPE0.skip = 0b10
     SVSHAPE0.offset = 0       # experiment with different offset, here
     SVSHAPE0.invxyz = [1,0,0] # inversion if desired
@@ -437,6 +435,7 @@ def demo():
     SVSHAPE1.lims = [xdim, ydim, zdim]
     SVSHAPE1.order = [0,1,2]  # experiment with different permutations, here
     SVSHAPE1.mode = 0b10
+    SVSHAPE1.submode2 = 0b100
     SVSHAPE1.skip = 0b11
     SVSHAPE1.offset = 0       # experiment with different offset, here
     SVSHAPE1.invxyz = [1,0,0] # inversion if desired
index 97df57aeb7889eb35fd44fabbd97ccfd2e30b64f..c2e1968df2ad7c014bdfc8059c0d941766f5d85d 100644 (file)
@@ -2,6 +2,9 @@ from openpower.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
                                         selectconcat)
 from openpower.decoder.isa.remapyield import iterate_indices
 from openpower.decoder.isa.remap_fft_yield import iterate_butterfly_indices
+from openpower.decoder.isa.remap_dct_yield import (
+                                iterate_dct_inner_butterfly_indices,
+                                iterate_dct_outer_butterfly_indices)
 from openpower.sv.svp64 import SVP64SHAPE
 import os
 from copy import deepcopy
@@ -24,6 +27,14 @@ class SVSHAPE(SelectableInt):
             #log("SVSHAPE setup field", field, offs, end)
             offs = end
 
+    @property
+    def submode2(self):
+        return self.fsi['permute'].asint(msb0=True)
+
+    @submode2.setter
+    def submode2(self, value):
+        self.fsi['permute'].eq(value)
+
     @property
     def order(self):
         permute = self.fsi['permute'].asint(msb0=True)
@@ -105,7 +116,13 @@ class SVSHAPE(SelectableInt):
         if self.mode == 0b00:
             iterate_fn = iterate_indices
         elif self.mode == 0b01:
-            iterate_fn = iterate_butterfly_indices
+            # further sub-selection
+            if self.submode2 == 0b000:
+                iterate_fn = iterate_butterfly_indices
+            elif self.submode2 in [0b001, 0b010]:
+                iterate_fn = iterate_dct_inner_butterfly_indices
+            elif self.submode2 in [0b011, 0b100]:
+                iterate_fn = iterate_dct_outer_butterfly_indices
         # create a **NEW** iterator each time this is called
         return iterate_fn(deepcopy(self))