Fortran forrtl:严重(151):已分配可分配数组-

Fortran forrtl:严重(151):已分配可分配数组-,fortran,openmp,Fortran,Openmp,我是Fortran新手,这是我第一次使用HPC和OpenMP。 在我的代码中,我有一个应该是并行的循环。我使用了一些动态变量,它们在并行循环中都是虚拟的 我在并行循环中分配动态变量 /var/spool/torque/mom_priv/jobs/775.head.cluster.SC: line 22: 28084 Segmentation fault ./a.out 我省略了代码中一些不相关的部分。执行程序时,会发生以下错误: !$OMP PARALLEL DO do 25

我是Fortran新手,这是我第一次使用HPC和OpenMP。 在我的代码中,我有一个应该是并行的循环。我使用了一些动态变量,它们在并行循环中都是虚拟的

我在并行循环中分配动态变量

/var/spool/torque/mom_priv/jobs/775.head.cluster.SC: line 22: 28084 Segmentation fault      ./a.out
我省略了代码中一些不相关的部分。执行程序时,会发生以下错误:

  !$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
forrtl: severe (151): allocatable array is already allocated
我将变量分配到并行区域之外,它适用于小数据,但对于大数据,会出现以下错误:

  !$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
forrtl: severe (151): allocatable array is already allocated
我对动态变量(虚拟变量)使用了PRIVATE子句:

在并行循环中分配变量,但同样的错误, 最后,我将代码更改为:

!$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)
它在运行时失败。它启动N个(线程数)循环,但无法完成它们,再次出现此错误:

  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)

有什么想法吗?

我修改了代码,终于成功了! 指令
$OMP并行DO
是两个指令的快捷方式
$OMP并行
$OMP DO
。我使用了这两个指令(而不是
!$OMP PARALLEL DO
)并将分配放在并行区域内。我猜(但我不确定),现在编译器知道如何获取私有变量的内存,因为我在分配之前放置了private子句,所以
分段错误
不会发生

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

您希望在循环
private
中分配所有变量。或者你不想在循环内部分配,而是在循环外部分配。你的意思是我应该使用'$OMP PARALLEL DO PRIVATE(),并将所有可分配变量放在括号中?如果我在循环外进行分配,就会出现内存不足,不是吗?这取决于你到底想做什么。也许你应该试着让它脱离循环。您确定您的串行代码按预期工作吗?我们不知道
num
order
iconf
的值来自何处。所有这些动态变量都是虚拟的,只能在并行循环中创建和使用。num、order、config是从文件读取的输入数据,iconf是循环的索引。我的串行代码工作正常。我认为并行循环中的allocate和deallocate变量有助于hpc使用更少的内存,对吗?不,编译器在调用
allocate
时分配可分配数组。如果你一开始就做一次,事情就会发生一次。如果在每个循环迭代中都这样做,那么它会在每个循环迭代中发生。但从你目前的逻辑来看,你可能需要保密。但是,这意味着内存增加了N倍,其中N是线程数。但我只是在猜测
call PLproduct(…)
的功能。谢谢马克的评论,我编辑了答案。