我有一个使用 MPI 的旧且凌乱的 Fortran 程序。它有一个用 C 编写的小模块,它试图通过malloc()
迭代调用来确定内存中最大的可分配块,直到它返回null
,然后将最大的成功分配大小返回给 Fortran 程序。
当我使用它编译它时gfortran
,它运行良好,但是当我尝试使用它时mpif90
,最后一个malloc()
导致段错误而不是返回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);
}
使用 just 编译和运行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
一切编译时也可以。所以问题出在 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 时,将标准替换为malloc
PAL 中自己的标准,这在异常情况下无法正常工作。有没有办法绕过它(例如,通过某种方式将 mybigalloc.c
与glibc
静态链接)?