Wednesday, 15 May 2013

Calling METIS API(wrtten in C language) in fortran program -



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.

conclution

the 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