2011-03-25 2 views
2

J'essaie d'utiliser CUBLAS pour additionner deux grandes matrices de taille inconnue. J'ai besoin d'un code totalement optimisé (si possible) donc j'ai choisi de ne pas réécrire le code d'addition matriciel (simple) mais en utilisant CUBLAS, en particulier la fonction cublasSgemm qui permet de sommer A et C (si B est une matrice unitaire): = alpha * op (A) * op (B) + bêta * c *CUBLAS - addition matricielle .. comment?

Le problème est le suivant: C et C++ stockent les matrices au format row-major, cublasSgemm est destiné (pour la compatibilité fortran) à fonctionner en colonnes. format majeur. Vous pouvez spécifier si A et B doivent être transposés en premier, mais vous ne pouvez pas indiquer de transposer C. Donc je ne peux pas compléter mon addition de matrice.

Je ne peux pas transposer la matrice C moi-même parce que le la matrice est quelque chose comme 20000x20000 taille maximale.

Une idée sur la façon de résoudre s'il vous plaît?

+0

Si vous ajoutez simplement les matrices, cela n'a pas vraiment d'importance, n'est-ce pas? Vous lui donnez alpha, Aij, bêta et Cij. Il pense que vous lui donnez alpha, Aji, beta et Cji, et vous donne ce qu'il pense être Cji = beta Cji + alpha Aji. Mais c'est le bon Cij en ce qui vous concerne. Mon inquiétude est quand vous commencez à aller à des choses qui _do_ matière - comme les produits matriciels. Là, il n'y a probablement pas de solution. –

+3

Mais plus précisément, vous ne voulez pas utiliser GEMM pour faire une matrice - vous faites une multiplication de matrice complètement inutile (qui prend ~ 20.000^3 opérations et beaucoup de passages dans la mémoire) juste pour faire ~ 20 000^2 opérations en un seul passage! Traiter les matrices comme 20 000^2-longs vecteurs et utiliser saxpy. –

+0

Un grand merci à vous pour la solution saxpy, c'était excellent! Il est donc totalement impossible d'implémenter une version (performative) de la multiplication matricielle avec cublas, n'est-ce pas? Je devrais le coder moi-même? –

Répondre

5

Si vous ajoutez simplement les matrices, cela n'a pas vraiment d'importance. Vous lui donnez alpha, Aij, bêta et Cij. Il pense que vous lui donnez alpha, Aji, beta et Cji, et vous donne ce qu'il pense être Cji = beta Cji + alpha Aji. Mais c'est le bon Cij en ce qui vous concerne. Mon inquiétude est quand vous commencez à aller à des choses qui comptent - comme les produits matriciels. Là, il n'y a probablement pas de solution. Mais plus précisément, vous ne voulez pas utiliser GEMM pour faire une addition matricielle - vous faites une multiplication de matrices complètement inutile (qui prend ~ 20 000 opérations et de nombreux passages dans la mémoire) pour un operatinon qui devrait seulement ~ 20 000 opérations et un seul passage! Traiter les matrices comme 20 000^2-longs vecteurs et utiliser saxpy.

La multiplication de la matrice nécessite beaucoup de bande passante en mémoire. Il existe donc une énorme différence de facteur (10x ou 100x) dans les performances entre le codage vous-même et une version accordée. Idéalement, vous devez modifier les structures de votre code pour qu'elles correspondent à la bibliothèque. Si vous ne pouvez pas, dans ce cas, vous pouvez gérer simplement en utilisant des identités d'algèbre linéaire. L'ordre C-vs-Fortran signifie que lorsque vous passez dans A, CUBLAS "voit" A T (une transposition). Ce qui est bien, nous pouvons le contourner. Si ce que vous voulez est C = A.B, passez dans les matrices dans l'ordre inverse, B.A. Ensuite, la bibliothèque voit (B T) A T), et calcule C T = (A.B) T; et puis quand il repasse C T, vous obtenez (dans votre commande) C. Testez-le et voir.

5

cublasgeam a été ajouté à CUBLAS5.0. Il calcule la somme pondérée de 2 matrices éventuellement transposées