元は F77 で記述され、現在は F90 で記述されているセル コードで 3D パーティクルをデバッグしようとしています。私自身と私の監督者は、コードがビジー状態になった時点で発生するメモリ リークが原因であると考えています (物理相互作用の後 - 多くの粒子が動き回っている場合)。Valgrind は、openMPI 抑制ファイルを使用して以下を実行します。
==8057== Invalid read of size 8
==8057== at 0x424300: send_b_bd_ (rpp3dsubs.f90:4521)
==8057== by 0x43C23A: mymain_ (rpp3dmain.f90:1651)
==8057== by 0x40221F: MAIN__ (rpp3d.f90:386)
==8057== by 0x401BAC: main (rpp3d.f90:199)
==8057== Address 0x16f81100 is 0 bytes inside a block of size 38,528 alloc'd
==8057== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==8057== by 0x438329: mymain_ (rpp3dmain.f90:120)
==8057== by 0x40221F: MAIN__ (rpp3d.f90:386)
==8057== by 0x401BAC: main (rpp3d.f90:199)
これらのエラーは約 30 個ほどあります。指摘されているサブルーチンの 1 つがこれです。
SUBROUTINE send_B_bd(myid)
USE B_bd_arrays
USE grid_parameter
IMPLICIT NONE
INCLUDE 'mpif.h'
INTEGER idown,iup,inorth,isouth,tag,ierr,mpi_status,myid
! to +x and from -x
IF (up >= 0) THEN
tag = 0
CALL MPI_SEND(B_bd_up(1,1),2*Grid_y*Grid_z,MPI_DOUBLE_PRECISION, &
up,tag,MPI_COMM_WORLD,ierr)
END IF
IF (down >= 0) THEN
tag = 0
CALL MPI_RECV(B_bd_up(1,1),2*Grid_y*Grid_z,MPI_DOUBLE_PRECISION, &
down,tag,MPI_COMM_WORLD,mpi_status,ierr)
B_bd_down=B_bd_up
ELSE
B_bd_down=0.0d0
END IF
B_bd_up=0.0d0
! to +y and from -y
IF (north >= 0) THEN
tag = 0
CALL MPI_SEND(B_bd_north(1,1),2*Grid_x*Grid_z,MPI_DOUBLE_PRECISION, &
north,tag,MPI_COMM_WORLD,ierr)
END IF
IF (south >= 0) THEN
tag = 0
CALL MPI_RECV(B_bd_north(1,1),2*Grid_x*Grid_z,MPI_DOUBLE_PRECISION, &
south,tag,MPI_COMM_WORLD,mpi_status,ierr)
B_bd_south=B_bd_north
ELSE
B_bd_south=0.0d0
END IF
B_bd_north=0.0d0
END SUBROUTINE send_B_bd
問題の原因となっている行は
B_bd_up=0.0d0
B_bd_down=0.0d0
および他の同様の割り当てステートメント。これらは、コードの別の場所 (基になるファイル rpp3d 内) で宣言されており、宣言ステートメントは次のとおりです。
module B_bd_arrays
DOUBLE PRECISION, ALLOCATABLE,save, DIMENSION (:,:) :: &
B_bd_north,B_bd_south,B_bd_down, B_bd_up
end module B_bd_arrays
これらは抑圧に値する声明であると想定しても安全ですか、それとももっと根本的なことが起こっているのでしょうか? このコードで高解像度を実行すると、何かが非物理的な結果を引き起こしていることを繰り返します。そのため、コードのより根本的な問題を検討する前に、すべての基本的なエラーを排除しようとしています。
これは非常に単純な質問かもしれませんが、私より知識のある方からの回答を希望します。私が理解しているように、
fortranArray = 0.0d0
配列をゼロにする完全に有効な方法であり、使用できないメモリにアクセスしようとするコードを生成する可能性は低いです。
さらに、次のような割り当てステートメントについても同様の問題が発生するようです。
E_bd_down(iy,iz)=Ex(ix,iy,iz)
E_bd_down(Grid_y+iy,iz)=Ey(ix,iy,iz)
E_bd_down(2*Grid_y+iy,iz)=Ez(ix,iy,iz)
これは同時発生とは言えません。私は一生、何が間違っているのか理解できません。