Отклонения METIS seg при запуске из Fortran

Я пытаюсь использовать библиотеку METIS для секционирования mesh как часть программы Fortran, которую я написал для вычисления конечных элементов. METIS написан на C, но он должен отлично работать с Fortran 90. Но я продолжаю получать seg-ошибки.

Один потенциальный икота состоит в том, что есть несколько аргументов, которым я даю нулевые указатели. Некоторым другим людям было сложно получить вызов функции C из fortran, чтобы распознать объект с нулевым указателем. Это было рассмотрено здесь, и я не думаю, что это вопрос, который у меня есть.

Я думаю, что проблема заключается в том, чтобы METIS изменил индекс начального массива; в C это 0, в Fortran – 1. Есть массив options переданный каждой функции, которая должна иметь поле METIS_OPTION_NUMBERING которое вы измените на 1 если вы хотите принять соглашение Fortran. В противном случае программа C попытается получить доступ к индексу 0, что даст вам ошибку seg.

Сообщение edunlop1 здесь говорит о том, что я просто делаю options массива options а некоторые согласованные соглашения с METIS определяют, какой элемент этого массива должен быть установлен равным 1, чтобы он мог перенумеровать каждый. Но что это за изменения в зависимости от используемой вами процедуры, равно как и длина массива.

Во всяком случае, вот мой код:

 integer :: ndomains,ncommon,objval integer :: options(0:40) integer, dimension(:), allocatable :: eptr,eind integer, pointer :: vwgt(:)=>null(), vsize(:)=>null(), opts(:)=>null() real(kind=8), pointer :: tpwgts(:)=>null() ! Read in the mesh data call getarg(1,meshname) call readmesh(meshname) allocate(color(ne),domain(nn)) allocate(eind(3*ne),eptr(ne+1)) do n=1,ne eptr(n) = 1+3*(n-1) do i=1,3 eind( eptr(n)+i-1 ) = elem(i,n) enddo enddo ! Try and call METIS ncommon = 2 ndomains = 2 options = 0 options(0) = 1 options(8) = 1 call METIS_PartMeshDual(ne,nn,eptr,eind,vwgt,vsize, & & ncommon,ndomains,tpwgts,options,objval,color,domain) 

Соответствующий код в METIS для изменения нумерации находится в файле libmetis / meshpart.c:

 /* renumber the mesh */ if (options && options[METIS_OPTION_NUMBERING] == 1) { ChangeMesh2CNumbering(*ne, eptr, eind); renumber = 1; } 

Какие-нибудь мысли? Я могу опубликовать вывод Valgrind, если это полезно.

    Использование:

     vwgt=>null() 

    вместо

     vwgt(:)=>null() 

    для всех нhive (т. е. vwgt, vsize, opts, tpwgts и т. д.). Проблема в том, что vwgt (:) действительно не определен, а не только vwgt или vwgt (1). Если у вас все еще есть проблемы, используйте отладчик для проверки всех значений.

    Я был ОП в теме, упомянутой во втором параграфе. Окончательное решение, к сожалению, находится в верхней части ответов (см. Отметку времени). Надеюсь, это поможет.

    Для этого может быть ничего, но, возможно, связанный пост во втором абзаце вопроса по-прежнему уместен.

    POINTER в Fortran и указатель на C не совсем то же самое, особенно если указатель Fortran относится к массиву . Реализация указателя на массив в Fortran должна хранить дополнительную информацию (границы массива или эквивалентную) за пределами, хранящейся в C-указателе (который является только адресом данных).

    (Технически, если соответствующие определения фиктивных аргументов для METIS_PartMeshDual не имеют необязательных или указательных атрибутов (невозможно, если это функция C, вызываемая и стандарт языка <= F2008), тогда ссылки на диссоциированные указатели в вызове в Fortran незаконно. Опять же - реализация зависит от того, что произойдет - я могу представить варианты реализации, где она будет работать, и где это не будет.)

    Обратите внимание, что в сообщении, которое вы связали с объявлениями указателей нhive, было изменено с массивов на скаляры как часть решения (первый ответ в списке – проверка времени сообщений). В примере кода, размещенном как часть вопроса, объявления для «нулевых» вещей все еще показывают массивы. Я подозреваю, что изменение в объявлении изменяет «настройку» для вызова C api и / или то, что выглядит разобщенный указатель для вашего компилятора.

    В эти дни, вызывая C API из Fortran, я предпочитаю (где это возможно) писать интерфейсные блоки для API C с использованием возможностей взаимодействия C Fortran 2003 (BIND (C) и друзей). Это гораздо более надежное решение и позволяет избежать такого рода проблем, связанных с платформой. Это требует, чтобы однократная предварительная работа, а также компилятор Fortran, который поддерживает этот аспект F2003. Поставщики библиотек, которые идут на проблемы с предоставлением таких интерфейсных блоков для своих пользователей Fortran, получают от меня большой тик и много добрых мыслей.

    Размеры массива Fortran более гибкие, чем C. Вы можете создавать массивы Fortran с 0-индексацией или любой желаемый начальный индекс.

     real, dimension (0:N-1) :: array real, dimension (:), allocatable :: group allocate (group (0:N-1)) 

    Если что-то не согласуется с начальным индексом, проблема, возможно, это поможет.