From: Luke Kenneth Casson Leighton Date: Fri, 23 Jul 2021 10:09:53 +0000 (+0100) Subject: set up submodes for SVSHAPE, to include DCT butterfly yielders X-Git-Tag: xlen-bcd~230 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=08f8894443c227bc046528ad1277a453dd0fcd94;p=openpower-isa.git set up submodes for SVSHAPE, to include DCT butterfly yielders --- diff --git a/src/openpower/decoder/isa/fastdct-test.py b/src/openpower/decoder/isa/fastdct-test.py index b1db7803..fab45e37 100644 --- a/src/openpower/decoder/isa/fastdct-test.py +++ b/src/openpower/decoder/isa/fastdct-test.py @@ -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): diff --git a/src/openpower/decoder/isa/remap_dct_yield.py b/src/openpower/decoder/isa/remap_dct_yield.py index b88b6726..d4a973be 100644 --- a/src/openpower/decoder/isa/remap_dct_yield.py +++ b/src/openpower/decoder/isa/remap_dct_yield.py @@ -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 diff --git a/src/openpower/decoder/isa/svshape.py b/src/openpower/decoder/isa/svshape.py index 97df57ae..c2e1968d 100644 --- a/src/openpower/decoder/isa/svshape.py +++ b/src/openpower/decoder/isa/svshape.py @@ -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))