0
votes
/var/spool/torque/mom_priv/jobs/775.head.cluster.SC: line 22: 28084 Segmentation fault      ./a.out

I am new in Fortran and this is the first time I work with HPC and OpenMP. In my code, I have a loop that should be parallel. I use some dynamic variables that all of them are dummy in the parallel loop.

I allocate the dynamic variables in parallel loop

  !$OMP PARALLEL DO
  do 250 iconf = 1,config

  allocate(randx(num),randy(num),randz(num),unit_cg(num),           &
 &          x(nfftdim1),y(nfftdim2),z(nfftdim3),fr1(num),           &
 &          fr2(num),fr3(num),theta1(order,num),                    &
 &          theta2(order,num),theta3(order,num),                    &
 &          Q(nfftdim1,nfftdim2,nfftdim3))  

... call some subroutines and do calculations ...

  deallocate(randx,randy,randz,unit_cg,fr1,fr2,fr3,theta1,theta2,   &
 &            theta3,x,y,z,Q)
  250   continue
  !$OMP END PARALLEL DO

I omited some irrelevant part of code. When the program is executed, this error occurs:

forrtl: severe (151): allocatable array is already allocated

I allocated the variables outside the parallel region, it works for small data, but for large data this error occurs:

/var/spool/torque/mom_priv/jobs/775.head.cluster.SC: line 22: 28084 Segmentation fault      ./a.out

I used PRIVATE clause for dynamic variables (dummy variables):

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(randx,randy,randz,            &
!$OMP& unit_cg,fr1,fr2,fr3,theta1,theta2,theta3,x,y,z,Q,                &
!$OMP& dir_ene,rec_ene,corr_ene,energy_final,plproduct_avg,             &
!$OMP& correlation_term)

and allocated variables inside parallel loop, but the same error, at last I changed the code to:

  allocate(randx(num),randy(num),randz(num),unit_cg(num),           &
 &          x(nfftdim1),y(nfftdim2),z(nfftdim3),fr1(num),           &
 &          fr2(num),fr3(num),theta1(order,num),                    &
 &          theta2(order,num),theta3(order,num),                    &
 &          Q(nfftdim1,nfftdim2,nfftdim3))  

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(randx,randy,randz,            &
!$OMP& unit_cg,fr1,fr2,fr3,theta1,theta2,theta3,x,y,z,Q,                &
!$OMP& dir_ene,rec_ene,corr_ene,energy_final,plproduct_avg,             &
!$OMP& correlation_term)


  do 250 iconf = 1,config

... call some subroutines and do calculations ...

  250   continue

  !$OMP END PARALLEL DO
      deallocate(randx,randy,randz,unit_cg,fr1,fr2,fr3,theta1,theta2,   &
 &            theta3,x,y,z,Q)

it fails at run-time. it starts N (number of thread) loops, but can not complete them, and again this error:

    /var/spool/torque/mom_priv/jobs/775.head.cluster.SC: line 22: 28084 Segmentation fault      ./a.out

any idea?

1
You want all of the variables you allocate in the loop private. Or you do not want to allocate them inside the loop, but outside. - Vladimir F
You mean I should use '!$OMP PARALLEL DO PRIVATE()' and put all the allocatable variables in the parenthesis? If I allocate outside the loop, the memory shortage occurs, doesn't it? - Motahareh Kia
That depends on what exactly you are trying to do. Perhaps you should try to get it outside the loop. Are you sure your serial code works as intended? We dont know where do the values of num, order and iconf come from. - Vladimir F
all of this dynamic variables are dummy and create and use only in parallel loop. and num, order, config are input data read from the file and iconf is the index of loop. my serial code works correctly. I think allocate and deallocate variables in the parallel loop help hpc to use less memory, am I right? - Motahareh Kia
No, the compiler allocates the allocatable array when you call allocate. If you do it once at the start it happens once. If you do it in every loop iteration, it happens in every loop iteration. But looking at you current logic, you probably need them private. However, that means N times more memory, where N is the number of threads. But I am just guessing what call PLproduct(...) does. - Vladimir F

1 Answers

2
votes

I changed the code and finally it WORKS! The directive !$OMP PARALLEL DO is the shortcut of two directives !$OMP PARALLEL and !$OMP DO. I used these two directives (instead of !$OMP PARALLEL DO) and put allocation inside parallel region. I guess (but I'm not sure), now the compiler knows how to get memories for private variables, because I put private clause before allocation and so the segmentation fault dose not occur.

!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(iconf,d,randx,                   &
!$OMP& randy,randz,unit_cg,theta1,theta2,theta3,fr1,fr2,fr3,Q,          &
!$OMP& plproduct_avg) 

      allocate(randx(num),randy(num),randz(num),unit_cg(num),           &
     &         fr1(num),fr2(num),fr3(num),theta1(order,num),            &
     &         theta2(order,num),theta3(order,num),                     &
     &         Q(nfftdim1,nfftdim2,nfftdim3))

!$OMP DO 
  do 250 iconf = 1,config
... call some subroutines and do calculations ...
  250   continue
!$OMP END DO

  deallocate(randx,randy,randz,unit_cg,fr1,fr2,fr3,theta1,theta2,   &
 &           theta3,Q)

!$OMP END PARALLEL