2015-07-13 4 views
1

J'essaie de comprendre l'idée de la dimension dominante dans cuBLAS. Il est mentionné que lda doit toujours être supérieur ou égal au nombre de lignes dans une matrice.La dimension principale de cuBLAS permet-elle d'accéder à une sous-matrice?

Si j'ai une matrice A 100x100 et que je voulais accéder à A (90:99, 0:99), quels seraient les arguments de cublasSetMatrix? lda spécifie le nombre de lignes entre les éléments dans la même colonne (100 dans ce cas), mais où devrais-je spécifier le 90? Je ne peux voir un moyen en ajustant *A.

La définition de la fonction est:

cublasStatus_t cublasSetMatrix(int rows, int cols, int elemSize, const void *A, int lda, void *B, int ldb) 

Et je suppose aussi que je ne serais pas en mesure de transférer la partie inférieure droite de 3x3 d'une matrice 5x5, compte tenu des limites de longueur.

+0

La réponse dépend de l'ordre de stockage de la matrice. Dans quel sens A est-il stocké? – talonmies

+0

@talonmies Colonne-major – John

+1

Oui, vous pouvez accéder à une sous-matrice arbitraire avec CUBLAS (ou tout BLAS, pour cette question). S'il vous plaît décoder votre notation. 'A (90:99, 0:99)' = colonne 99 des lignes 90 à 0? Pourquoi les lignes sont-elles spécifiées dans l'ordre inverse? – njuffa

Répondre

3

Vous devez "ajuster *A", comme vous l'avez appelé. Le pointeur donné à cette fonction doit être l'entrée de départ de la sous-matrice correspondante.

Vous n'avez pas dit si votre matrice A est réellement la matrice d'entrée ou de sortie, mais cela ne devrait pas changer beaucoup, conceptuellement.

En supposant que vous avez le code suivant:

// The matrix in host memory 
int rowsA = 100; 
int colsA = 100; 
float *A = new float[rowsA*colsA]; 

// Fill A with values 
... 

// The sub-matrix that should be copied to the device. 
// The minimum index is INCLUSIVE 
// The maximum index is EXCLUSIVE 
int minRowA = 0; 
int maxRowA = 100; 
int minColA = 90; 
int maxColA = 100; 
int rowsB = maxRowA-minRowA; 
int colsB = maxColA-minColA; 

// Allocate the device matrix 
float *dB = nullptr; 
cudaMalloc(&dB, rowsB * colsB * sizeof(float)); 

Ensuite, pour l'appel cublasSetMatrix, vous devez calculer l'élément à partir de la matrice source:

float *sourceA = A + (minRowA + minColA * rowsA); 
cublasSetMatrix(rowsB, colsB, sizeof(float), sourceA, rowsA, dB, rowsB); 

Et c'est là que 90 que vous avez demandé entre en jeu: C'est le minColA dans le calcul du pointeur source.