Указатель маскируется при вызове функции C из Фортрана - PullRequest
0 голосов
/ 26 января 2019

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, но поведение (сбой) остается прежним.

1 Ответ

0 голосов
/ 26 января 2019

Это предваряется моими главными комментариями [и вашими].

Похоже, вы получаете [нежелательный] знак расширения адреса.

gfortran строитсяс -mcmodel=medium, но не с.

С этой опцией, более крупные символы / массивы будут связаны свыше 2 ГБ [с установленным битом знака]

Итак, добавьте опцию к обоим илиоставьте оба, чтобы решить проблему.

...