3 from functools
import reduce
5 from nmutil
.formaltest
import FHDLTestCase
6 from openpower
.decoder
.helpers
import fp64toselectable
7 from openpower
.decoder
.isa
.test_caller
import run_tst
8 from openpower
.decoder
.selectable_int
import SelectableInt
9 from openpower
.simulator
.program
import Program
10 from openpower
.insndb
.asm
import SVP64Asm
13 # Pure Python implementation of matrix multiply
15 # x = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
16 # y = [[1,2],[1,2],[3,4]]
18 zip_b
= list(zip(*b
)) # transpose b matrix
19 return [[sum(ele_a
*ele_b
for ele_a
, ele_b
in zip(row_a
, col_b
))
20 for col_b
in zip_b
] for row_a
in a
]
23 class DecoderTestCase(FHDLTestCase
):
25 def _check_regs(self
, sim
, expected
):
27 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
29 def test_sv_maddld_remap1(self
):
30 """perform an integer matrix multiply using maddld
31 lst = ["svshape 2, 2, 3, 0, 0",
32 "svremap 31, 1, 2, 3, 0, 0, 0",
33 "sv.maddld *0, *8, *16, *0"
35 REMAP maddld RT, RA, RB, RC
37 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
38 "svremap 31, 1, 2, 3, 0, 0, 0",
39 "sv.maddld *0, *16, *32, *0"
57 xf
= reduce(operator
.add
, X
)
58 yf
= reduce(operator
.add
, Y
)
59 print("flattened X,Y")
63 # and create a linear result2, same scheme
64 #result1 = [0] * (ydim1*xdim2)
68 for i
, x
in enumerate(xf
):
69 gprs
[i
+16] = x
# X matrix
70 for i
, y
in enumerate(yf
):
71 gprs
[i
+32] = y
# Y matrix
73 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
74 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
76 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
79 with
Program(lst
, bigendian
=False) as program
:
80 sim
= self
.run_tst_program(program
, initial_regs
=gprs
)
81 print("spr svshape0", sim
.spr
['SVSHAPE0'])
82 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
83 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
84 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
85 print("spr svshape1", sim
.spr
['SVSHAPE1'])
86 print("spr svshape2", sim
.spr
['SVSHAPE2'])
87 print("spr svshape3", sim
.spr
['SVSHAPE3'])
90 expected
.append(sim
.gpr(i
).asint())
92 print("maddld-matrix i", i
, expected
[i
])
93 # confirm that the results are as expected
94 # for i, (t, u) in enumerate(res):
95 # self.assertEqual(sim.fpr(i+2), t)
96 # self.assertEqual(sim.fpr(i+6), u)
98 def test_sv_remap1(self
):
99 """>>> lst = ["svshape 2, 2, 3, 0, 0",
100 "svremap 31, 1, 2, 3, 0, 0, 0",
101 "sv.fmadds *0, *8, *16, *0"
103 REMAP fmadds FRT, FRA, FRC, FRB
105 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
106 "svremap 31, 1, 2, 3, 0, 0, 0",
107 "sv.fmadds *0, *16, *32, *0"
125 xf
= reduce(operator
.add
, X
)
126 yf
= reduce(operator
.add
, Y
)
127 print("flattened X,Y")
131 # and create a linear result2, same scheme
132 #result1 = [0] * (ydim1*xdim2)
136 for i
, x
in enumerate(xf
):
137 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
138 for i
, y
in enumerate(yf
):
139 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
141 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
142 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
144 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
147 with
Program(lst
, bigendian
=False) as program
:
148 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
149 print("spr svshape0", sim
.spr
['SVSHAPE0'])
150 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
151 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
152 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
153 print("spr svshape1", sim
.spr
['SVSHAPE1'])
154 print("spr svshape2", sim
.spr
['SVSHAPE2'])
155 print("spr svshape3", sim
.spr
['SVSHAPE3'])
157 print("ffmadds-matrix i", i
, float(sim
.fpr(i
)))
158 # confirm that the results are as expected
159 # for i, (t, u) in enumerate(res):
160 # self.assertEqual(sim.fpr(i+2), t)
161 # self.assertEqual(sim.fpr(i+6), u)
163 def test_sv_remap2(self
):
164 """>>> lst = ["svshape 5, 4, 3, 0, 0",
165 "svremap 31, 1, 2, 3, 0, 0, 0",
166 "sv.fmadds *0, *8, *16, *0"
168 REMAP fmadds FRT, FRA, FRC, FRB
170 lst
= SVP64Asm(["svshape 4, 3, 3, 0, 0",
171 "svremap 31, 1, 2, 3, 0, 0, 0",
172 "sv.fmadds *0, *16, *32, *0"
204 Y3
= [[5, 8, 1, 2, 3],
211 # get the dimensions of the 2 matrices
217 print("xdim2 ydim1 ydim2", xdim2
, ydim1
, ydim2
)
219 xf
= reduce(operator
.add
, X
)
220 yf
= reduce(operator
.add
, Y
)
221 print("flattened X,Y")
225 # and create a linear result2, same scheme
226 #result1 = [0] * (ydim1*xdim2)
231 for i
, x
in enumerate(xf
):
232 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
233 for i
, y
in enumerate(yf
):
234 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
236 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
237 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
239 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
242 with
Program(lst
, bigendian
=False) as program
:
243 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
244 print("spr svshape0", sim
.spr
['SVSHAPE0'])
245 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
246 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
247 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
248 print("spr svshape1", sim
.spr
['SVSHAPE1'])
249 print("spr svshape2", sim
.spr
['SVSHAPE2'])
250 print("spr svshape3", sim
.spr
['SVSHAPE3'])
252 print("i", i
, float(sim
.fpr(i
)))
253 # confirm that the results are as expected
254 # for i, (t, u) in enumerate(res):
255 # self.assertEqual(sim.fpr(i+2), t)
256 # self.assertEqual(sim.fpr(i+6), u)
258 def test_sv_remap3_horizontal_or(self
):
259 """>>> lst = ["svshape 3, 2, 1, 0, 0",
260 "svremap 31, 1, 3, 1, 1, 1, 0",
263 REMAP horizontal-or using "or RA,RS,RB"
264 same trick can be applied to do horizontal-add
265 or horizontal-multiply. just remember for multiply
266 to pre-load 1 (1.0) into the results first (or any other
269 sv.or is horribly obscure because RA (the destination)
270 actually gets treated as RT by the REMAP subsystem.
272 The purpose here is to demonstrate a horizontal mapreduce
273 by using/abusing Matrix REMAP (ignoring the B-Matrix entirely)
275 if data is laid out in R G B R G B R G B format and
276 comprises tuples (R<<16 G<<8 B<<0) then a horizontal-or
277 may reduce down to (R<<16) | (G<<8> | (B<<0) on a per-row
280 # 3x4 matrix of data to be ORed together by row.
281 # Add any number of extra rows (up to 6) here (6 because sv.or *0,*0,*6)
282 X1
= [[0x1, 0x10, 0x100], # 0x111
283 [0x2, 0x40, 0x300], # 0x342
284 [0x9, 0x70, 0x800], # 0x879
285 [0x3, 0x71, 0x460], # overlaps (still ORed) - 0x473
288 # get the dimensions of the array
292 lst
= SVP64Asm(["svshape %d, %d, 1, 0, 0" % (xdim1
, ydim1
),
294 # "svremap 31, 3, 0, 3, 1, 2, 0",
295 # "sv.ternlogi *12, *0, *6, 250" # 0b11111110
296 "svremap 31, 1, 3, 1, 1, 1, 0",
301 print("xdim1, ydim1", xdim1
, ydim1
)
303 expected
= [0] * ydim1
304 for i
, row
in enumerate(X1
):
305 expected
[i
] = reduce(operator
.or_
, row
)
306 print("\texpected ORed", hex(expected
[i
]))
307 xf
= reduce(operator
.add
, X1
)
314 for i
, x
in enumerate(xf
):
317 with
Program(lst
, bigendian
=False) as program
:
318 sim
= self
.run_tst_program(program
, gprs
)
319 print("spr svshape0", sim
.spr
['SVSHAPE0'])
320 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
321 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
322 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
323 print("spr svshape1", sim
.spr
['SVSHAPE1'])
324 print("spr svshape2", sim
.spr
['SVSHAPE2'])
325 print("spr svshape3", sim
.spr
['SVSHAPE3'])
326 for i
in range(ydim1
):
327 print("i", i
, sim
.gpr(0+i
), hex(expected
[i
]))
328 for i
in range(ydim1
):
329 self
.assertEqual(sim
.gpr(0+i
), SelectableInt(expected
[i
], 64))
331 def run_tst_program(self
, prog
, initial_regs
=None,
335 if initial_regs
is None:
336 initial_regs
= [0] * 32
337 simulator
= run_tst(prog
, initial_regs
, mem
=initial_mem
,
338 initial_fprs
=initial_fprs
,
349 if __name__
== "__main__":