add i-DCT SVP64 unit test for outer butterfly
[openpower-isa.git] / src / openpower / decoder / isa / svshape.py
1 from openpower.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
2 selectconcat)
3 from openpower.decoder.isa.remapyield import iterate_indices
4 from openpower.decoder.isa.remap_fft_yield import iterate_butterfly_indices
5 from openpower.decoder.isa.remap_dct_yield import (
6 iterate_dct_inner_butterfly_indices,
7 iterate_dct_inner_costable_indices,
8 iterate_dct_outer_butterfly_indices,
9 iterate_dct_inner_halfswap_loadstore)
10 from openpower.sv.svp64 import SVP64SHAPE
11 import os
12 from copy import deepcopy
13 from openpower.util import log
14
15
16 class SVSHAPE(SelectableInt):
17 def __init__(self, value):
18 SelectableInt.__init__(self, value, 32)
19 offs = 0
20 # set up sub-fields from Record layout
21 self.fsi = {}
22 l = deepcopy(SVP64SHAPE.layout)
23 l.reverse()
24 for field, width in l:
25 end = offs+width
26 fs = tuple(range(offs, end))
27 v = FieldSelectableInt(self, fs)
28 self.fsi[field] = v
29 log("SVSHAPE setup field", field, offs, end)
30 offs = end
31
32 @property
33 def submode2(self):
34 return self.fsi['permute'].asint(msb0=True)
35
36 @submode2.setter
37 def submode2(self, value):
38 self.fsi['permute'].eq(value)
39
40 @property
41 def order(self):
42 permute = self.fsi['permute'].asint(msb0=True)
43 return SVP64SHAPE.order(permute)
44
45 @order.setter
46 def order(self, value):
47 rorder = SVP64SHAPE.rorder(value)
48 self.fsi['permute'].eq(rorder)
49
50 @property
51 def xdimsz(self):
52 return self.fsi['xdimsz'].asint(msb0=True)+1
53
54 @xdimsz.setter
55 def xdimsz(self, value):
56 self.fsi['xdimsz'].eq(value-1)
57
58 @property
59 def ydimsz(self):
60 return self.fsi['ydimsz'].asint(msb0=True)+1
61
62 @ydimsz.setter
63 def ydimsz(self, value):
64 self.fsi['ydimsz'].eq(value-1)
65
66 @property
67 def zdimsz(self):
68 return self.fsi['zdimsz'].asint(msb0=True)+1
69
70 @zdimsz.setter
71 def zdimsz(self, value):
72 self.fsi['zdimsz'].eq(value-1)
73
74 @property
75 def lims(self):
76 return [self.xdimsz, self.ydimsz, self.zdimsz]
77
78 @lims.setter
79 def lims(self, value):
80 self.xdimsz = value[0]
81 self.ydimsz = value[1]
82 self.zdimsz = value[2]
83
84 @property
85 def invxyz(self):
86 inv = self.fsi['invxyz'].asint(msb0=True)
87 return [(inv & 0b1), (inv & 0b10) >> 1, (inv & 0b100) >> 2]
88
89 @invxyz.setter
90 def invxyz(self, value):
91 self.fsi['invxyz'].eq(value[0] | (value[1]<<1) | (value[2]<<2))
92
93 @property
94 def mode(self):
95 return self.fsi['mode'].asint(msb0=True)
96
97 @mode.setter
98 def mode(self, value):
99 self.fsi['mode'].eq(value)
100
101 @property
102 def skip(self):
103 return self.fsi['skip'].asint(msb0=True)
104
105 @skip.setter
106 def skip(self, value):
107 self.fsi['skip'].eq(value)
108
109 @property
110 def offset(self):
111 return self.fsi['offset'].asint(msb0=True)
112
113 @offset.setter
114 def offset(self, value):
115 self.fsi['offset'].eq(value)
116
117 def get_iterator(self):
118 log ("SVSHAPE get_iterator", self.mode, self.ydimsz)
119 if self.mode == 0b00:
120 iterate_fn = iterate_indices
121 elif self.mode in [0b01, 0b11]:
122 # further sub-selection
123 if self.ydimsz == 1:
124 iterate_fn = iterate_butterfly_indices
125 elif self.ydimsz in [2, 4]:
126 iterate_fn = iterate_dct_inner_butterfly_indices
127 elif self.ydimsz == 3:
128 iterate_fn = iterate_dct_outer_butterfly_indices
129 elif self.ydimsz == 5:
130 iterate_fn = iterate_dct_inner_costable_indices
131 elif self.ydimsz == 6:
132 iterate_fn = iterate_dct_inner_halfswap_loadstore
133 # create a **NEW** iterator each time this is called
134 return iterate_fn(deepcopy(self))
135
136
137 if __name__ == '__main__':
138 os.environ['SILENCELOG'] = "1"
139 xdim = 3
140 ydim = 2
141 zdim = 1
142 SVSHAPE0 = SVSHAPE(0)
143 SVSHAPE0.lims = [xdim, ydim, zdim]
144 SVSHAPE0.order = [1,0,2] # experiment with different permutations, here
145 SVSHAPE0.mode = 0b00
146 SVSHAPE0.skip = 0b00
147 SVSHAPE0.offset = 0 # experiment with different offset, here
148 SVSHAPE0.invxyz = [0,0,0] # inversion if desired
149
150 VL = xdim * ydim * zdim
151
152 print ("Matrix Mode")
153 for idx, new_idx in enumerate(SVSHAPE0.get_iterator()):
154 if idx >= VL:
155 break
156 print ("%d->%d" % (idx, new_idx))
157
158 print ("")
159 print ("FFT Mode")
160
161 # set the dimension sizes here
162 xdim = 8
163 ydim = 0 # not needed
164 zdim = 0 # again, not needed
165
166 # set total. err don't know how to calculate how many there are...
167 # do it manually for now
168
169 VL = 0
170 size = 2
171 n = xdim
172 while size <= n:
173 halfsize = size // 2
174 tablestep = n // size
175 for i in range(0, n, size):
176 for j in range(i, i + halfsize):
177 VL += 1
178 size *= 2
179
180 # j schedule
181 SVSHAPE0 = SVSHAPE(0)
182 SVSHAPE0.lims = [xdim, ydim, zdim]
183 SVSHAPE0.order = [0,1,2] # experiment with different permutations, here
184 SVSHAPE0.mode = 0b00
185 SVSHAPE0.offset = 0 # experiment with different offset, here
186 SVSHAPE0.invxyz = [0,0,0] # inversion if desired
187 # j+halfstep schedule
188 SVSHAPE1 = SVSHAPE(0)
189 SVSHAPE1.lims = [xdim, ydim, zdim]
190 SVSHAPE1.order = [0,1,2] # experiment with different permutations, here
191 SVSHAPE1.mode = 0b01
192 SVSHAPE1.offset = 0 # experiment with different offset, here
193 SVSHAPE1.invxyz = [0,0,0] # inversion if desired
194 # k schedule
195 SVSHAPE2 = SVSHAPE(0)
196 SVSHAPE2.lims = [xdim, ydim, zdim]
197 SVSHAPE2.order = [0,1,2] # experiment with different permutations, here
198 SVSHAPE2.mode = 0b10
199 SVSHAPE2.offset = 0 # experiment with different offset, here
200 SVSHAPE2.invxyz = [0,0,0] # inversion if desired
201
202 # enumerate over the iterator function, getting new indices
203 schedule = []
204 for idx, (jl, jh, k) in enumerate(zip(iterate_indices(SVSHAPE0),
205 iterate_indices(SVSHAPE1),
206 iterate_indices(SVSHAPE2))):
207 if idx >= VL:
208 break
209 schedule.append((jl, jh, k))
210
211 # ok now pretty-print the results, with some debug output
212 size = 2
213 idx = 0
214 while size <= n:
215 halfsize = size // 2
216 tablestep = n // size
217 print ("size %d halfsize %d tablestep %d" % \
218 (size, halfsize, tablestep))
219 for i in range(0, n, size):
220 prefix = "i %d\t" % i
221 k = 0
222 for j in range(i, i + halfsize):
223 jl, jh, ks = schedule[idx]
224 print (" %-3d\t%s j=%-2d jh=%-2d k=%-2d -> "
225 "j[jl=%-2d] j[jh=%-2d] exptable[k=%d]" % \
226 (idx, prefix, j, j+halfsize, k,
227 jl, jh, ks))
228 k += tablestep
229 idx += 1
230 size *= 2
231