TL; DR
Когда я передаю массив из Fortran в C, адрес массива неверен в C. Я проверил это, напечатав адрес массива в Fortran до CALL
, затем перейдя в функцию C и напечатав адрес аргумента.
- Указатель Фортрана:
0x9acd44c0
- Указатель C:
0xffffffff9acd44c0
Верхнее слово указателя C было установлено на 0xffffffff
. Я пытаюсь понять, почему это происходит, и происходит только в кластере HPC, а не на компьютере разработчика.
Контекст
Я использую довольно большую научную программу, написанную на Fortran / C ++ / CUDA. На какой-то конкретной машине я получаю segfault при вызове функции C из Fortran. Я обнаружил, что указатель на функцию C передается с некоторыми неправильно установленными байтами.
Фрагменты кода
Каждый файл Фортрана в программе содержит общий заголовочный файл, который устанавливает некоторые параметры и объявляет общие блоки.
IMPLICIT REAL*8 (A-H,O-Z)
COMMON/NBODY/ X(3,NMAX), BODY(NMAX)
COMMON/GPU/ GPUPHI(NMAX)
Сайт вызова Фортрана выглядит так:
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 и проверил значение аргумента 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
, но поведение (сбой) остается прежним.