RANDOM_NUMBER & _SEED oddities

PGI Folks,

I have an…oddity I need help explaining. I’m trying to figure out a nice, portable way to get random numbers with different compilers. Obviously, RANDOM_NUMBER is the way to go. Now, the code I’m using will also need a static seed, so I’ll need to use RANDOM_SEED as well. Following a chunk of code I found via Google at Lahey, I made this program:

program randomTest

implicit none

real*8 :: rn(10)

integer :: seed_size
integer, allocatable :: seed(:)
integer :: i

call random_seed()
call random_seed(size=seed_size)

write (*,*) 'seed_size for RANDOM_SEED is: '
write (*,*) seed_size

allocate(seed(seed_size))
call random_seed(get=seed)

write (*,*) 'System generated RANDOM_SEED is: '
write(*,*) seed

seed=12
!seed = [ (i,i=1,seed_size) ]
call random_seed(put=seed)
call random_seed(get=seed)

write (*,*) 'Our specified RANDOM_SEED is: '
write(*,*) seed
deallocate(seed)

call random_number(rn)
write (*,*) rn

end program randomTest

When I compile and run this code I get a…curiosity:

$ pgfortran randomtest.F90 && ./a.out
 seed_size for RANDOM_SEED is: 
           34
 System generated RANDOM_SEED is: 
      1120731      7216334      1854449      4125410      8077957        55766 
      6275042      7511160      8086732      6595401       175655      3844873 
      2093857      1818440      6712803      7103074      5115164       839058 
      4556604       467731       284012      2784412      2530688      7365308 
      6706998      3320922      8209924      7768441       290898      3262263 
      7108656      1804980      2305714      7339660
 Our specified RANDOM_SEED is: 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12
   2.8610232902792632E-006   2.8610232902792632E-006   2.8610232902792632E-006 
   2.8610232902792632E-006   2.8610232902792632E-006   4.2915349354188947E-006 
   4.2915349354188947E-006   4.2915349354188947E-006   4.2915349354188947E-006 
   4.2915349354188947E-006

Huh. That’s not that random…looking (as xkcd taught us, it still might be random). It turns out if you increase the size of rn (say, dimension 200), it does start “looking” random:

$ pgfortran randomtest.F90 && ./a.out
 seed_size for RANDOM_SEED is: 
           34
 System generated RANDOM_SEED is: 
      4193689      4181511      1633777      4958531      6587629      6505414 
        44629      3833330      1937304      2133152      2014503      6498151 
      3342430      7256452      3886428      1245379      6241516      6257177 
       887417      3292396      3900654      5533165      3650824      2752512 
      6321256      2223711       996759      5180850       230618      2486501 
      1362322      1675880       470661      4135704
 Our specified RANDOM_SEED is: 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12           12           12 
           12           12           12           12
   2.8610232902792632E-006   2.8610232902792632E-006   2.8610232902792632E-006 
   2.8610232902792632E-006   2.8610232902792632E-006   4.2915349354188947E-006 
   4.2915349354188947E-006   4.2915349354188947E-006   4.2915349354188947E-006 
   4.2915349354188947E-006   5.7220465805585263E-006   5.7220465805585263E-006 
   5.7220465805585263E-006   5.7220465805585263E-006   5.7220465805585263E-006 
   7.1525582256981579E-006   7.1525582256981579E-006   8.5830698708377895E-006 
   8.5830698708377895E-006   8.5830698708377895E-006   1.0013581515977421E-005 
   1.0013581515977421E-005   1.2874604806256684E-005   1.2874604806256684E-005 
   1.2874604806256684E-005   1.4305116451396316E-005   1.4305116451396316E-005 
   1.8596651386815211E-005   1.8596651386815211E-005   1.8596651386815211E-005 
   2.0027163031954842E-005   2.0027163031954842E-005   2.5749209612513368E-005 
   2.5749209612513368E-005   2.7179721257653000E-005   2.8610232902792632E-005 
   2.8610232902792632E-005   3.5762791128490790E-005   3.5762791128490790E-005 
   4.0054326063909684E-005   4.1484837709049316E-005   4.1484837709049316E-005 
   5.0067907579887105E-005   5.0067907579887105E-005   5.8650977450724895E-005 
   6.0081489095864526E-005   6.0081489095864526E-005   7.0095070611841948E-005 
   7.0095070611841948E-005   8.4400187063238263E-005   8.5830698708377895E-005 
   8.7261210353517527E-005   9.8705303514634579E-005   9.8705303514634579E-005 
   1.2016297819172905E-004   1.2159348983686868E-004   1.2731553641742721E-004 
   1.4019014122368390E-004   1.4019014122368390E-004   1.7023088577161616E-004 
   1.7166139741675579E-004   1.8596651386815211E-004   2.0027163031954842E-004 
   2.0027163031954842E-004   2.4032595638345811E-004   2.4175646802859774E-004 
   2.7036670093139037E-004   2.8610232902792632E-004   2.8753284067306595E-004 
   3.3903125989809269E-004   3.4046177154323232E-004   3.9052967912311942E-004 
   4.0769581886479500E-004   4.1484837709049316E-004   4.7922140112177658E-004 
   4.8065191276691621E-004   5.6076056489473558E-004   5.7935721628155079E-004 
   6.0081489095864526E-004   6.7949303144132500E-004   6.8092354308646463E-004 
   8.0108652127819369E-004   8.2111368431014853E-004   8.7118159189003563E-004 
   9.6559536046925132E-004   9.6845638375953058E-004   1.1401177811762864E-003 
   1.1615754558533808E-003   1.2617112710131551E-003   1.3732911793340463E-003 
   1.3833047608500237E-003   1.6193391822980630E-003   1.6422273686202971E-003 
   1.8224718359078906E-003   1.9526483956155971E-003   1.9841196518086690E-003 
   2.2988322137393880E-003   2.3231509117067617E-003   2.6235583571860843E-003 
   2.7737620799257456E-003   2.8553012436987046E-003   3.2644275742086393E-003 
   3.2916072954662923E-003   3.7636761383623707E-003   3.9353375357791265E-003 
   4.1170125147118597E-003   4.6377187535426856E-003   4.6749120563163160E-003 
   5.3830153206604336E-003   5.5775649043994235E-003   5.9394843506197503E-003 
   6.5903671491582827E-003   6.6590317081249850E-003   7.6818475343998216E-003 
   7.9007158161061852E-003   8.5630427078058347E-003   9.3641292290840283E-003 
   9.5143329518236897E-003   1.0946275108608461E-002   1.1192323111572478E-002 
   1.2326718846168205E-002   1.3299466764863155E-002   1.3631345466535549E-002 
   1.5583993862151146E-002   1.5867235167888794E-002   1.7709734166828639E-002 
   1.8877031669262578E-002   1.9570829817155300E-002   2.2174361011309429E-002 
   2.2526266876013779E-002   2.5391581701228461E-002   2.6777747485368764E-002 
   2.8133872524961134E-002   3.1538490240393457E-002   3.2040599827837468E-002 
   3.6337856809836921E-002   3.7970070596941241E-002   4.0460591371129340E-002 
   4.4837957005256612E-002   4.5671945294373018E-002   5.1921850671988068E-002 
   5.3837305764830035E-002   5.8170325537957979E-002   6.3714988674519191E-002 
   6.5242775111528317E-002   7.4096211683297497E-002   7.6363572640843813E-002 
   8.3561907239186439E-002   9.0492736159887954E-002   9.3376647636489452E-002 
   0.1056347019236910        0.1084041724686813        0.1198997640490234      
   0.1284628067568292        0.1338372390076188        0.1504726589289476      
   0.1540761177630543        0.1718216147210114        0.1823001125216592      
   0.1920075645455768        0.2141876476034668        0.2193188928745826      
   0.2459178264043089        0.2586636851625030        0.2755694717847632      
   0.3046803837633547        0.3126955405110721        0.3515525283279999      
   0.3670678576311843        0.3954692358337866        0.4331431905201839      
   0.4465327795186909        0.5020251872569474        0.5211439753942386      
   0.5672908505547980        0.6154433030418431        0.6385403440642676      
   0.7162128348604142        0.7404628682688212        0.8132086769591069      
   0.8741069882043462        0.9141098158490308        2.0893218623768917E-002 
   5.3158408779893307E-002   0.1647612052871068        0.2411748458355305      
   0.3095790516828174        0.4540364091439528        0.4996911882985842      
   0.6667863925440543        0.7623188212297691        0.8768699022376154      
   6.9479712185795961E-002   0.1382315323628518        0.3829992274044685      
   0.5027816894985904        0.6900785791967223        0.9435867003901421      
   5.2341348211882632E-002   0.4038924460282374

After a while, the numbers aren’t the same anymore, which is good, but there seems to be a bit of a startup “bias” where the values monotonically increase until you reach 1.0 and then it “looks” random.

I’ll note that the generator in gfortran or ifort don’t seem to have the same issue:

$ gfortran randomtest.F90 && ./a.out 
 seed_size for RANDOM_SEED is: 
           8
 System generated RANDOM_SEED is: 
   437395160  1404128605   572505362 -1187264075   454383258   525702629   973594203  1758310677
 Our specified RANDOM_SEED is: 
          12          12          12          12          12          12          12          12
  0.75896909164940396       0.48897481984547464       0.79513291277748022       0.98009539185978756       0.83467919508698862       0.85101238952040359       0.16483897501956624       0.14000430522166651       3.96003308392569586E-002  0.46935267743450682 

$ ifort randomtest.F90 && a.out 
randomtest.F90(23): (col. 1) remark: LOOP WAS VECTORIZED.
 seed_size for RANDOM_SEED is: 
           2
 System generated RANDOM_SEED is: 
  1351962852   156569157
 Our specified RANDOM_SEED is: 
          12          12
  0.999996210913953       0.694234916013649       0.769806140769980     
  0.997026373980212       0.443334298526595       0.940541781459957     
  0.975740233872978       1.607431767802543E-002  0.449636255958620     
  7.682652516768049E-003

I’m guessing the Standard doesn’t specify what the random number generator for an implementation is, just how it will be called, since each compiler gives different answers. Is there a “best practices” guide for calling the PGI RANDOM_NUMBER routine?

ETA: Oh, and I should have said this, but obviously, if your RANDOM_SEED is pretty random (like the system seed), pgfortran “looks” random:

$ pgfortran randomtest.F90 && ./a.out
 seed_size for RANDOM_SEED is: 
           34
 System generated RANDOM_SEED is: 
      8093102      2880621      3485957      6920646      7079926      8288461 
      7336175      2932069      7005763      4518683      2351199      4098661 
      2355125      3674405      7170886      2951714       306196       743387 
       188311      1938423      6027605      4458888      6263290      2424047 
      1007418      1494285      2611832      3318276      7764244      3167453 
      6653661      2773408      7100761      5707740
   0.5215295654376177        0.2205747040406578        0.3656515800431919      
   0.6801460585258496        0.2190848209415321        1.0128064769659773E-002 
   0.6585979470808354        0.7175234108447057        0.7687646990084431      
   0.4501628522964864

That’s good, but usually when one specifies a seed, it’ll just be some simple number like 1. You’ll note from my code stub, I tried:

seed = [ (i,i=1,seed_size) ]

but even that still has the “spin-up” problem, just not as severe (rn(1) and rn(2) aren’t the same, say).

Thanks,
Matt

Zombie Thread, reactivate!

All, I just wanted to point out that I’m still seeing this weirdness even with PGI 14.10. If you use RANDOM_SEED and set it to something trivial, you want to be careful.

For example, seed=1 is not a good idea if your code looks like mine (calling RANDOM_NUMBER on an array) as it only looks “random” after about 220 elements. The array members monotonically increase.

Now, if you set seed=789789789, things get random after about element 30.

More oddities happen if, say, seed(1)=1 and seed(2:)=0:

 Our specified RANDOM_SEED is: 
            1            0            0            0            0            0 
            0            0            0            0            0            0 
            0            0            0            0            0            0 
            0            0            0            0            0            0 
            0            0            0            0            0            0 
            0            0            0            0
 Results of calling random_number on an array:
   1.4210854715202004E-014    0.000000000000000         0.000000000000000      
    0.000000000000000         0.000000000000000        1.4210854715202004E-014 
    0.000000000000000         0.000000000000000         0.000000000000000      
    0.000000000000000        1.4210854715202004E-014    0.000000000000000      
    0.000000000000000         0.000000000000000         0.000000000000000      
   1.4210854715202004E-014    0.000000000000000        1.4210854715202004E-014 
    0.000000000000000         0.000000000000000        1.4210854715202004E-014 
    0.000000000000000        2.8421709430404007E-014    0.000000000000000      
    0.000000000000000        1.4210854715202004E-014    0.000000000000000      
   4.2632564145606011E-014    0.000000000000000         0.000000000000000      
   1.4210854715202004E-014    0.000000000000000        5.6843418860808015E-014 
    0.000000000000000        1.4210854715202004E-014   1.4210854715202004E-014 
    0.000000000000000        7.1054273576010019E-014    0.000000000000000      
   4.2632564145606011E-014   1.4210854715202004E-014    0.000000000000000      
   8.5265128291212022E-014    0.000000000000000        8.5265128291212022E-014 
   1.4210854715202004E-014    0.000000000000000        9.9475983006414026E-014 
    0.000000000000000        1.4210854715202004E-013   1.4210854715202004E-014 
   1.4210854715202004E-014   1.1368683772161603E-013    0.000000000000000      
   2.1316282072803006E-013   1.4210854715202004E-014   5.6843418860808015E-014 
   1.2789769243681803E-013    0.000000000000000        2.9842794901924208E-013 
   1.4210854715202004E-014   1.4210854715202004E-013   1.4210854715202004E-013 
    0.000000000000000        3.9790393202565610E-013   1.4210854715202004E-014 
   2.8421709430404007E-013   1.5631940186722204E-013   1.4210854715202004E-014 
   5.1159076974727213E-013   1.4210854715202004E-014   4.9737991503207013E-013 
   1.7053025658242404E-013   7.1054273576010019E-014   6.3948846218409017E-013 
   1.4210854715202004E-014   7.9580786405131221E-013   1.8474111129762605E-013 
   2.1316282072803006E-013   7.8159700933611020E-013   1.4210854715202004E-014 
   1.1937117960769683E-012   1.9895196601282805E-013   4.9737991503207013E-013 
   9.3791641120333225E-013   2.8421709430404007E-014   1.7053025658242404E-012 
   2.1316282072803006E-013   9.9475983006414026E-013   1.1084466677857563E-012 
   9.9475983006414026E-014   2.3447910280083306E-012   2.2737367544323206E-013 
   1.7905676941154525E-012   1.2931877790833823E-012   3.1263880373444408E-013 
   3.1263880373444408E-012   2.4158453015843406E-013   2.9842794901924208E-012 
   1.4921397450962104E-012   8.1001871876651421E-013   4.0643044485477731E-012

and it takes about 500 elements to look random.

Hi Matt,

I’ll investigate this a bit further, but I think the core issue is due to using the same value for every seed. What happens if you set every seed to a different, non-consecutive, value?

  • Mat

Well, there is some interesting behavior.

Let’s try this:

seed = [ (i**n,i=1,seed_size) ]

with i = 1, 2, 3, 4.

With that, the end of “gross monotonicity”[1] in the random number array occurs at

(columns: i, rn(i), rn(i)-rn(i-1))

n=1:
          175   0.9038747378111367        5.6092745333572225E-002
          176   0.9663215774338880        6.2446839622751327E-002
          177   5.3497433696463759E-002  -0.9128241437374243     
          178   0.1081391630714705        5.4641729375006776E-002
          179   0.2113412797016991        0.1032021166302286     

n=2:
          130   0.9590979678618368        0.1254534862709704     
          131   0.9694915882269868        1.0393620365150014E-002
          132   6.4146635662140739E-002  -0.9053449525648460     
          133   0.1740371088950923        0.1098904732329515     
          134   0.1934591649581847        1.9422056063092441E-002

n=3:
           82   0.7702055796421803       -9.5573436214010599E-002
           83   0.9099665659761627        0.1397609863339824     
           84   2.5454639266655477E-003  -0.9074211020494971     
           85   6.7769169998683765E-003   4.2314530732028288E-003
           86   0.2405978579412391        0.2338209409413707     

n=4: 
            1   5.4477697201519959E-002   5.4477697201519959E-002
            2   7.3303230209631920E-002   1.8825533008111961E-002
            3   9.6714029835339943E-002   2.3410799625708023E-002
            4   0.1254882944081430        2.8774264572803077E-002
            5   0.1604957750028291        3.5007480594686058E-002
            6   5.6949621237706083E-002  -0.1035461537651230     
            7   7.7882774682890954E-002   2.0933153445184871E-002
            8   0.1045265305547645        2.6643755871873509E-002

Now, I say “gross monotonicity” because even at consecutive-i (n=1) it’s not purely monotonic, but generally monotonic:

 Results of calling random_number on an array:
            1   3.3378604769040976E-006   3.3378604769040976E-006
            2   3.8146976919506415E-006   4.7683721504654386E-007
            3   4.2915349069971853E-006   4.7683721504654386E-007
            4   4.7683721220437292E-006   4.7683721504654386E-007
            5   5.2452093370902730E-006   4.7683721504654386E-007
            6   4.7683721078328745E-006  -4.7683722925739858E-007
            7   5.4836279304026903E-006   7.1525582256981579E-007
            8   6.1988837529725060E-006   7.1525582256981579E-007
            9   6.9141395755423218E-006   7.1525582256981579E-007
           10   7.6293953981121376E-006   7.1525582256981579E-007
           11   7.3909767763780110E-006  -2.3841862173412665E-007
           12   8.3446512064710987E-006   9.5367443009308772E-007
           13   9.2983256365641864E-006   9.5367443009308772E-007
           14   1.0252000066657274E-005   9.5367443009308772E-007
           15   1.1205674496750362E-005   9.5367443009308772E-007
           16   1.1205674482539507E-005  -1.4210854715202004E-014
           17   1.2397767520155867E-005   1.1920930376163597E-006
           18   1.2636186113468284E-005   2.3841859331241722E-007
           19   1.4066697758607916E-005   1.4305116451396316E-006
           20   1.5497209403747547E-005   1.4305116451396316E-006
           21   1.5974046604583236E-005   4.7683720083568915E-007
           22   1.7642976857246140E-005   1.6689302526629035E-006
           23   1.7404558221301158E-005  -2.3841863594498136E-007
           24   1.9550325689010606E-005   2.1457674677094474E-006
           25   2.1696093156720053E-005   2.1457674677094474E-006
           26   2.2888186180125558E-005   1.1920930234055049E-006
           27   2.5272372255358277E-005   2.3841860752327193E-006
           28   2.4795534997679169E-005  -4.7683725767910801E-007
           29   2.7894976895481705E-005   3.0994418978025351E-006
           30   3.0994418793284240E-005   3.0994418978025351E-006
           31   3.3140186246782832E-005   2.1457674534985927E-006
           32   3.6478046752108639E-005   3.3378605053258070E-006
           33   3.6001209480218677E-005  -4.7683727188996272E-007
           34   4.0292744415637571E-005   4.2915349354188947E-006
           35   4.3630604906752524E-005   3.3378604911149523E-006
           36   4.7206884005390748E-005   3.5762790986382242E-006

The differences are small, but the random numbers are O(1e-6), then O(1e-5), etc.

It’s very…odd. I have no way to really prove these aren’t random numbers. They just don’t seem random at the beginning of generation.

Using the following code, I get the then following output:

! Program to test generation of random numbers.
!
Program test_random
integer :: values(1:8),k,it,maxiter
integer, allocatable, dimension(:) :: seed
real(8) :: rand, rand_total

call date_and_time(values = values)
call random_seed(size = k)
if(allocated(seed) == .true.) deallocate(seed)
allocate(seed(1:k))
seed(:) = values(8)
call random_seed(put = seed)
!

it = 0
maxiter = 10
do while(it <= maxiter)
it = it + 1
call random_number(rand)
print *,'it,rand = ',it,rand
end do
!
end

it,rand = 1 1.6188623450830164E-004
it,rand = 2 1.6188623450830164E-004
it,rand = 3 1.6188623450830164E-004
it,rand = 4 1.6188623450830164E-004
it,rand = 5 1.6188623450830164E-004
it,rand = 6 2.4282935176245246E-004
it,rand = 7 2.4282935176245246E-004
it,rand = 8 2.4282935176245246E-004
it,rand = 9 2.4282935176245246E-004
it,rand = 10 2.4282935176245246E-004
it,rand = 11 3.2377246901660328E-004

This has the same initial behaviour that was first reported by “The Matt”. The first five numbers are the same and then the next five numbers are the same!

Is this what you get when you run my short piece of code?

Malcolm

Furthur to my previous note I should have noted what I am running on:

mbibby3262 pgfortran -V

pgfortran 15.3-0 64-bit target on x86-64 Linux -tp nehalem
The Portland Group - PGI Compilers and Tools
Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.

Also I increased the MAXITER value to 20 in the code and got the following results:

it,rand = 1 1.1920930376163597E-004
it,rand = 2 1.1920930376163597E-004
it,rand = 3 1.1920930376163597E-004
it,rand = 4 1.1920930376163597E-004
it,rand = 5 1.1920930376163597E-004
it,rand = 6 1.7881395564245395E-004
it,rand = 7 1.7881395564245395E-004
it,rand = 8 1.7881395564245395E-004
it,rand = 9 1.7881395564245395E-004
it,rand = 10 1.7881395564245395E-004
it,rand = 11 2.3841860752327193E-004
it,rand = 12 2.3841860752327193E-004
it,rand = 13 2.3841860752327193E-004
it,rand = 14 2.3841860752327193E-004
it,rand = 15 2.3841860752327193E-004
it,rand = 16 2.9802325940408991E-004
it,rand = 17 2.9802325940408991E-004
it,rand = 18 3.5762791128490790E-004
it,rand = 19 3.5762791128490790E-004
it,rand = 20 3.5762791128490790E-004
it,rand = 21 4.1723256316572588E-004

It sure doesn’t look random! How do we get this fixed?

Malcolm

Hi Malcom,

The problem here is that you’re setting the seeds to the same value. Try setting them to different values.

  • Mat

Mat, are you saying that I have to set the seed each time I call random_number? I will try it, but it doesn’t seem right. That means two calls to generate one random_number - one for the seed followed by one for the number!!

Malcolm

Mat, by your reasoning, if I only set the seed once then I should get the same random numbers. Actually, as you can see from the data, without resetting the seed the numbers do change sporadically.

I assert that PGI has a problem with their random number generator! If you would like to modify the code that I submitted earlier to prove me wrong, then please do so.

Malcolm