2017-05-31 3 views
0

Je dois générer une grande quantité de nombres aléatoires (de zéro à 1, répartis uniformément).Erreur de segmentation lors de la génération de nombreux nombres aléatoires à l'aide de PGI Fortran

J'avais d'abord une boucle Do et générait des nombres aléatoires à la volée en tant que tel:

Real :: RandomN 
Integer :: N 
DO N = 1, 10000 
    Call RANDOM_NUMBER(RandomN) 
    ... Some Code ... 
ENDDO 

Cependant, je recevais une erreur de segmentation lors de la génération des nombres (si je commentais le « random_number d'appel (RandomN) "ligne, ça a bien fonctionné).

Puis après avoir lu un message sur les forums PGI (http://www.pgroup.com/userforum/viewtopic.php?t=713&highlight=randomseed). J'ai décidé de générer d'abord tous les nombres et de les mettre dans un tableau.

Real :: RndNum(1:10000,1:5) 
Integer :: time(8), seed(2) 
Call DATE_AND_TIME(values=time)  ! Get the current time 
seed(1) = time(4) * (360000*time(5) + 6000*time(6) + 100*time(7) + time(8)) 
Call RANDOM_SEED(PUT=seed) 
Call RANDOM_NUMBER(RndNum) 

Cependant, cela me donne un segfault tout de suite. Je l'ai essayé une version réduite sans la graine:

Real :: RndNum(1:10000,1:5) 
Call RANDOM_NUMBER(RndNum) 

Ce travaux pour quelques itérations de mon code et produit alors une erreur de segmentation ainsi. Est-ce que j'utilise une sorte de mémoire? est-il un moyen de l'effacer? ou l'empêcher d'être épuisé?

J'ai aussi essayé:

CALL SYSTEM_CLOCK(count, count_rate, count_max) 
CALL srand(count) 

DO N=1, CAPN 
    RndNum(N,1) = rand() 
    RndNum(N,2) = rand() 
    RndNum(N,3) = rand() 
    RndNum(N,4) = rand() 
    RndNum(N,5) = rand() 
ENDDO 

Mais cela donne aussi une erreur de segmentation.

+1

Si cela vous donne une erreur de segmentation, affichez le ** code complet **. Tout y compris 'programme' et' fin programme'. Voir [mcve]. Re votre édition: que s'est-il passé quand vous avez essayé ça? –

+0

Le code complet est de quelques 1000 lignes et implique plusieurs fichiers. J'ai isolé le problème et essayé d'expliquer le bit qui cause le problème. –

Répondre

2

Votre groupe de graines est trop petit. Obtenez la taille minimale comme ceci:

program testpgi 
    Real :: RndNum(1:10000,1:5) 
    Integer :: time(8), seed(2) 
    Integer :: min_seed_size 
    Call DATE_AND_TIME(values=time)  ! Get the current time 
    seed(1) = time(4) * (360000*time(5) + 6000*time(6) + 100*time(7) + time(8)) 

    Call RANDOM_SEED(SIZE=min_seed_size) 
    write(*,*) min_seed_size 
end program testpgi 

Je l'ai juste couru sur le compilateur PGI, et a obtenu 34. Si je fais Integer :: seed(33), il décharge le noyau. Si je fais Integer :: seed(34), ce n'est pas le cas.

+0

super, merci. Je vais l'essayer –

+0

En le plaçant à la graine à 34 ou plus, cela lui permet de courir pour une itération, après quoi il se sépare à nouveau. J'ai essayé de le mettre à 400 et il a couru pour 5 itérations, à 4000 seulement 1 itération, puis 6 itérations. Donc, il semble encore être le dumping de base. Des idées pour l'empêcher? (C'est dans un sous-programme appelé et exécuté sur l'hôte) –

+0

Ensuite, je pense que vous avez un autre problème. Je viens de courir avec 'seed (34)', fait BOTH 'appel RANDOM_NUMBER (RndNum)' ET bouclé sur un seul nombre aléatoire 100 000 fois. Pas de faute de seg. Avez-vous vérifié la taille de la graine min pour votre version? – Jack