f25d3c69a2d4fe66819b0e4b43b0796aa9bfe452
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
]
49 class DecoderTestCase(FHDLTestCase
):
51 def _check_regs(self
, sim
, expected
):
53 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
55 def test_sv_maddld_remap1(self
):
56 """perform an integer matrix multiply using maddld
57 lst = ["svshape 2, 2, 3, 0, 0",
58 "svremap 31, 1, 2, 3, 0, 0, 0",
59 "sv.maddld *0, *8, *16, *0"
61 REMAP maddld RT, RA, RB, RC
63 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
64 "svremap 31, 1, 2, 3, 0, 0, 0",
65 "sv.maddld *0, *16, *32, *0"
83 expected
= matmult_outer(X
, Y
)
84 expected2
= matmult_inner(X
, Y
)
85 expected
= flatten(expected
)
86 expected2
= flatten(expected2
)
87 print("expected-matrix (outer):")
89 print("expected-matrix (inner):")
92 xf
= reduce(operator
.add
, X
)
93 yf
= reduce(operator
.add
, Y
)
94 expected
= reduce(operator
.add
, expected
)
95 print("flattened X,Y,expected")
100 # and create a linear result2, same scheme
101 #result1 = [0] * (ydim1*xdim2)
104 # store GPR x-flattened and y-flattened in GPRs
105 for i
, x
in enumerate(xf
):
106 gprs
[i
+16] = x
# X matrix
107 for i
, y
in enumerate(yf
):
108 gprs
[i
+32] = y
# Y matrix
110 with
Program(lst
, bigendian
=False) as program
:
111 sim
= self
.run_tst_program(program
, initial_regs
=gprs
)
112 print("spr svshape0", sim
.spr
['SVSHAPE0'])
113 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
114 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
115 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
116 print("spr svshape1", sim
.spr
['SVSHAPE1'])
117 print("spr svshape2", sim
.spr
['SVSHAPE2'])
118 print("spr svshape3", sim
.spr
['SVSHAPE3'])
120 total
= len(X
)*len(Y
[0])
121 for i
in range(total
):
122 results
.append(sim
.gpr(i
).asint())
123 for i
in range(total
):
124 print("maddld-matrix i", i
, results
[i
])
125 # confirm that the results are as expected
126 self
.assertEqual(results
, expected
)
128 def test_sv_remap1(self
):
129 """>>> lst = ["svshape 2, 2, 3, 0, 0",
130 "svremap 31, 1, 2, 3, 0, 0, 0",
131 "sv.fmadds *0, *8, *16, *0"
133 REMAP fmadds FRT, FRA, FRC, FRB
135 lst
= SVP64Asm(["svshape 2, 2, 3, 0, 0",
136 "svremap 31, 1, 2, 3, 0, 0, 0",
137 "sv.fmadds *0, *16, *32, *0"
155 xf
= reduce(operator
.add
, X
)
156 yf
= reduce(operator
.add
, Y
)
157 print("flattened X,Y")
161 # and create a linear result2, same scheme
162 #result1 = [0] * (ydim1*xdim2)
166 for i
, x
in enumerate(xf
):
167 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
168 for i
, y
in enumerate(yf
):
169 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
171 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
172 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
174 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
177 with
Program(lst
, bigendian
=False) as program
:
178 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
179 print("spr svshape0", sim
.spr
['SVSHAPE0'])
180 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
181 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
182 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
183 print("spr svshape1", sim
.spr
['SVSHAPE1'])
184 print("spr svshape2", sim
.spr
['SVSHAPE2'])
185 print("spr svshape3", sim
.spr
['SVSHAPE3'])
187 print("ffmadds-matrix i", i
, float(sim
.fpr(i
)))
188 # confirm that the results are as expected
189 # for i, (t, u) in enumerate(res):
190 # self.assertEqual(sim.fpr(i+2), t)
191 # self.assertEqual(sim.fpr(i+6), u)
193 def test_sv_remap2(self
):
194 """>>> lst = ["svshape 5, 4, 3, 0, 0",
195 "svremap 31, 1, 2, 3, 0, 0, 0",
196 "sv.fmadds *0, *8, *16, *0"
198 REMAP fmadds FRT, FRA, FRC, FRB
200 lst
= SVP64Asm(["svshape 4, 3, 3, 0, 0",
201 "svremap 31, 1, 2, 3, 0, 0, 0",
202 "sv.fmadds *0, *16, *32, *0"
234 Y3
= [[5, 8, 1, 2, 3],
241 # get the dimensions of the 2 matrices
247 print("xdim2 ydim1 ydim2", xdim2
, ydim1
, ydim2
)
249 xf
= reduce(operator
.add
, X
)
250 yf
= reduce(operator
.add
, Y
)
251 print("flattened X,Y")
255 # and create a linear result2, same scheme
256 #result1 = [0] * (ydim1*xdim2)
261 for i
, x
in enumerate(xf
):
262 fprs
[i
+16] = fp64toselectable(float(x
)) # X matrix
263 for i
, y
in enumerate(yf
):
264 fprs
[i
+32] = fp64toselectable(float(y
)) # Y matrix
266 # t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
267 # u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
269 # print ("FFT", i, "in", a, b, "coeff", c, "mul",
272 with
Program(lst
, bigendian
=False) as program
:
273 sim
= self
.run_tst_program(program
, initial_fprs
=fprs
)
274 print("spr svshape0", sim
.spr
['SVSHAPE0'])
275 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
276 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
277 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
278 print("spr svshape1", sim
.spr
['SVSHAPE1'])
279 print("spr svshape2", sim
.spr
['SVSHAPE2'])
280 print("spr svshape3", sim
.spr
['SVSHAPE3'])
282 print("i", i
, float(sim
.fpr(i
)))
283 # confirm that the results are as expected
284 # for i, (t, u) in enumerate(res):
285 # self.assertEqual(sim.fpr(i+2), t)
286 # self.assertEqual(sim.fpr(i+6), u)
288 def test_sv_remap3_horizontal_or(self
):
289 """>>> lst = ["svshape 3, 2, 1, 0, 0",
290 "svremap 31, 1, 3, 1, 1, 1, 0",
293 REMAP horizontal-or using "or RA,RS,RB"
294 same trick can be applied to do horizontal-add
295 or horizontal-multiply. just remember for multiply
296 to pre-load 1 (1.0) into the results first (or any other
299 sv.or is horribly obscure because RA (the destination)
300 actually gets treated as RT by the REMAP subsystem.
302 The purpose here is to demonstrate a horizontal mapreduce
303 by using/abusing Matrix REMAP (ignoring the B-Matrix entirely)
305 if data is laid out in R G B R G B R G B format and
306 comprises tuples (R<<16 G<<8 B<<0) then a horizontal-or
307 may reduce down to (R<<16) | (G<<8> | (B<<0) on a per-row
310 # 3x4 matrix of data to be ORed together by row.
311 # Add any number of extra rows (up to 6) here (6 because sv.or *0,*0,*6)
312 X1
= [[0x1, 0x10, 0x100], # 0x111
313 [0x2, 0x40, 0x300], # 0x342
314 [0x9, 0x70, 0x800], # 0x879
315 [0x3, 0x71, 0x460], # overlaps (still ORed) - 0x473
318 # get the dimensions of the array
322 lst
= SVP64Asm(["svshape %d, %d, 1, 0, 0" % (xdim1
, ydim1
),
324 # "svremap 31, 3, 0, 3, 1, 2, 0",
325 # "sv.ternlogi *12, *0, *6, 250" # 0b11111110
326 "svremap 31, 1, 3, 1, 1, 1, 0",
331 print("xdim1, ydim1", xdim1
, ydim1
)
333 expected
= [0] * ydim1
334 for i
, row
in enumerate(X1
):
335 expected
[i
] = reduce(operator
.or_
, row
)
336 print("\texpected ORed", hex(expected
[i
]))
337 xf
= reduce(operator
.add
, X1
)
344 for i
, x
in enumerate(xf
):
347 with
Program(lst
, bigendian
=False) as program
:
348 sim
= self
.run_tst_program(program
, gprs
)
349 print("spr svshape0", sim
.spr
['SVSHAPE0'])
350 print(" xdimsz", sim
.spr
['SVSHAPE0'].xdimsz
)
351 print(" ydimsz", sim
.spr
['SVSHAPE0'].ydimsz
)
352 print(" zdimsz", sim
.spr
['SVSHAPE0'].zdimsz
)
353 print("spr svshape1", sim
.spr
['SVSHAPE1'])
354 print("spr svshape2", sim
.spr
['SVSHAPE2'])
355 print("spr svshape3", sim
.spr
['SVSHAPE3'])
356 for i
in range(ydim1
):
357 print("i", i
, sim
.gpr(0+i
), hex(expected
[i
]))
358 for i
in range(ydim1
):
359 self
.assertEqual(sim
.gpr(0+i
), SelectableInt(expected
[i
], 64))
361 def run_tst_program(self
, prog
, initial_regs
=None,
365 if initial_regs
is None:
366 initial_regs
= [0] * 32
367 simulator
= run_tst(prog
, initial_regs
, mem
=initial_mem
,
368 initial_fprs
=initial_fprs
,
379 if __name__
== "__main__":