2015-12-25 2 views
0

C'est la première fois que je n'ai pas pu obtenir d'aide à partir des réponses à des questions précédemment publiées.Limite supérieure de la taille de matrice pour la multiplication à l'aide de la fonction cublas gemm (cublasSgemm)

J'ai utilisé cublasSgemm tout à fait avec succès pour multipliant les matrices carrées. Mais récemment, j'ai observé que si le nombre de lignes ou de colonnes augmentait au delà de 269 (ie 270 x 270 matrices et plus), je commence à obtenir des "violations d'accès à la mémoire", quand débogue en activant Nsight Cuda Memory Checker. Si je n'active pas le vérificateur de mémoire, il n'y a pas d'exception et les résultats sont également corrects.

suivant est le message d'erreur exact

Memory Checker détecté 64 violations d'accès

violations d'accès au stockage (mémoire globale)

Est-il une limitation de mon gpu ou cublasSgemm fonction? Que puis-je faire pour résoudre ce problème? J'utilise Cuda 6.5 avec MS Visual Studio 2012 sur Quadro FX 1800M (sm_12). OS est MS Windows 7 64 bits.

J'inclus une version dépouillée du code ci-dessous

#include <stdio.h> 
#include <cuda.h> 
#include <cublas_v2.h> 

int main(int argc, char **argv) 
{ 
const int m = 269; // for 1 - 269 there are no access violations 
// but as soon as m >= 270 Memory Checker throws memory access violations 
// Note: the results are correct even with these violations 
float *X = new float[m*m]; 
float *Y = new float[m*m]; 
float *Z = new float[m*m]; 
float *devX, *devY, *devZ; 
cublasHandle_t handle; 
cudaError_t err; 
cublasStatus_t err1; 

//simple initialization 
for(unsigned long i = 0; i < m*m; i++) 
{ 
    X[i] = 1; 
    Y[i] = 2; 
} 

err1 = cublasCreate(&handle); 
if(err1 != CUBLAS_STATUS_SUCCESS) 
    return 1; 

err = cudaMalloc((void **)&devX, m*m*sizeof(*devX)); 
if(err != CUBLAS_STATUS_SUCCESS) 
    return 1; 

err = cudaMalloc((void **)&devY, m*m*sizeof(*devY)); 
if(err != CUBLAS_STATUS_SUCCESS) 
    return 1; 

err = cudaMalloc((void **)&devZ, m*m*sizeof(*devZ)); 
if(err != CUBLAS_STATUS_SUCCESS) 
    return 1; 


err1 = cublasSetMatrix(m, m, sizeof(*X), X, m, devX, m); 
if(err1 != CUBLAS_STATUS_SUCCESS) 
    return 1; 

err1 = cublasSetMatrix(m, m, sizeof(*Y), Y, m, devY, m); 
if(err1 != CUBLAS_STATUS_SUCCESS) 
    return 1; 

//////////////////////////////////////////////////////////// 
printf("Reached sgemm without error\n"); 
const float alpha = 1.0f, beta = 0.0f; 
// cuda memory checker detects access violations when m > 269 
cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, m, m, &alpha, devX, m, devY, m, &beta, devZ, m); 
cudaDeviceSynchronize(); 
printf("reached after sgemm without error\n"); 
//////////////////////////////////////////////////////////// 

err1 = cublasGetMatrix(m, m, sizeof(*devZ), devZ, m, Z, m); 
if(err != CUBLAS_STATUS_SUCCESS) 
    return 1; 

// just printing a single element for brevity 
printf("....%f....", Z[0]); 

cudaFree(devX); 
cudaFree(devY); 
cudaFree(devZ); 
cublasDestroy_v2(handle); 
getchar(); 
return 0; 
} 

ÉDITÉE

Update: Same result even after disabling TDR, as shown in this image

ÉDITÉE ENCORE

Compilé et a couru le cublas échantillon téléchargé à partir :

https://people.maths.ox.ac.uk/gilesm/cuda/prac5/simpleCUBLAS.cpp

et encore pour N> 500 obtenir la même erreur que précédemment.

Si Cuda Memory Checker est pas activé alors comme avant ce programme s'exécute avec succès et affiche le message "test passé". En réalité, les violations d'accès commencent à partir de N = 350, mais à ce stade, elles sont imprévisibles, c'est-à-dire qu'elles surviennent parfois et d'autres fois elles ne se produisent pas. Mais pour N> 500, ils se produisent toujours

Utilisé cudaDeviceGetLimit (& heap_size, cudaLimitMallocHeapSize); pour obtenir un heap_size de 3435973836 octets. Donc, probablement ce n'est pas le problème non plus!

ÉDITÉ J'ai couru maintenant le code de projet exemple «C: \ ProgramData \ NVIDIA Corporation \ CUDA Samples \ v6.5 \ 7_CUDALibraries \ simpleCUBLAS. Pas de chance!!

EDITED L'utilisation d'un seul GPU peut-elle être la raison?

+0

il faut également noter qu'il n'y a aucun problème à allouer la mémoire pour deux matrices d'entrée et la matrice de sortie. Le GPU a une mémoire de 1GB. – malang

+0

Il existe une fausse détection de défaut. Êtes-vous sûr que ceux-ci sont réels? Pouvez-vous les détecter vous-même? Est-ce que c'est important? – talonmies

+1

Vous êtes peut-être en train de courir dans un événement Windows TDR. Avez-vous modifié le paramètre de délai d'attente TDR? –

Répondre

0

Même si la suite n'est pas une réponse « complète », mais même alors j'ai décidé de partager mon observation

J'ai finalement décidé de revenir à l'utilisation cuda sur linux. Utilisation de cuda-gdb avec memcheck activé. Bien que l'exécution linux dans le niveau 1 n'est pas amusant, mais tous les Incertitude associés à l'utilisation de Windows est supprimé Le code ci-dessus fonctionne maintenant même N = 15000.

En bref, cublas gemm fonctions ne sont limitées que par la capacité matérielle

+1

Vous ne devriez pas avoir à basculer vers le niveau d'exécution 1. le niveau d'exécution 3 devrait convenir si votre objectif est d'empêcher X de fonctionner. –

+0

@RobertCrovella mais sur mon ubuntu 14.04 l'arrêt de lightdm n'a pas fonctionné. Donc je suis simplement passé au niveau d'exécution 1 – malang

+1

Vous n'avez pas besoin d'arrêter lightdm. Au niveau d'exécution 3, le service X ne sera pas démarré au démarrage. Définissez le niveau d'exécution sur 3 et redémarrez.L'avantage du niveau d'exécution 3 est que des fonctionnalités telles que le réseau sont toujours fonctionnelles, et vous pouvez toujours utiliser Linux comme environnement mutliuser. –