MPI を使用する古くて厄介な Fortran プログラムがあります。malloc()
C で記述された小さなモジュールが 1 つあり、が返されるまで繰り返し呼び出してメモリ内の最大の割り当て可能なブロックを決定しようとしnull
、次に成功した最大の割り当てサイズを Fortran プログラムに返します。
を使用してコンパイルするとgfortran
うまく動作しますが、 を使用しようとするmpif90
と、最後malloc()
に を返す代わりに segfault が発生しnull
ます。
これは、実際の MPI コードを含まない最小の例です。ファイルmain.f
:
program test
complex(8) :: sig(256000000) ! Just allocating some big array in fortran
sig(1) = 0.d0 ! and now wondering how much space is left?
call bigalloc
end
ファイルbigalloc.c
#include <stdlib.h>
#include <stdio.h>
void bigalloc_() {
size_t step = 0x80000000;
size_t size = 0;
int failed = 0;
void* p;
do {
size += step;
p = malloc(size);
if (p) {
free(p);
printf("Allocated %zd...\n", size);
} else {
printf("So, that's our limit\n");
failed = 1;
}
} while (!failed);
}
以下を使用してコンパイルおよび実行しますgfortran
(期待どおりに動作します):
~$ gcc -c bigalloc.c -o bigalloc.o && gfortran -o main main.f bigalloc.o && ./main
Allocated 2147483648...
Allocated 4294967296...
So, that's our limit
MPI でコンパイルして実行 (失敗):
~$ gcc -c bigalloc.c -o bigalloc.o && mpif90 -o main main.f bigalloc.o && ./main
Allocated 2147483648...
Allocated 4294967296...
Segmentation fault
gcc
ここで何も変更しないで置き換えmpicc
ます。main
も C で書かれ、mpicc
すべてを使用してコンパイルされる場合も OK です。したがって、問題は Fortran だけです。
の出力mpif90 -show
はこちらです。問題は、オプションの存在のみに依存し-lopen-pal
ます。
$ mpif90 -show
gfortran -I/usr/include/openmpi/1.2.4-gcc/64 -I/usr/include/openmpi/1.2.4-gcc -m64 -pthread -I/usr/lib64/openmpi/1.2.4-gcc -L/usr/lib64/openmpi/1.2.4-gcc -lmpi_f90 -lmpi_f77 -lmpi -lopen-rte -lopen-pal -ldl -Wl,--export-dynamic -lnsl -lutil -lm -ldl
MPI をリンクしている間、stnadardmalloc
を PAL からの独自の stnadard に置き換えているようですが、これは例外では適切に機能しません。bigalloc.c
それを回避する方法はありますか (たとえば、myをglibc
静的にリンクするなど)?