Le problème avec cet exemple est qu'il ne fonctionne que pour les matrices carrées. Si les matrices ne sont pas carrées, vous ne pouvez pas calculer A^t*B^t
en raison d'une erreur de dimension (en supposant que les cotes étaient correctes pour A*B
). Je n'ai pas d'installation cuBLAS à portée de main, donc c'est une sorte de photo dans le noir, mais je serais vraiment surpris si CUBLAS fonctionne différemment de BLAS. BLAS s'attend à ce que les matrices soient en ordre majeur de la colonne (aussi appelé ordre Fortran), mais peut aussi être utilisé pour les matrices en ordre majeur (ordre C). À mon avis, ce qui pourrait être complètement faux, gemm_v2
n'est pas la meilleure façon de gérer la multiplication de deux matrices d'ordre C, par exemple parce que si l'on multiplie deux matrices d'ordre C on aurait aussi un C- matrice de commande comme réponse.
L'astuce pour calculer le produit de deux C-ordre-matrices avec l'aide de gemm
fonctionnerait comme suit:
Même si elle est sans doute connu de vous, je voudrais tout d'abord des précisions sur la ligne-major order (c-memory-layout) et l'ordre des colonnes (fortran-memory-layout), afin d'étoffer ma réponse.
Donc, si nous avons un 2x3
(soit 2 lignes et 3 colonnes) matrice A
, et le stocker dans une mémoire continue nous obtenons:
row-major-order(A) = A11, A12, A13, A21, A22, A23
col-major-order(A) = A11, A21, A12, A22, A13, A33
Cela signifie que si nous obtenons une mémoire continue, ce qui représente un matrice dans le rang-ordre-majeur, et l'interpréter comme une matrice dans la colonne-ordre-majeur, nous obtiendrons une matrice assez différente!
Cependant, si nous prenons un coup d'œil à la matrice transposée A^t
nous pouvons facilement voir:
row-major-order(A) = col-major-order(A^t)
col-major-order(A) = row-major-order(A^t)
Cela signifie que, si nous voulons obtenir la matrice C
dans la ligne-major ordre à la suite, la Blas-routine devrait écrire la matrice transposée C
dans la colonne-ordre-majeur (après tout cela, nous ne pouvons pas changer) dans cette mémoire même. Cependant, C^t=(AB)^t=B^t*A^t
et B^t
et A^t
sont les matrices d'origine réinterprétées dans l'ordre des colonnes majeures.
Maintenant, A
être un -MATRIX n x k
et B
un k x m
matrix, l'appel de routine gemm devrait être la suivante:
gemm('N', 'N', m, n, k, 1.0, B, m, A, k, 0.0, C, m)
S'il vous plaît noter:
- Nous ne sommes pas transposer matrices
A
et B
, car elle est assurée par la réinterprétation C-ordre Fortran ordre.
- Nous devons permuter les emplacements des matrices
A
et B
afin d'obtenir C^t
dans la commande Fortran comme résultat.
- La matrice résultante
C
est en C ordre (par réinterprétant de Fortran pour C-ordre nous nous débarrassons de ^t
).
dans l'appel à blas, indiquez GEMM (transa, transb, m, n, k, alpha, A: r, B: r, bêta, C: w); où transa et transb sont des opérations à appliquer aux matrices. Dans l'exemple gemm_v1, cette opération est d'identité, dans l'exemple gemm_v2 il est transposent. Ensuite, vous spécifiez m, n et k. Ce sont les #rows de A (m), #columns des rangées A/N ° de B (n) et des colonnes de B (k). Si vous gardez la syntaxe de l'exemple, vous spécifiez qu'il soit matrices au carré, donc c'est là pour le changer. Assurez-vous que la forme de vos matrices correspond à la déclaration. – Uvar