代码之家  ›  专栏  ›  技术社区  ›  Anthony Atmaram

从Fortran调用C函数时,指针被屏蔽

  •  1
  • Anthony Atmaram  · 技术社区  · 6 年前

    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 但是行为(崩溃)保持不变。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Craig Estey    6 年前

    这是我[和你]的评论的前言。

    看起来你得到了地址的[不需要的]符号扩展。

    gfortran 正在用 -mcmodel=medium 但是C没有。

    使用该选项,较大的符号/数组将链接到2GB以上[设置了符号位]

    因此,可以同时添加这两个选项,也可以同时取消这两个选项来解决问题。