[英]Pointer is being being masked when calling a C function from Fortran
當我將一個數組從 Fortran 傳遞給 C 時,該數組的地址在 C 中是不正確的。我通過在CALL
之前在 Fortran 中打印數組的地址來檢查這一點,然后進入 C 函數並打印參數的地址。
0x9acd44c0
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[]);
調試發現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.