2017-07-25 2 views
18

J'essaie d'utiliser les fonctions cuBLAS dans le paquet Numba d'Anaconda et j'ai un problème. J'ai besoin que les matrices d'entrée soient en ordre C. La sortie peut être dans l'ordre Fortran. Je peux exécuter le script d'exemple fourni avec le package, here. Le script a deux fonctions, gemm_v1 et gemm_v2. Dans gemm_v1, l'utilisateur doit créer les matrices d'entrée dans l'ordre Fortran. En gemm_v2, ils peuvent être passés à l'implémentation cuda de GEMM et transposés sur le périphérique. Je peux obtenir ces exemples pour travailler avec des matrices carrées. Cependant, je ne peux pas comprendre comment utiliser gemm_v2 pour travailler avec des matrices d'entrée non carrées. Existe-t-il un moyen de travailler avec des matrices de saisie d'ordre C qui ne sont pas carrées?matrices d'ordre C non carrés dans cuBLAS (numba)

Note:
Idéalement, l'entrée et la sortie des matrices resterait sur l'appareil après l'appel à GEMM être utilisé dans d'autres calculs (cela fait partie d'une méthode itérative).

+0

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

Répondre

3

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:

  1. Nous ne sommes pas transposer matrices A et B, car elle est assurée par la réinterprétation C-ordre Fortran ordre.
  2. Nous devons permuter les emplacements des matrices A et B afin d'obtenir C^t dans la commande Fortran comme résultat.
  3. La matrice résultante C est en C ordre (par réinterprétant de Fortran pour C-ordre nous nous débarrassons de ^t).