Calling METIS API(wrtten in C language) in fortran program -
over 2 weeks, i've struggled phone call 1 of metis library written in c fortran code. and, unfortunately, doesn't seem happy end without help. found posts direct calling , using interface. prefer latter because monitor variables debugging. there 3 codes attached. 1. c function i'd use 2. fortran interface module 3. fortran program
(1) c function
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)
i removed c funciton body. it's not necessary understand problem
here, idx_t integer , real_t single or double precision. ne options input , lastly 3 arguments output. , vwgt, vsize, tpwgts , options can receive null input default setting wrote interface module using c function this
(2) fortran interface module
fixed! insert use iso_c_bind under use constants use integer(c_int) instead of integer ne, nn , other variables. remove unused module constants.
module calling_metis !use constants, : p2 !this double precision utilize 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) utilize intrinsic :: iso_c_binding !use constants, : 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
and here programme code calling function
(3) fortran program
fixed! allocation size of npart fixed. not ne nn opts(7)=1 added fortran-style array of epart, npart(no effect until now).
program metis_call_test !some 'use' statments utilize calling_metis utilize iso_c_binging !added implicit none ! local variable integer :: ic character(80) :: grid_file !grid_file grid_file = 'test.grid' ! (1) read grid files phone call read_grid(grid_file) ! (2) construction input info 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 , eind building eptr(0) = 0 ic=1, ncells eptr(ic) = eptr(ic-1) + cell(ic)%nvtxs eind(eptr(ic-1):eptr(ic)-1) = cell(ic)%vtx end ! 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) phone call metis_partmeshnodal phone call metis_setdefaultoptions(opts) opts(7) = 1 !added. fortran style output array epart, npart. phone 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 programme
but problem error message below though set null tpwgt.
input error: inorrect sum of 0.000000 tpwgts constraint 0.
and message handled in code below.
for (i=0; i<ctrl->ncon; 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: wrong sum of %"prreal" tpwgts constraint %"pridx".\n", sum, i)); homecoming 0; } }
anyway, in order see if set array tpwgts intead of null, tpwgts(:) = 1.0/nparts, makes sum of tpwgts equal 1.0. got same message 1.75 sum.
these questions 1. did utilize null() passing arguments correctly? 2. have pass pointers arguments c function? how? 3. putting integer opts(0:39) plenty use? example, in post without 'interface module', simple code options(3)=1 used. in c code, options has 16 named variable options[metis_option_numbering], options[metis_option_ufactor]. think thing necessary set options have no idea. 4. there illustration metis in fortran?
any kind of hint/advice great help me. give thanks you.
conclutionthe problem had c function couldn't recognize null pointer fortran code.
there miss declations of variables in interface module(see 'fixed' , comments)
it looks code works properly. option(7) = 1 fortran style output didn't work , i'm looking @ it.
no, cannot pass null()
, fortran pointer constant. must pass c_null_ptr
module iso_c_binding
, interface must reflect this. dummy argument must type(c_ptr)
, value
attribute. may work because of same internal representation, wouldn't count on it.
no, if pass normal variable, can pass straight reference. in fortran. if interface bind(c)
, compiler knows must send pointer.
there new ts update fortran 2008, can define dummy arguments in interoperable procedures optional
. can pass null pointer omitting them. gfortran should back upwards this.
note: here can see much different c signature of function, sure yours ok? http://charm.cs.uiuc.edu/doxygen/charm/meshpart_8c.shtml
fortran fortran-iso-c-binding metis
No comments:
Post a Comment