2010-11-10 35 views
0

Y at-il limitation ducurandGenerateNormalDouble se bloque avec le numéro de larege de nombres aléatoires à générer

curandGenerateNormal ( générateur de curandGenerator_t, flotteur * outputPtr, size_t n, flotteur signifie, flotteur stddev)

fonction? curandGenerateNormal est appelé à l'intérieur d'une boucle, lorsque j'augmente la taille du paramètre size_t n, le code a commencé à se bloquer lorsqu'il a été appelé plusieurs fois.

Des idées?

+0

La fonction GenerateUniformDouble s'exécute correctement à l'intérieur de la boucle, mais nous avons besoin de curandGenerateNormalDouble pour produire le nombre entre 0 et 1. Veuillez nous aider. – Stratford

+1

"curandGenerateNormalDouble plante avec" ... avec quoi ?! – Tom

Répondre

1

Pouvez-vous élaborer sur ce qui se passe réellement quand il se bloque? Vérifiez-vous toutes les valeurs d'erreur?

Votre boucle devrait ressembler au code ci-dessous. Est-il possible que cudaMalloc échoue à votre insu et vous passez donc un pointeur invalide, ou quelque chose de similaire?

curandGenerator_t gen; 
curandResult = curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT)); 
if (curandResult != CURAND_STATUS_SUCCESS) 
{ 
    // throw or whatever 
} 

curandResult = curandSetPseudoRandomGeneratorSeed(gen, 1234ULL)); 
if (curandResult != CURAND_STATUS_SUCCESS) 
{ 
    // throw or whatever 
} 

cudaResult = cudaMalloc((void **)&data, szend * sizeof(float)); 
if (cudaResult != cudaSuccess) 
{ 
    // throw or whatever 
} 

for (unsigned int sz = szstart ; sz <= szend ; sz += szstep) 
{ 
    float *data = 0; 

    /* Could allocate and free the memory on each iteration, 
     instead of allocating for the maximum size upfront... 
    cudaResult = cudaMalloc((void **)&data, sz * sizeof(float)); 
    if (cudaResult != cudaSuccess) 
    { 
     // throw or whatever 
    } 
    */ 
    curandResult = curandGenerateNormal(gen, data, sz, mean, stddev); 
    if (curandResult != CURAND_STATUS_SUCCESS) 
    { 
     // throw or whatever 
    } 
    /* If allocating on each iteration, need to free... 
    cudaResult = cudaFree(data); 
    if (cudaResult != cudaSuccess) 
    { 
     // throw or whatever 
    } 
    */ 
} 
cudaResult = cudaFree(data); 
if (cudaResult != cudaSuccess) 
{ 
    // throw or whatever 
} 

curandResult = curandDestroyGenerator(&gen)); 
if (curandResult != CURAND_STATUS_SUCCESS) 
{ 
    // throw or whatever 
} 

En ce qui concerne votre commentaire, notez que curandGenerateNormalDouble va générer des nombres normalement distribués avec une moyenne donnée et l'écart-type, que les conflits avec votre condition qu'ils soient compris entre 0 et 1. Quelle distribution avez-vous besoin?

+0

Salut Tom, merci pour la réponse. nous avons besoin de nombres aléatoires de NormalDistribution avec la moyenne 0 et stddev 1. Le plantage que j'ai obtenu provient de la boucle lorsque la valeur du paramètre sz est grande. En outre, lorsque le curandResult! = CURAND_STATUS_SUCCESS, comment pourrions-nous produire des messages d'erreur détaillés. Merci – Stratford

+0

Pour allouer et libérer la mémoire à chaque itération, cela ralentira-t-il la performance? J'alloue la mémoire avant le début de la boucle avec une taille fixe égale au nombre de nombres aléatoires générés dans chaque boucle et libère la mémoire après la boucle. Cependant, lorsque le nombre de nombres aléatoires doit être généré est énorme, le programme se bloque après quelques exécutions avec curandGenerateNormalDouble. – Stratford

+0

J'ai utilisé #define CURAND_CALL (x) faire {if ((x)! = CURAND_STATUS_SUCCESS) {\ \t printf ("% s Erreur à% s:% d \ n", "Bibliothèque CURAND", __FILE __, __ LINE__); \ \t return EXIT_FAILURE;}} while (0) à partir des exemples d'API lors de l'appel du curandGenerateNormalDouble afin que le programme s'arrête lorsque la valeur de renturn n'est pas égale à CURAND_STATUS_SUCCESS. – Stratford