Вызов METIS API (написанный на языке C) в программе на фортране

За 2 недели ямы изо всех сил пытались позвонить одному изMETIS библиотека написана на C из моего кода на Фортране. И, к сожалению, это неКажется, что СЧАСТЛИВЫЙ КОНЕЦ без вашей помощи. Я нашел несколько постов опрямой вызов а такжеиспользуя интерфейс, Я предпочитаю последнее, потому что я мог контролировать переменные для отладки. Я прикрепил три кода.



1. С функция I 'хотел бы использовать

2. интерфейсный модуль Fortran

3. фортран программа

(1) функция c

int METIS_PartMeshNodal(idx_t *ne, idx_t *nn, idx_t *eptr, idx_t *eind, 
      idx_t *vwgt, idx_t *vsize, idx_t *nparts, real_t *tpwgts, 
      idx_t *options, idx_t *objval, idx_t *epart, idx_t *npart)

Я удалил тело cc funciton. Это'нет необходимости понимать мою проблему

Вот,idx_t целое число иreal_t одинарной или двойной точности. ОтНебраска вопции входные и последние три аргумента выводятся. А такжеvwgt,VSIZE,tpwgts а такжеопции может получить нулевое значение в качестве входных данных для настройки по умолчанию. Я написал интерфейсный модуль для использования функции c, как это

(2) интерфейсный модуль Fortran

Исправлена!Вставитьиспользовать iso_c_bind подиспользовать константыиспользованиецелое число (c_int) вместоцелое число запе,пп и другие переменные.Удалить неиспользуемый модульконстанты.

module Calling_METIS

  !use constants,  only : p2 !this is for double precision
  use iso_c_bind            !inserted later

  implicit none

  !integer                                    :: ne, nn              !modified
  integer(c_int)                              :: ne, nn 
  !integer,  dimension(:), allocatable        :: eptr, eind          !modified
  integer(c_int),  dimension(:), allocatable  :: eptr, eind
  !integer,  dimension(:), allocatable        :: vwgt, vsize         !modified
  type(c_ptr)                                 :: vwgt, vsize         
  !integer                                    :: nparts              !modified
  integer(c_int)                              :: nparts
  !real(p2), dimension(:), allocatable        :: tpwgts              !modified 
  type(c_ptr)                                 :: tpwgts      
  !integer,  dimension(0:39)                  :: opts                !modified
  integer(c_int),  dimension(0:39)            :: opts        
  !integer                                    :: objval              !modified
  integer(c_int)                              :: objval
  !integer,  dimension(:), allocatable        :: epart, npart        !modified 
  integer(c_int),  dimension(:), allocatable  :: epart, npart 

  interface
    subroutine METIS_PartMeshNodal( ne, nn, eptr, eind, vwgt, vsize, nparts, tpwgt, &
                                    opts, objval, epart, npart) bind(c)
      use intrinsic        :: iso_c_binding
      !use constants,  only  : p2

      implicit none

      integer (c_int),                  intent(in)  :: ne, nn
      integer (c_int), dimension(*),    intent(in)  :: eptr, eind
      !integer (c_int), dimension(*),    intent(in) :: vwgt, vsize  !modified
      type(c_ptr),                          value   :: vwgt, vsize   
      integer (c_int),                  intent(in)  :: nparts
      !real(c_double),  dimension(*),    intent(in) :: tpwgt        !modified
      type(c_ptr),                          value   :: tpwgt
      integer (c_int), dimension(0:39), intent(in)  :: opts
      integer (c_int),                  intent(out) :: objval
      integer (c_int), dimension(*),    intent(out) :: epart
      integer (c_int), dimension(*),    intent(out) :: npart

    end subroutine METIS_PartMeshNodal  
  end interface
end module

А вот мой программный код, вызывающий функцию

(3) программа Фортран

Исправлена!размер распределенияNpart фиксированный. НеНебраска ппopts (7) = 1 добавлен для получения массива в стиле фортрана из epart, npart (до сих пор не работал).

program METIS_call_test

 !some 'use' statments
 use Calling_METIS
 use iso_c_binging         !added

 implicit none

 ! Local variable
 integer         :: iC
 character(80)   :: grid_file !grid_file

 grid_file = 'test.grid'

 ! (1) Read grid files
 call read_grid(grid_file)

 ! (2) Construction Input Data for calling METIS Function
 ! # of cells, vertices
 ne = ncells
 nn = nvtxs

 ! eptr, eind allocation 
 allocate(eptr(0:ne), eind(0:3*ntria + 4*nquad - 1))

 ! eptr and eind building
 eptr(0) = 0
 do iC=1, ncells
   eptr(iC) = eptr(iC-1) + cell(iC)%nvtxs
   eind(eptr(iC-1):eptr(iC)-1) = cell(iC)%vtx
 end do

 ! epart, npart building
 !allocate(epart(ne), npart(ne))
 allocate(epart(ne), npart(nn))   ! modified

 ! # of partition setting
 nparts = 2
 vwgt   = c_null_ptr    !added
 vsize  = c_null_ptr    !added
 tpwgt  = c_null_ptr    !added     

 ! (3) Call METIS_PartMeshNodal
 call METIS_SetDefaultOptions(opts)

 opts(7) = 1                      !Added. For fortran style output array epart, npart. 

 call METIS_PartMeshNodal(ne, nn, eptr, eind, vwgt, vsize, nparts, tpwgt, &
                           opts, objval, epart, npart)
 !call METIS_PartMeshNodal(ne, nn, eptr, eind, null(), null(), nparts, null(), &
 !                         opts, objval, epart, npart)         !wrong...

end program

Но проблема в том, что я получаю сообщение об ошибке, как показано ниже, хотя я ставлю ноль для tpwgt.

Ошибка ввода: неверная сумма 0,000000 для tpwgts для ограничения 0.

И это сообщение обрабатывается в коде ниже.

for (i=0; incon; i++) {
    sum = rsum(ctrl->nparts, ctrl->tpwgts+i, ctrl->ncon);
    if (sum < 0.99 || sum > 1.01) {
      IFSET(dbglvl, METIS_DBG_INFO, 
          printf("Input Error: Incorrect sum of %"PRREAL" for 
                  tpwgts for constraint %"PRIDX".\n", sum, i));
      return 0;
    }
  }

Во всяком случае, чтобы увидеть, что я получу, если я положу массив для tpwgts intead из NULL,tpwgts (:) = 1.0 / nparts, что делает сумму tpwgts равной 1,0. Но я получил то же сообщение с1,75 на сумму.

Это мои вопросы

1. Я правильно использовал null () для передачи аргументов?

2. Должен ли я передавать указатели для всех аргументов в функцию c? тогда как?

3. Достаточно ли для использования ввода целого числа в opts (0:39)? Например, всообщение безинтерфейсный модуль, используется простой код, например options (3) = 1. Но в коде c параметры имеют 16 именованных переменных, таких как options [METIS_OPTION_NUMBERING], options [METIS_OPTION_UFACTOR]. Я думаю, что некоторые вещи необходимы для установки параметров, но я понятия не имею. 4. Есть ли пример для METIS в фортране?

Любой намек / совет будет большой помощью для меня. Спасибо.

Conclution

У меня была проблемас функция не моглане признать ноль указатель из кода Фортрана.

Были некоторые пропущенные переменные в интерфейсном модуле (см. 'Исправлена' и комментарии)

Похоже, код работает правильно. Ноопция (7) = 1 для вывода в стиле фортран не сделалне работает, и теперь яЯ смотрю на это.

Ответы на вопрос(2)

Ваш ответ на вопрос