0

ここで、move_alloc が gfortran 4.2 以降で機能することを読みました。ubuntu 12.04にgfortran 4.6がインストールされていますが、move_allocが機能していません! move_alloc は、10 回実行されるループ内で 5 回使用されます。gfrotran を使用して (エラーや警告なしで) コンパイルした後、プログラムはループの 1 つのステップのみを実行し (間違いを確認するためにいくつかの出力が表示されます)、「セグメンテーション違反 (カーネル イメージが記録されました)」と表示されます。ただし、ifort を使用すると、プログラムはCentOS で gfortran 4.4.6 を使用しようとしました. どちらのコンピューターも x86_64 です.

その他の重要な情報: コードのこの部分は、move_alloc によって割り当てられたベクトルのサイズがわからない場合、モジュール内のサブルーチンにあります。これらすべてのベクトルは、サブルーチンで属性インテント (out) を使用しています。xray_all、yray_all、elem_all は倍精度で、その他は整数です。メインとモジュールは別のファイルにあります。これは、move_alloc を使用するコードの一部です。

program main
double precision,allocatable,dimension(:)::xrayall,yrayall
(...)other allocatable variables
call yyyy(....,ray_indent,xray_all,...)
end program main 

module xxxx
subroutine yyyy
do j=1,10
  <lots of calculation>

     allocate( vec_aux( 1:(i+size(ray_indent) ) ) )
     vec_aux(1:size(ray_indent))=ray_indent
     vec_aux(size(ray_indent)+1:)=j   
     call MOVE_ALLOC(vec_aux,ray_indent) 

    allocate( vec_auxreal( 1:(i+size(xray_all) ) ) )
    vec_auxreal(1:size(xray_all))=xray_all
    vec_auxreal(size(xray_all)+1:)=xray
    call MOVE_ALLOC(vec_auxreal,xray_all)          

    allocate( vec_auxreal( 1:(i+size(yray_all) ) ) )
    vec_auxreal(1:size(yray_all))=yray_all
    vec_auxreal(size(yray_all)+1:)=yray
    call MOVE_ALLOC(vec_auxreal,yray_all)             

    elemsize=count(icol/=0);

     allocate( vec_auxreal( 1:(elemsize+size(elem_all) ) ) )
     vec_auxreal(1:size(elem_all))=elem_all
     vec_auxreal(size(elem_all)+1:)=elem(1:elemsize)
     call MOVE_ALLOC(vec_auxreal,elem_all)         

     allocate( vec_aux( 1:(elemsize+size(icol_all) ) ) )
     vec_aux(1:size(icol_all))=icol_all
     vec_aux(size(icol_all)+1:)=icol(1:elemsize)
     call MOVE_ALLOC(vec_aux,icol_all)

    allocate( vec_aux( 1:(elemsize+size(irow_all) ) ) )
    vec_aux(1:size(irow_all))=irow_all
    vec_aux(size(irow_all)+1:)=j+control           !
    call MOVE_ALLOC(vec_aux,irow_all)
end do
end module xxxx
end subroutine yyyy
4

1 に答える 1

0

私は解決策を見つけました!gfortran では、5 つの式すべてに次の if ステートメントを追加する必要があります。

 allocate( vec_auxreal( 1:(elemsize+size(elem_all) ) ) )
 if (j/=1) vec_auxreal(1:size(elem_all))=elem_all 
 vec_auxreal(size(elem_all)+1:)=elem(1:elemsize) 
 call MOVE_ALLOC(vec_auxreal,elem_all)

これは、ベクトルがまだ空の場合、gfortran では何も追加しないことが認識されないために発生します。ifort (バージョン 12.0 でテスト済み) では、この if ステートメントはプログラムの動作に必要ありません。

于 2013-08-21T15:23:39.753 に答える