(no commit message)
[libreriscv.git] / openpower / sv / remapmatrix.py
1 from remapyield import iterate_indices
2 from functools import reduce
3 import operator
4
5
6 def iterate_triple(SVSHAPE0, SVSHAPE1, SVSHAPE2):
7 # zip three iterators together, yields a synchronised
8 # tuple of three indices at a time
9 yield from zip(iterate_indices(SVSHAPE0),
10 iterate_indices(SVSHAPE1),
11 iterate_indices(SVSHAPE2))
12
13
14 def matrix_demo():
15 #### test matrices 1
16 # 3x2 matrix
17 X1 = [[1, 2, 3],
18 [3, 4, 5],
19 ]
20 # 2x3 matrix
21 Y1 = [[6, 7],
22 [8, 9],
23 [10, 11],
24 ]
25
26 #### test matrices 2
27 # 3x3 matrix
28 X2 = [[12,7,3],
29 [4 ,5,6],
30 [7 ,8,9],
31 ]
32 # 3x4 matrix
33 Y2 = [[5,8,1,2],
34 [6,7,3,0],
35 [4,5,9,1]]
36
37 #### test matrices 3
38 # 3x4 matrix
39 X3 = [[12,7,3],
40 [4 ,5,6],
41 [7 ,8,9],
42 [2 ,0,1]]
43 # 3x5 matrix
44 Y3 = [[5,8,1,2,3],
45 [6,7,3,0,9],
46 [4,5,9,1,2]]
47
48 # pick one of the above (crude, non-automated, but it works, hey)
49 X = X1
50 Y = Y1
51
52 # get the dimensions of the 2 matrices
53 xdim1 = len(X[0])
54 ydim1 = len(X)
55 xdim2 = len(Y[0])
56 ydim2 = len(Y)
57
58 # print out X and Y
59 print ("X:")
60 for r in X:
61 print ("\t", r)
62 print ("Y:")
63 for r in Y:
64 print ("\t", r)
65
66 # first, calculate the result matrix manually.
67 # set up result matrix of correct size
68 result = []
69 for _ in range(ydim1):
70 result.append([0]*xdim2)
71 # iterate through rows of Y
72 count = 0
73 for k in range(len(Y)): # ydim2
74 # iterate through rows of X
75 for i in range(len(X)): # ydim1
76 # iterate through columns of Y
77 for j in range(len(Y[0])): # xdim2
78 print ("order %d res %d X %d Y %d" % \
79 (count,
80 (i*xdim2)+j, # result linear array index
81 (i*xdim1)+k, # X linear array index
82 (k*xdim2)+j)) # Y linear array index
83 result[i][j] += X[i][k] * Y[k][j]
84 count += 1
85 print ("expected result")
86 for r in result:
87 print ("\t", r)
88
89 # now. flatten the X and Y matrices into linear 1D Arrays.
90 # linear rows are sequentially-packed first (inner loop),
91 # columns next (outer loop):
92 # 0 1 2 3
93 # 4 5 6 7
94 # 8 9 10 11
95 # =>
96 # 0 1 2 3 4 .... 10 11
97 xf = reduce(operator.add, X)
98 yf = reduce(operator.add, Y)
99 print ("flattened X,Y")
100 print ("\t", xf)
101 print ("\t", yf)
102 # and create a linear result2, same scheme
103 result2 = [0] * (ydim1*xdim2)
104
105 ########
106 # now create the schedule. we use three generators, zipped
107 # together
108
109 print ("xdim2 ydim1 ydim2", xdim2, ydim1, ydim2)
110
111 class SVSHAPE:
112 pass
113 # result uses SVSHAPE0
114 SVSHAPE0 = SVSHAPE()
115 SVSHAPE0.lims = [xdim2, ydim1, ydim2]
116 SVSHAPE0.order = [0,1,2] # result iterates through i and j (modulo)
117 SVSHAPE0.mode = 0b00
118 SVSHAPE0.skip = 0b11 # select 1st 2 dimensions (skip 3rd)
119 SVSHAPE0.offset = 0 # no offset
120 SVSHAPE0.invxyz = [0,0,0] # no inversion
121 # X uses SVSHAPE1
122 SVSHAPE1 = SVSHAPE()
123 SVSHAPE1.lims = [xdim2, ydim1, ydim2]
124 SVSHAPE1.order = [0,2,1] # X iterates through i and k
125 SVSHAPE1.mode = 0b00
126 SVSHAPE1.skip = 0b01 # skip middle dimension
127 SVSHAPE1.offset = 0 # no offset
128 SVSHAPE1.invxyz = [0,0,0] # no inversion
129 # y-selector uses SHAPE2
130 SVSHAPE2 = SVSHAPE()
131 SVSHAPE2.lims = [xdim2, ydim1, ydim2]
132 SVSHAPE2.order = [0,2,1] # X iterates through i and k
133 SVSHAPE2.mode = 0b00
134 SVSHAPE2.skip = 0b11 # select 1st 2 dimensions (skip 3rd)
135 SVSHAPE2.offset = 0 # no offset
136 SVSHAPE2.invxyz = [0,0,0] # no inversion
137
138
139 # perform the iteration over the *linear* arrays using the
140 # schedules
141 VL = ydim2 * xdim2 * ydim1
142 i = 0
143 for i, idxs in enumerate(iterate_triple(SVSHAPE0, SVSHAPE1, SVSHAPE2)):
144 if i == VL:
145 break
146 r_idx, x_idx, y_idx = idxs
147 new_result = result2[r_idx] + xf[x_idx] * yf[y_idx]
148 print ("idxs", i, idxs, len(result2), len(xf), len(yf),
149 " results ", result2[r_idx], xf[x_idx], yf[y_idx], new_result)
150 result2[r_idx] = new_result
151
152 # now print out sections of result array, assuming elements of a "row"
153 # are in sequence (inner loop), columns are outer
154 for i in range(0, len(result2), xdim2):
155 print ("\t", result2[i:i+xdim2])
156
157 if __name__ == '__main__':
158 matrix_demo()