2

このコードは、Intel コンパイラで実行すると機能します。ただし、pgi で実行すると、リストされているサブルーチンの * と ** の間で障害がセグメント化されます。-mcmodel-medium で pgi コンパイラを使用しています。このコードで openacc の使用を開始するには、PGI を使用する必要があります。何が間違っているのでしょうか?前もって感謝します!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!Reading in trajectories from 'md.traj' file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE READ_INPUT(time_i,time_f,dt,ION_COUNT,x,y,z,lf,l,nsteps)

    IMPLICIT NONE
    Integer*4, Intent(IN)                           ::time_i,time_f,dt
    Real*4,Intent(OUT),DIMENSION(:,:), Allocatable  ::x,y,z
    Real*4                                          ::vx,vy,vz
    Real*8,  Intent(OUT)                            ::lf,l
    Integer*4                                       ::time,t,j,nsteps
    Integer*4                                       ::ION_COUNT
    Character*100                                   ::filename
    Character*5                                     ::timezone
    Character*6                                     ::xfiletype
    Character*8                                     ::xcode_version,date
    Character*10                                    ::xcode_name,daytime
    Character*20                                    ::xsim_type
    Real*8                                         ::time_set,aspect(3),ev,ek,ppx,pp(9),rho
write (*,*) '*'         
    Allocate(x(1:51200,0:nsteps))
    Allocate(y(1:51200,0:nsteps))
    Allocate(z(1:51200,0:nsteps))
write (*,*) '**'

    open(UNIT=20,FILE='md.traj.00007000000.xv4b',status='OLD',form='unformatted',convert='BIG_ENDIAN')
    Do 20, time=time_i, time_f, dt
     write (*,*) time
     write(*,1001) time
1001    format ('md.',1I11.11,'.x4b')
     write (filename,1001) time
     read(20) xfiletype
     read(20) xcode_name, xcode_version
     read(20) date,daytime,timezone
     read(20) xsim_type
     read(20) time_set,rho,aspect(1),aspect(2),aspect(3),ev, ek, ppx, pp, ION_COUNT
     !rho=ION_COUNT/(xl(1)*xl(2)*xl(3))
     t=(time-time_i)/dt

! サブルーチン コード内に割り当てずに、この行のセグメント フォールト

     read (20) (x(j,t),y(j,t),z(j,t),vx,vy,vz, j=1,ION_COUNT) 
     l=(ION_COUNT/(rho))**(1.0/3.0)
    !write (*,*) x(500,5),'in read input'
     lf=(2*3.1415)/l
    20 continue

    RETURN
    END SUBROUTINE READ_INPUT
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

メインコードはこちら

  Program SofQ

  Implicit NONE  
  Integer            :: time,time_u,j,i,k,OMP_NUM_THREADS
  Integer            :: t1,t3,t4,K2
  Integer            :: dw,t,time1,time2
  Real*4             :: sumbin(0:50000)
  Real*8             :: f(0:500,0:10000)
  Integer            :: Q1,Q2,Q3,Q4,Q5,N1,N2,N3,N4,N5,Qcur
  Real*4             :: CI,co(0:6537673),si(0:6537673),b(0:6537673)
  Real*8             :: dotprod,co_temp,si_temp
  Real*4             :: Qavg,zz,qmax,pfrac,nfrac
  Complex*16,Allocatable:: q(:,:)
  Complex            :: sumbin1(0:50000),sumbin2(0:50000)
  Double Precision   :: yy 
  Character          :: sofq_output,dumb
  Parameter (CI=(0,-1))
  Real*8             ::rtemp1,rtemp2,rtemp3
  Character*5        :: simtype

  Integer*4          ::p_start,p_end,nsteps

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Declarations for READ_INPUT
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  Integer*4                          ::time_i,time_f,dt,ION_COUNT
  Real*4,Dimension(:,:),Allocatable  ::x,y,z
  Real*8                             ::lf,l
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!Declarations for READ_VECTORS
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  Integer*4                         ::vmax,lines,i_vmax
  Integer*4, Dimension(1:6537673)   ::rx,ry,rz,mag,degen
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!Declarations for COMPUTE_SQ
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  Integer*4                         ::ions,t2
  Real*8, Allocatable               ::s(:)
  Complex*16,Allocatable            ::r(:,:)


open (UNIT=11,File='sqt_n1_gpu.dat')
write (*,*) 'begin'     
call system_clock(time1)      

  dt=20
  time_i= 7000000
  time_f= 7000500 !7050000

    nsteps=(time_f-time_i)/dt
    Allocate(x(1:51200,0:nsteps))
    Allocate(y(1:51200,0:nsteps))
    Allocate(z(1:51200,0:nsteps))  

  ION_COUNT=51200
  qmax=0.6
  simtype='pfrac'

!      OMP_NUM_THREADS=16

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Parallel Test!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!       !$OMP PARALLEL
!       write (*,*) 'Parallel?'
!       !$OMP END PARALLEL
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    CALL READ_INPUT(time_i,time_f,dt,ION_COUNT,x,y,z,lf,l,nsteps)
write (*,*) 'input'

そのため、いくつかのコメンターがサブルーチン内の再割り当てについて尋ねました。これを行ったのは、最初に 2 番目の割り当てなしで試してみたところ、最初の x() 値を読み取るときにサブルーチンでセグメンテーション違反を受け取ったためです。サブルーチンの割り当てをコメントアウトして、これをもう一度試してみたところ、x() の読み取り中に PGI seg が失敗し、Intel コンパイラが同じことをしたことがわかりました。この行は上で太字で示されています。

4

1 に答える 1

0

intent(OUT)割り当て可能な配列である引数にを使用すると、配列変数 (この場合は x、y、z) は、サブルーチンに入ると「未割り当て」になります。したがって、この場合、使用を開始する前にサブルーチン内に割り当てる必要があります。

サブルーチン内で割り当て可能な配列を割り当てる場合、それは仮引数に関連付けられているため、配列がローカル配列の場合のように、サブルーチンの最後で割り当てが解除されることはありません。

そのため、単に x、y、z を指定してintent(inout)(または何も指定しないで、この場合は "intent(INOUT)" はインテントを定義しないのと同じ影響があります) 宣言するだけでよく、サブルーチン内で配列を再度割り当てる必要はありません。または、ルーチン内でのみ割り当てて、ルーチン外での割り当てを避けることもできます。しかし、サブルーチンの外で配列を使用したいと思われる場合、これは悪い習慣だと思います。

サブルーチン内で「割り当て」ずにコードを使用すると、両方のコンパイラが「セグフォールト」するという事実は、配列がサブルーチンに入るときに割り当てられないため、正しい動作です (インテント (out) のため)。サブルーチン内で配列を「再度」割り当てた場合の PGI の「seg fault」は、ある種のコンパイラのバグのようです。この場合、PGI を使用する場合は、サブルーチンの外側に割り当てることが唯一の利用可能なオプションになる可能性があります。

于 2014-11-29T10:33:43.197 に答える