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 # Check that outer/inner methods match
88 assert expected
== expected2
89 print("flattened X,Y,expected (outer), expected (inner)")
93 print("\t", expected2
)
95 # and create a linear result2, same scheme
96 #result1 = [0] * (ydim1*xdim2)
99 # store GPR x-flattened and y-flattened in GPRs
100 for i
, x
in enumerate(xf
):
101 gprs
[i
+16] = x
# X matrix
102 for i
, y
in enumerate(yf
):
103 gprs
[i
+32] = y
# Y matrix
105 with
Program(lst
, bigendian
=False) as program
:
106 sim
= self
.run_tst_program(program
, initial_regs
=gprs
)
107 print("spr svshape0", sim
.spr
['SVSHAPE0'])
108 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
109 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
110 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
111 print("spr svshape1", sim
.spr
['SVSHAPE1'])
112 print("spr svshape2", sim
.spr
['SVSHAPE2'])
113 print("spr svshape3", sim
.spr
['SVSHAPE3'])
115 total
= len(X
)*len(Y
[0])
116 for i
in range(total
):
117 results
.append(sim
.gpr(i
).asint())
118 for i
in range(total
):
119 print("maddld-matrix i", i
, results
[i
])
120 # confirm that the results are as expected
121 self
.assertEqual(results
, expected
)
123 def test_sv_remap1(self
):
124 """>>> lst = ["svshape 2, 2, 3, 0, 0",
125 "svremap 31, 1, 2, 3, 0, 0, 0",
126 "sv.fmadds *0, *8, *16, *0"
128 REMAP fmadds FRT, FRA, FRC, FRB
130 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
131 "svremap 31, 1, 2, 3, 0, 0, 0",
132 "sv.fmadds *0, *16, *32, *0"
150 xf
= reduce(operator
.add
, X
)
151 yf
= reduce(operator
.add
, Y
)
152 print("flattened X,Y")
156 # and create a linear result2, same scheme
157 #result1 = [0] * (ydim1*xdim2)
161 for i
, x
in enumerate(xf
):
162 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
163 for i
, y
in enumerate(yf
):
164 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
166 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
167 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
169 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
172 with
Program(lst
, bigendian
=False) as program
:
173 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
174 print("spr svshape0", sim
.spr
['SVSHAPE0'])
175 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
176 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
177 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
178 print("spr svshape1", sim
.spr
['SVSHAPE1'])
179 print("spr svshape2", sim
.spr
['SVSHAPE2'])
180 print("spr svshape3", sim
.spr
['SVSHAPE3'])
182 print("ffmadds-matrix i", i
, float(sim
.fpr(i
)))
183 # confirm that the results are as expected
184 # for i, (t, u) in enumerate(res):
185 # self.assertEqual(sim.fpr(i+2), t)
186 # self.assertEqual(sim.fpr(i+6), u)
188 def test_sv_remap2(self
):
189 """>>> lst = ["svshape 5, 4, 3, 0, 0",
190 "svremap 31, 1, 2, 3, 0, 0, 0",
191 "sv.fmadds *0, *8, *16, *0"
193 REMAP fmadds FRT, FRA, FRC, FRB
195 lst
= SVP64Asm(["svshape 4, 3, 3, 0, 0",
196 "svremap 31, 1, 2, 3, 0, 0, 0",
197 "sv.fmadds *0, *16, *32, *0"
229 Y3
= [[5, 8, 1, 2, 3],
236 # get the dimensions of the 2 matrices
242 print("xdim2 ydim1 ydim2", xdim2
, ydim1
, ydim2
)
244 xf
= reduce(operator
.add
, X
)
245 yf
= reduce(operator
.add
, Y
)
246 print("flattened X,Y")
250 # and create a linear result2, same scheme
251 #result1 = [0] * (ydim1*xdim2)
256 for i
, x
in enumerate(xf
):
257 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
258 for i
, y
in enumerate(yf
):
259 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
261 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
262 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
264 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
267 with
Program(lst
, bigendian
=False) as program
:
268 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
269 print("spr svshape0", sim
.spr
['SVSHAPE0'])
270 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
271 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
272 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
273 print("spr svshape1", sim
.spr
['SVSHAPE1'])
274 print("spr svshape2", sim
.spr
['SVSHAPE2'])
275 print("spr svshape3", sim
.spr
['SVSHAPE3'])
277 print("i", i
, float(sim
.fpr(i
)))
278 # confirm that the results are as expected
279 # for i, (t, u) in enumerate(res):
280 # self.assertEqual(sim.fpr(i+2), t)
281 # self.assertEqual(sim.fpr(i+6), u)
283 def test_sv_remap3_horizontal_or(self
):
284 """>>> lst = ["svshape 3, 2, 1, 0, 0",
285 "svremap 31, 1, 3, 1, 1, 1, 0",
288 REMAP horizontal-or using "or RA,RS,RB"
289 same trick can be applied to do horizontal-add
290 or horizontal-multiply. just remember for multiply
291 to pre-load 1 (1.0) into the results first (or any other
294 sv.or is horribly obscure because RA (the destination)
295 actually gets treated as RT by the REMAP subsystem.
297 The purpose here is to demonstrate a horizontal mapreduce
298 by using/abusing Matrix REMAP (ignoring the B-Matrix entirely)
300 if data is laid out in R G B R G B R G B format and
301 comprises tuples (R<<16 G<<8 B<<0) then a horizontal-or
302 may reduce down to (R<<16) | (G<<8> | (B<<0) on a per-row
305 # 3x4 matrix of data to be ORed together by row.
306 # Add any number of extra rows (up to 6) here (6 because sv.or *0,*0,*6)
307 X1
= [[0x1, 0x10, 0x100], # 0x111
308 [0x2, 0x40, 0x300], # 0x342
309 [0x9, 0x70, 0x800], # 0x879
310 [0x3, 0x71, 0x460], # overlaps (still ORed) - 0x473
313 # get the dimensions of the array
317 lst
= SVP64Asm(["svshape %d, %d, 1, 0, 0" % (xdim1
, ydim1
),
319 # "svremap 31, 3, 0, 3, 1, 2, 0",
320 # "sv.ternlogi *12, *0, *6, 250" # 0b11111110
321 "svremap 31, 1, 3, 1, 1, 1, 0",
326 print("xdim1, ydim1", xdim1
, ydim1
)
328 expected
= [0] * ydim1
329 for i
, row
in enumerate(X1
):
330 expected
[i
] = reduce(operator
.or_
, row
)
331 print("\texpected ORed", hex(expected
[i
]))
332 xf
= reduce(operator
.add
, X1
)
339 for i
, x
in enumerate(xf
):
342 with
Program(lst
, bigendian
=False) as program
:
343 sim
= self
.run_tst_program(program
, gprs
)
344 print("spr svshape0", sim
.spr
['SVSHAPE0'])
345 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
346 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
347 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
348 print("spr svshape1", sim
.spr
['SVSHAPE1'])
349 print("spr svshape2", sim
.spr
['SVSHAPE2'])
350 print("spr svshape3", sim
.spr
['SVSHAPE3'])
351 for i
in range(ydim1
):
352 print("i", i
, sim
.gpr(0+i
), hex(expected
[i
]))
353 for i
in range(ydim1
):
354 self
.assertEqual(sim
.gpr(0+i
), SelectableInt(expected
[i
], 64))
356 def run_tst_program(self
, prog
, initial_regs
=None,
360 if initial_regs
is None:
361 initial_regs
= [0] * 32
362 simulator
= run_tst(prog
, initial_regs
, mem
=initial_mem
,
363 initial_fprs
=initial_fprs
,
374 if __name__
== "__main__":