1 from remapyield
import iterate_indices
2 from functools
import reduce
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
))
48 # pick one of the above (crude, non-automated, but it works, hey)
52 # get the dimensions of the 2 matrices
59 print ("X:", xdim1
, ydim1
)
62 print ("Y:", xdim2
, ydim2
)
66 # first, calculate the result matrix manually.
67 # set up result matrix of correct size
69 for _
in range(ydim1
):
70 result
.append([0]*xdim2
)
71 # iterate through rows of Y
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" % \
80 (i
*ydim1
)+j
, # result linear array index
81 (i
*ydim1
)+k
, # X linear array index
82 (k
*xdim2
)+j
)) # Y linear array index
83 result
[i
][j
] += X
[i
][k
] * Y
[k
][j
]
85 print ("expected result")
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):
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")
102 # and create a linear result2, same scheme
103 result2
= [0] * (ydim1
*xdim2
)
106 # now create the schedule. we use three generators, zipped
109 print ("xdim2 ydim1 ydim2", xdim2
, ydim1
, ydim2
)
113 # result uses SVSHAPE0
115 SVSHAPE0
.lims
= [xdim2
, ydim1
, ydim2
]
116 SVSHAPE0
.order
= [0,1,2] # result iterates through i and j (modulo)
118 SVSHAPE0
.skip
= 0b11 # select 1st 2 dimensions (skip 3rd)
119 SVSHAPE0
.offset
= 0 # no offset
120 SVSHAPE0
.invxyz
= [0,0,0] # no inversion
123 SVSHAPE1
.lims
= [xdim2
, ydim1
, ydim2
]
124 SVSHAPE1
.order
= [0,2,1] # X iterates through i and k
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
131 SVSHAPE2
.lims
= [xdim2
, ydim1
, ydim2
]
132 SVSHAPE2
.order
= [0,2,1] # X iterates through i and k
134 SVSHAPE2
.skip
= 0b11 # select 1st 2 dimensions (skip 3rd)
135 SVSHAPE2
.offset
= 0 # no offset
136 SVSHAPE2
.invxyz
= [0,0,0] # no inversion
139 # perform the iteration over the *linear* arrays using the
141 VL
= ydim2
* xdim2
* ydim1
143 for i
, idxs
in enumerate(iterate_triple(SVSHAPE0
, SVSHAPE1
, SVSHAPE2
)):
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
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
])
157 if __name__
== '__main__':