2016-07-02 22 views
3

Ich versuche, Matrix Multiplikation mit dem Fortran BLAS gemm Funktion zu tun, siehe here.Fortran gemm Funktion auf C-zusammenhängende Matrizen

Die Signatur dieser Funktion ist, die Bedeutung aller Parameter könnte in der obigen Verbindung gefunden werden.

call sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc) 

Mein Problem ist, dass, ich mag C-zusammenhängenden Arrays anstelle von Fortran-zusammenhängend diejenigen verwenden, und ich habe mit den oben sgemm für eine ganze Weile spielt, immer noch schlecht verwirrt.

Bitte helfen Sie mir, einige konkrete Beispiele zu sehen.

Alle meine Eingabearrays sind C-zusammenhängend.

a = [[0,1], 
    [2,3]] 
b = [[0,1,2], 
    [3,4,5]] 
# pre-alloc memory for c 
c = [[0,0,0], 
    [0,0,0]] 

# compute c = a * b, which should be as follows 
# c = [[3,4,5], 
#  [9,14,19]] 

# since sgemm assumes Fortran-contiguous, so I thought it would be 
sgemm('T', 'T', 2, 3, 2, 1.0, a, 2, b, 3, 0, c, 2) 
     ~~~~~~~ ~~~~~~~   ~~~ ~~~  ~~~ 
    trans both m,n,k   lda ldb  ldc 

# HOWEVER, c is not what I expected, 
c = [[3,9,4], 
    [14,5,19]] 

Anscheinend sgemm speichert die Elemente in Fortran-zusammenhängender Reihenfolge, wie man dieses Problem löst? Auch ich verstehe nicht ganz, wie diese m,n,k,lda,ldb bestimmt sind, wenn die transa/transb='T' or 'N', hoffe, Sie könnten mir eine detaillierte Erklärung geben.

HINWEIS

Ich verwende diese gemm Funktion von scipy.linalg.cython_blas exportiert, was bedeutet, habe ich keine andere Wahl, anstatt diese Fortran Bestellung Sachen zu spielen.

Antwort

2

Wenn Sie Row-Major-Matrix anstelle von Fortran-Stil Col-Dur verwenden möchten, könnten Sie die CBLAS API gemm verwenden. Sie können das Matrixspeicherlayout mit dem ersten Parameter auswählen.

https://software.intel.com/en-us/node/520775


Oder Sie noch Fortran-API verwenden können. Ein sich änderndes Matrix-Layout entspricht der Matrix-Transponierung. Allerdings berechnen Sie das transponierte C falsch.

Ihr Code berechnen C in Col-Dur, aber Sie brauchen ein C in Zeile-Dur. Also müssen Sie C^T in Col-Dur von Fortran API berechnen, was C in Zeile-Dur entspricht.

Es sollte

sein
C^T = B^T * A^T 

Grundsätzlich müssen Sie A und B, und die entsprechenden Parameter auszutauschen. Für weitere Details zu diesen Parametern können Sie diese Antwort sehen.

Transpose matrix multiplication in cuBLAS howto

+0

bekam ich Ihren Standpunkt 'C^T = B^T * A^T', aber ich bin schlecht verwirrt, was das' m, n, k, Lda, ldb, ldc' sein sollte wenn ich 'transa, transb = 'T' oder 'N'' verwende? – avocado

+0

@loganecolss Ich habe einen Link hinzugefügt. – kangshiyin

+0

Ja, sicher, ich weiß über 'numpy.dot', aber was ich tue beschäftigt sich mit' C'-Arrays, also verwende ich Cython und Low-Level-Gemm. – avocado