Ошибка сегментации в программе Fortran с использованием функций RMA MPI-2
Следующая короткая программа Fortran90 аварийно завершает работу, если она содержит вызов MPI_GET. Ранг 1 пытается прочитать значение из ранга 0 и зависает в MPI_WIN_UNLOCK. Попытка ранга 0 завершается сбоем в MPI_BARRIER с ошибкой сегментации.
Я неоднократно проверял синтаксис команд, но они, похоже, были правильными. Аналогичный код в C / C++ работает в той же системе.Я использую OpenMPI 1.4.3 и gfortran 4.4.5.
PROGRAM mpitest
USE mpi
IMPLICIT NONE
INTEGER :: ierr, npe, rnk, win
INTEGER (KIND=MPI_ADDRESS_KIND) lowerbound, sizeofreal
REAL :: val = 1.0, oval = 2.0
CALL MPI_INIT( ierr )
CALL MPI_COMM_RANK( MPI_COMM_WORLD, rnk, ierr )
CALL MPI_COMM_SIZE( MPI_COMM_WORLD, npe, ierr )
CALL MPI_TYPE_GET_EXTENT(MPI_REAL, lowerbound, sizeofreal, ierr)
CALL MPI_WIN_CREATE(val, sizeofreal, sizeofreal, MPI_INFO_NULL, MPI_COMM_WORLD, win, ierr)
IF( rnk .EQ. 1 ) THEN
CALL MPI_WIN_LOCK( MPI_LOCK_SHARED, 0, 0, win, ierr )
CALL MPI_GET( oval, 1, MPI_REAL, 0, 0, 1, MPI_REAL, win, ierr )
CALL MPI_WIN_UNLOCK( 0, win, ierr )
END IF
CALL MPI_BARRIER( MPI_COMM_WORLD, ierr )
CALL MPI_WIN_FREE(win, ierr)
CALL MPI_FINALIZE(ierr)
END PROGRAM mpitest
mpif90 mpitest.f90
mpirun -n 2 ./a.out
*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: 0x34006020a0
[ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x36420) [0x7f2d1c8c1420]
[ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x13ae70) [0x7f2d1c9c5e70]
[ 2] /usr/lib/libmpi.so.0(ompi_convertor_pack+0x199) [0x7f2d1c61d629]
[ 3] /usr/lib/openmpi/lib/openmpi/mca_osc_pt2pt.so(+0x56b0) [0x7f2d166876b0]
[ 4] /usr/lib/openmpi/lib/openmpi/mca_osc_pt2pt.so(+0x3a81) [0x7f2d16685a81]
[ 5] /usr/lib/openmpi/lib/openmpi/mca_osc_pt2pt.so(+0x23ac) [0x7f2d166843ac]
[ 6] /usr/lib/libopen-pal.so.0(opal_progress+0x5b) [0x7f2d1ba700db]
[ 7] /usr/lib/libmpi.so.0(+0x35635) [0x7f2d1c60f635]
[ 8] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(+0x1afa) [0x7f2d1688eafa]
[ 9] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(+0x958f) [0x7f2d1689658f]
[10] /usr/lib/libmpi.so.0(MPI_Barrier+0x8d) [0x7f2d1c6250cd]
[11] /usr/lib/libmpi_f77.so.0(PMPI_BARRIER+0x13) [0x7f2d1cf661d3]
[12] ./a.out() [0x401003]
[13] ./a.out(main+0x34) [0x401058]
[14] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f2d1c8ac30d]
[15] ./a.out() [0x400da9]
*** End of error message ***
1 ответ:
Это сложно, но ключ к разгадке приходит из того факта, что segfault происходит здесь в несвязанной и совершенно безопасной процедуре,
MPI_Barrier()
. Проблема в том, что существует повреждение стека.Основная проблема - это просто несоответствие типа аргумента (которое я надеялся, что привязки MPI Fortran поймают, но не поймали). Целевой аргумент смещения в MPI_Get является целым числом вида
MPI_ADDRESS_KIND
, но вы просто передаете ему целое число.Если вы используете
lowerbound
в качестве своего target offset, или продвигать 0, который вы передаете, чтобы быть своего рода MPI_ADDRESS_KIND явно, ваша программа работает.