fab9c2e9337df86c874d4cc060537805a6e10fe3
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
12 def setup_result_matrix(rows
, cols
):
14 for i
in range(0, rows
):
16 for k
in range(0, cols
):
20 # Outer product - normal method learned at school
21 def matmult_outer(a
,b
):
22 # Result matrix has same number of rows as matrix a
23 # and same number of columns as matrix b
24 result
= setup_result_matrix(len(a
), len(b
[0]))
26 for i
in range(len(a
)): # Number of rows in matrix a
27 for k
in range(len(b
[0])): # Number of columns in matrix b
28 # Number of columns in matrix a or rows in mat b
29 for j
in range(0, len(a
[0])):
30 result
[i
][k
] += a
[i
][j
] * b
[j
][k
]
34 # Inner product - slight re-arrangement to reduce stalling
36 def matmult_inner(a
,b
):
37 result
= setup_result_matrix(len(a
), len(b
[0]))
39 for i
in range(len(a
)): # Number of rows in matrix a
40 # Number of columns in matrix a or rows in mat b
41 for j
in range(0, len(a
[0])):
42 for k
in range(len(b
[0])): # Number of columns in matrix b
43 result
[i
][k
] += a
[i
][j
] * b
[j
][k
]
48 class DecoderTestCase(FHDLTestCase
):
50 def _check_regs(self
, sim
, expected
):
52 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
54 def test_sv_maddld_remap1(self
):
55 """perform an integer matrix multiply using maddld
56 lst = ["svshape 2, 2, 3, 0, 0",
57 "svremap 31, 1, 2, 3, 0, 0, 0",
58 "sv.maddld *0, *8, *16, *0"
60 REMAP maddld RT, RA, RB, RC
62 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
63 "svremap 31, 1, 2, 3, 0, 0, 0",
64 "sv.maddld *0, *16, *32, *0"
83 xf
= reduce(operator
.add
, X
)
84 yf
= reduce(operator
.add
, Y
)
85 expected
= reduce(operator
.add
, matmult_outer(X
, Y
))
86 expected2
= reduce(operator
.add
, matmult_inner(X
, Y
))
87 print("flattened X,Y,expected (outer), expected (inner)")
91 print("\t", expected2
)
93 # and create a linear result2, same scheme
94 #result1 = [0] * (ydim1*xdim2)
97 # store GPR x-flattened and y-flattened in GPRs
98 for i
, x
in enumerate(xf
):
99 gprs
[i
+16] = x
# X matrix
100 for i
, y
in enumerate(yf
):
101 gprs
[i
+32] = y
# Y matrix
103 with
Program(lst
, bigendian
=False) as program
:
104 sim
= self
.run_tst_program(program
, initial_regs
=gprs
)
105 print("spr svshape0", sim
.spr
['SVSHAPE0'])
106 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
107 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
108 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
109 print("spr svshape1", sim
.spr
['SVSHAPE1'])
110 print("spr svshape2", sim
.spr
['SVSHAPE2'])
111 print("spr svshape3", sim
.spr
['SVSHAPE3'])
113 total
= len(X
)*len(Y
[0])
114 for i
in range(total
):
115 results
.append(sim
.gpr(i
).asint())
116 for i
in range(total
):
117 print("maddld-matrix i", i
, results
[i
])
118 # confirm that the results are as expected
119 self
.assertEqual(results
, expected
)
121 def test_sv_remap1(self
):
122 """>>> lst = ["svshape 2, 2, 3, 0, 0",
123 "svremap 31, 1, 2, 3, 0, 0, 0",
124 "sv.fmadds *0, *8, *16, *0"
126 REMAP fmadds FRT, FRA, FRC, FRB
128 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
129 "svremap 31, 1, 2, 3, 0, 0, 0",
130 "sv.fmadds *0, *16, *32, *0"
148 xf
= reduce(operator
.add
, X
)
149 yf
= reduce(operator
.add
, Y
)
150 print("flattened X,Y")
154 # and create a linear result2, same scheme
155 #result1 = [0] * (ydim1*xdim2)
159 for i
, x
in enumerate(xf
):
160 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
161 for i
, y
in enumerate(yf
):
162 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
164 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
165 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
167 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
170 with
Program(lst
, bigendian
=False) as program
:
171 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
172 print("spr svshape0", sim
.spr
['SVSHAPE0'])
173 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
174 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
175 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
176 print("spr svshape1", sim
.spr
['SVSHAPE1'])
177 print("spr svshape2", sim
.spr
['SVSHAPE2'])
178 print("spr svshape3", sim
.spr
['SVSHAPE3'])
180 print("ffmadds-matrix i", i
, float(sim
.fpr(i
)))
181 # confirm that the results are as expected
182 # for i, (t, u) in enumerate(res):
183 # self.assertEqual(sim.fpr(i+2), t)
184 # self.assertEqual(sim.fpr(i+6), u)
186 def test_sv_remap2(self
):
187 """>>> lst = ["svshape 5, 4, 3, 0, 0",
188 "svremap 31, 1, 2, 3, 0, 0, 0",
189 "sv.fmadds *0, *8, *16, *0"
191 REMAP fmadds FRT, FRA, FRC, FRB
193 lst
= SVP64Asm(["svshape 4, 3, 3, 0, 0",
194 "svremap 31, 1, 2, 3, 0, 0, 0",
195 "sv.fmadds *0, *16, *32, *0"
227 Y3
= [[5, 8, 1, 2, 3],
234 # get the dimensions of the 2 matrices
240 print("xdim2 ydim1 ydim2", xdim2
, ydim1
, ydim2
)
242 xf
= reduce(operator
.add
, X
)
243 yf
= reduce(operator
.add
, Y
)
244 print("flattened X,Y")
248 # and create a linear result2, same scheme
249 #result1 = [0] * (ydim1*xdim2)
254 for i
, x
in enumerate(xf
):
255 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
256 for i
, y
in enumerate(yf
):
257 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
259 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
260 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
262 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
265 with
Program(lst
, bigendian
=False) as program
:
266 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
267 print("spr svshape0", sim
.spr
['SVSHAPE0'])
268 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
269 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
270 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
271 print("spr svshape1", sim
.spr
['SVSHAPE1'])
272 print("spr svshape2", sim
.spr
['SVSHAPE2'])
273 print("spr svshape3", sim
.spr
['SVSHAPE3'])
275 print("i", i
, float(sim
.fpr(i
)))
276 # confirm that the results are as expected
277 # for i, (t, u) in enumerate(res):
278 # self.assertEqual(sim.fpr(i+2), t)
279 # self.assertEqual(sim.fpr(i+6), u)
281 def test_sv_remap3_horizontal_or(self
):
282 """>>> lst = ["svshape 3, 2, 1, 0, 0",
283 "svremap 31, 1, 3, 1, 1, 1, 0",
286 REMAP horizontal-or using "or RA,RS,RB"
287 same trick can be applied to do horizontal-add
288 or horizontal-multiply. just remember for multiply
289 to pre-load 1 (1.0) into the results first (or any other
292 sv.or is horribly obscure because RA (the destination)
293 actually gets treated as RT by the REMAP subsystem.
295 The purpose here is to demonstrate a horizontal mapreduce
296 by using/abusing Matrix REMAP (ignoring the B-Matrix entirely)
298 if data is laid out in R G B R G B R G B format and
299 comprises tuples (R<<16 G<<8 B<<0) then a horizontal-or
300 may reduce down to (R<<16) | (G<<8> | (B<<0) on a per-row
303 # 3x4 matrix of data to be ORed together by row.
304 # Add any number of extra rows (up to 6) here (6 because sv.or *0,*0,*6)
305 X1
= [[0x1, 0x10, 0x100], # 0x111
306 [0x2, 0x40, 0x300], # 0x342
307 [0x9, 0x70, 0x800], # 0x879
308 [0x3, 0x71, 0x460], # overlaps (still ORed) - 0x473
311 # get the dimensions of the array
315 lst
= SVP64Asm(["svshape %d, %d, 1, 0, 0" % (xdim1
, ydim1
),
317 # "svremap 31, 3, 0, 3, 1, 2, 0",
318 # "sv.ternlogi *12, *0, *6, 250" # 0b11111110
319 "svremap 31, 1, 3, 1, 1, 1, 0",
324 print("xdim1, ydim1", xdim1
, ydim1
)
326 expected
= [0] * ydim1
327 for i
, row
in enumerate(X1
):
328 expected
[i
] = reduce(operator
.or_
, row
)
329 print("\texpected ORed", hex(expected
[i
]))
330 xf
= reduce(operator
.add
, X1
)
337 for i
, x
in enumerate(xf
):
340 with
Program(lst
, bigendian
=False) as program
:
341 sim
= self
.run_tst_program(program
, gprs
)
342 print("spr svshape0", sim
.spr
['SVSHAPE0'])
343 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
344 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
345 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
346 print("spr svshape1", sim
.spr
['SVSHAPE1'])
347 print("spr svshape2", sim
.spr
['SVSHAPE2'])
348 print("spr svshape3", sim
.spr
['SVSHAPE3'])
349 for i
in range(ydim1
):
350 print("i", i
, sim
.gpr(0+i
), hex(expected
[i
]))
351 for i
in range(ydim1
):
352 self
.assertEqual(sim
.gpr(0+i
), SelectableInt(expected
[i
], 64))
354 def run_tst_program(self
, prog
, initial_regs
=None,
358 if initial_regs
is None:
359 initial_regs
= [0] * 32
360 simulator
= run_tst(prog
, initial_regs
, mem
=initial_mem
,
361 initial_fprs
=initial_fprs
,
372 if __name__
== "__main__":