簡體   English   中英

從 Fortran 調用 C 函數時,指針被屏蔽

[英]Pointer is being being masked when calling a C function from Fortran

TL; 博士

當我將一個數組從 Fortran 傳遞給 C 時,該數組的地址在 C 中是不正確的。我通過在CALL之前在 Fortran 中打印數組的地址來檢查這一點,然后進入 C 函數並打印參數的地址。

  • Fortran 指針: 0x9acd44c0
  • C 指針: 0xffffffff9acd44c0

C 指針的高位雙字已設置為0xffffffff 我試圖理解為什么會發生這種情況,並且只發生在 HPC 集群上,而不是在開發機器上。

語境

我正在使用一個用 Fortran/C++/CUDA 編寫的相當大的科學程序。 在某些特定機器上,從 Fortran 調用 C 函數時出現段錯誤。 我發現一個指針被傳遞給 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)

nvcc編譯的 C 函數聲明如下:

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_函數,並檢查pot參數的值:

(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 ,但行為(崩潰)保持不變。

這是我的主要評論 [和你的] 的序言。

您似乎收到了地址的 [不需要的] 標志擴展名。

gfortran是用-mcmodel=medium構建的,但 C 沒有。

使用該選項,較大的符號/數組將鏈接到 2GB 以上 [已設置符號位]

因此,將選項添加到兩者或將其都保留以解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM