We now look at how the FLAMEPy API can be used to implement different matrix-matrix multiplication algorithms.
First, we create some matrices.
import numpy as np
m = 4
n = 3
k = 5
C = np.matrix( np.random.random( (m, n) ) )
print( 'C = ' )
print( C )
Cold = np.matrix( np.zeros( (m,n ) ) )
Cold = np.matrix( np.copy( C ) ) # an alternative way of doing a "hard" copy, in this case of a matrix
A = np.matrix( np.random.random( (m, k) ) )
print( 'A = ' )
print( A )
B = np.matrix( np.random.random( (k, n) ) )
print( 'B = ' )
print( B )
Gemm_nn_unb_var1( A, B, C )
This routine computes $ C := A B + C $ by columns. The "_nn_" means that this is the "No transpose, No transpose" case of matrix multiplication.
The reason for this is that the operations $ C := A^T B + C $ ("_tn_" or "Transpose, No transpose"), $ C := A B^T + C $ ("_nt_" or "No transpose, Transpose"), and $ C := A^T B^T + C $ ("_tt_" or "Transpose, Transpose") are also encountered.
The specific laff function we will use is
laff.gemv( trans, alpha, A, x, beta, y )
which computes
$ y := \alpha A x + \beta y $ or $ y := \alpha A^T x + \beta y $, depending on
parameter trans
. In particular,
laff.gemv( 'No transpose', alpha, A, x, beta, y )
computes $ y := \alpha A x + \beta y $.
laff.gemv( 'Transpose', alpha, A, x, beta, y )
computes $ y := \alpha A^T x + \beta y $.
Use the Spark webpage to generate a code skeleton. (Make sure you adjust the name of the routine.)
import flame
import laff as laff
def Gemm_nn_unb_var1(A, B, C):
BL, BR = flame.part_1x2(B, \
0, 'LEFT')
CL, CR = flame.part_1x2(C, \
0, 'LEFT')
while BL.shape[1] < B.shape[1]:
B0, b1, B2 = flame.repart_1x2_to_1x3(BL, BR, \
1, 'RIGHT')
C0, c1, C2 = flame.repart_1x2_to_1x3(CL, CR, \
1, 'RIGHT')
#------------------------------------------------------------#
laff.gemv( 'No transpose', 1.0, A, b1, 1.0, c1 )
#------------------------------------------------------------#
BL, BR = flame.cont_with_1x3_to_1x2(B0, b1, B2, \
'LEFT')
CL, CR = flame.cont_with_1x3_to_1x2(C0, c1, C2, \
'LEFT')
flame.merge_1x2(CL, CR, C)
C = np.matrix( np.copy( Cold ) ) # restore C
Gemm_nn_unb_var1( A, B, C )
print( 'C - ( Cold + A * B )' )
print( C - ( Cold + A * B ) )
Bingo! It works!
Copy and paste the code into PictureFLAME , a webpage where you can watch your routine in action. Just cut and paste into the box.
Disclaimer: we implemented a VERY simple interpreter. If you do something wrong, we cannot guarantee the results. But if you do it right, you are in for a treat.
If you want to reset the problem, just click in the box into which you pasted the code and hit "next" again.