1 """provides convenient field mappings for SVSHAPE in different modes
3 the trickiest is Indexed mode which sits inside Matrix using two of
4 permute options to activate.
6 https://libre-soc.org/openpower/sv/remap
9 from openpower
.decoder
.selectable_int
import (FieldSelectableInt
, SelectableInt
,
11 from openpower
.decoder
.isa
.remapyield
import iterate_indices
12 from openpower
.decoder
.isa
.remap_fft_yield
import iterate_butterfly_indices
13 from openpower
.decoder
.isa
.remap_dct_yield
import (
14 iterate_dct_inner_butterfly_indices
,
15 iterate_dct_inner_costable_indices
,
16 iterate_dct_outer_butterfly_indices
,
17 iterate_dct_inner_halfswap_loadstore
)
18 from openpower
.sv
.svp64
import SVP64SHAPE
20 from copy
import deepcopy
21 from openpower
.util
import log
24 class SVSHAPE(SelectableInt
):
25 def __init__(self
, value
):
26 SelectableInt
.__init
__(self
, value
, 32)
28 # set up sub-fields from Record layout
30 l
= deepcopy(SVP64SHAPE
.layout
)
32 for field
, width
in l
:
34 fs
= tuple(range(offs
, end
))
35 v
= FieldSelectableInt(self
, fs
)
37 log("SVSHAPE setup field", field
, offs
, end
)
42 return self
.mode
== 0b00 and self
.submode2
in [0b110, 0b111]
46 return self
.fsi
['permute'].asint(msb0
=True)
49 def submode2(self
, value
):
50 self
.fsi
['permute'].eq(value
)
54 permute
= self
.fsi
['permute'].asint(msb0
=True)
56 permute
-= 0b110 # xyz or yxz
57 return SVP64SHAPE
.order(permute
)
60 def order(self
, value
):
61 rorder
= SVP64SHAPE
.rorder(value
)
62 self
.fsi
['permute'].eq(rorder
)
66 return self
.fsi
['xdimsz'].asint(msb0
=True)+1
69 def xdimsz(self
, value
):
70 self
.fsi
['xdimsz'].eq(value
-1)
74 return self
.fsi
['ydimsz'].asint(msb0
=True)+1
77 def ydimsz(self
, value
):
78 self
.fsi
['ydimsz'].eq(value
-1)
82 return self
.fsi
['zdimsz'].asint(msb0
=True) << 1
86 z
= self
.fsi
['zdimsz'].asint(msb0
=True)+1
88 z
= 1 # no z dimension when indexed
92 def zdimsz(self
, value
):
93 self
.fsi
['zdimsz'].eq(value
-1)
97 return [self
.xdimsz
, self
.ydimsz
, self
.zdimsz
]
100 def lims(self
, value
):
101 self
.xdimsz
= value
[0]
102 self
.ydimsz
= value
[1]
103 self
.zdimsz
= value
[2]
107 inv
= self
.fsi
['invxyz'].asint(msb0
=True)
108 if self
.is_indexed():
109 inv
&= 0b011 # no 3rd z in indexed mode
110 return [(inv
& 0b1), (inv
& 0b10) >> 1, (inv
& 0b100) >> 2]
113 def invxyz(self
, value
):
114 self
.fsi
['invxyz'].eq(value
[0] |
(value
[1]<<1) |
(value
[2]<<2))
118 return self
.fsi
['mode'].asint(msb0
=True)
121 def mode(self
, value
):
122 self
.fsi
['mode'].eq(value
)
126 return self
.fsi
['skip'].asint(msb0
=True)
130 if self
.is_indexed():
131 inv
= self
.fsi
['invxyz'].asint(msb0
=True)
132 return (inv
& 0b100) >> 2
133 return self
.fsi
['skip'].asint(msb0
=True)
136 def skip(self
, value
):
137 self
.fsi
['skip'].eq(value
)
141 return self
.fsi
['offset'].asint(msb0
=True)
144 def offset(self
, value
):
145 self
.fsi
['offset'].eq(value
)
147 def get_iterator(self
):
148 log ("SVSHAPE get_iterator", self
.mode
, self
.ydimsz
)
149 if self
.mode
== 0b00:
150 iterate_fn
= iterate_indices
151 elif self
.mode
in [0b01, 0b11]:
152 # further sub-selection
154 iterate_fn
= iterate_butterfly_indices
155 elif self
.ydimsz
in [2, 4]:
156 iterate_fn
= iterate_dct_inner_butterfly_indices
157 elif self
.ydimsz
== 3:
158 iterate_fn
= iterate_dct_outer_butterfly_indices
159 elif self
.ydimsz
in [5, 13]:
160 iterate_fn
= iterate_dct_inner_costable_indices
161 elif self
.ydimsz
in [6, 14, 15]:
162 iterate_fn
= iterate_dct_inner_halfswap_loadstore
163 # create a **NEW** iterator each time this is called
164 return iterate_fn(deepcopy(self
))
167 if __name__
== '__main__':
168 os
.environ
['SILENCELOG'] = "1"
172 SVSHAPE0
= SVSHAPE(0)
173 SVSHAPE0
.lims
= [xdim
, ydim
, zdim
]
174 SVSHAPE0
.order
= [1,0,2] # experiment with different permutations, here
177 SVSHAPE0
.offset
= 0 # experiment with different offset, here
178 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
180 VL
= xdim
* ydim
* zdim
182 print ("Matrix Mode")
183 for idx
, new_idx
in enumerate(SVSHAPE0
.get_iterator()):
186 print ("%d->%d" % (idx
, new_idx
))
191 # set the dimension sizes here
193 ydim
= 0 # not needed
194 zdim
= 0 # again, not needed
196 # set total. err don't know how to calculate how many there are...
197 # do it manually for now
204 tablestep
= n
// size
205 for i
in range(0, n
, size
):
206 for j
in range(i
, i
+ halfsize
):
211 SVSHAPE0
= SVSHAPE(0)
212 SVSHAPE0
.lims
= [xdim
, ydim
, zdim
]
213 SVSHAPE0
.order
= [0,1,2] # experiment with different permutations, here
215 SVSHAPE0
.offset
= 0 # experiment with different offset, here
216 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
217 # j+halfstep schedule
218 SVSHAPE1
= SVSHAPE(0)
219 SVSHAPE1
.lims
= [xdim
, ydim
, zdim
]
220 SVSHAPE1
.order
= [0,1,2] # experiment with different permutations, here
222 SVSHAPE1
.offset
= 0 # experiment with different offset, here
223 SVSHAPE1
.invxyz
= [0,0,0] # inversion if desired
225 SVSHAPE2
= SVSHAPE(0)
226 SVSHAPE2
.lims
= [xdim
, ydim
, zdim
]
227 SVSHAPE2
.order
= [0,1,2] # experiment with different permutations, here
229 SVSHAPE2
.offset
= 0 # experiment with different offset, here
230 SVSHAPE2
.invxyz
= [0,0,0] # inversion if desired
232 # enumerate over the iterator function, getting new indices
234 for idx
, (jl
, jh
, k
) in enumerate(zip(iterate_indices(SVSHAPE0
),
235 iterate_indices(SVSHAPE1
),
236 iterate_indices(SVSHAPE2
))):
239 schedule
.append((jl
, jh
, k
))
241 # ok now pretty-print the results, with some debug output
246 tablestep
= n
// size
247 print ("size %d halfsize %d tablestep %d" % \
248 (size
, halfsize
, tablestep
))
249 for i
in range(0, n
, size
):
250 prefix
= "i %d\t" % i
252 for j
in range(i
, i
+ halfsize
):
253 jl
, jh
, ks
= schedule
[idx
]
254 print (" %-3d\t%s j=%-2d jh=%-2d k=%-2d -> "
255 "j[jl=%-2d] j[jh=%-2d] exptable[k=%d]" % \
256 (idx
, prefix
, j
, j
+halfsize
, k
,