DR
当我将数组从fortran传递到c时,数组的地址在c中是不正确的。我通过在
CALL
,然后进入C函数并打印参数的地址。
-
Fortran指针:
0x9acd44c0
-
C指针:
0xffffffff9acd44c0
C指针的上双字已设置为
0xffffffff
. 我试图理解为什么会发生这种情况,并且只在HPC集群上发生,而不是在开发机器上。
语境
我使用的是一个相当大的科学计划在Fortran /C++/CUDA。在某些特定的机器上,当从Fortran调用C函数时,我会得到一个segfault。我发现有一个指针被错误地传递给了C函数,并且设置了一些字节。
代码片段
程序中的每个Fortran文件都包含一个公共头文件,它设置了一些选项并声明了公共块。
IMPLICIT REAL*8 (A-H,O-Z)
COMMON/NBODY/ X(3,NMAX), BODY(NMAX)
COMMON/GPU/ GPUPHI(NMAX)
Fortran调用站点如下所示:
CALL GPUPOT(NN,BODY(IFIRST),X(1,IFIRST),GPUPHI)
以及C函数,它由
nvcc
,声明如下:
extern "C" void gpupot_(int *n,
double m[],
double x[][3],
double pot[]);
GDB输出
我在调试中发现
pot
不正确;因此任何访问该阵列的尝试都会出错。
当我用gdb运行程序时,我在
gpupot
并打印出
GPUPHI
变量:
(gdb) p &GPUPHI
$1 = (PTR TO -> ( real(kind=8) (1050000))) 0x9acd44c0 <gpu_>
然后我让调试器单步执行
gpupot_
C函数,并检查
锅
论点:
(gdb) p pot
$2 = (double *) 0xffffffff9acd44c0
所有其他参数都有正确的指针值。
编译器选项
为设置的编译器选项
gfortran
是:
-fPIC -O3 -ffast-math -Wall -fopenmp -mcmodel=medium -march=native -mavx -m64
和
NVCC
正在使用以下内容:
-ccbin=g++ -Xptxas -v -ftz=true -lineinfo -D_FORCE_INLINES \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_35,code=compute_35 -Xcompiler \
"-O3 -fPIC -Wall -fopenmp -std=c++11 -fPIE -m64 -mavx \
-march=native" -std=c++14 -lineinfo
对于调试,
-O3
替换为
-g -O0 -fcheck=all -fstack-protector -fno-omit-frame-pointer
但是行为(崩溃)保持不变。