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

前端 未结 2 2015
甜味超标
甜味超标 2020-12-12 02:12

Over 2 weeks, I\'ve struggled to call one of the METIS library written in C from my fortran code. And, unfortunately, It doesn\'t seem to be a HAPPY END without your help. I

2条回答
  •  旧时难觅i
    2020-12-12 02:21

    I think your opts(7) does not work because you also need an interface for the METIS function METIS_SetDefaultOptions. Based on the answer from http://glaros.dtc.umn.edu/gkhome/node/877, I created a wrapper module (metisInterface.F90) with the interfaces I needed:

    module metisInterface
    ! module to allows us to call METIS C functions from the main Fortran code
    
       use,intrinsic :: ISO_C_BINDING
    
       integer :: ia,ic
       integer(C_INT) :: metis_ne,metis_nn
       integer(C_INT) :: ncommon,objval
       integer(C_INT) :: nparts
       integer(C_INT),allocatable,dimension(:) :: eptr,eind,perm,iperm
       integer(C_INT),allocatable,dimension(:) :: epart,npart
       type(C_PTR) :: vwgt,vsize,twgts,tpwgts
       integer(C_INT) :: opts(0:40)
    
    
       interface
          integer(C_INT) function METIS_SetDefaultOptions(opts) bind(C,name="METIS_SetDefaultOptions")
             use,intrinsic :: ISO_C_BINDING
             implicit none
             integer(C_INT) :: opts(0:40)
          end function METIS_SetDefaultOptions
       end interface 
    
       interface
          integer(C_INT) function METIS_PartMeshDual(ne,nn,eptr,eind,vwgt,vsize,ncommon,nparts,tpwgts, &
                                  opts,objval,epart,npart) bind(C,name="METIS_PartMeshDual")
             use,intrinsic :: ISO_C_BINDING
             implicit none
             integer(C_INT):: ne, nn
             integer(C_INT):: ncommon, objval
             integer(C_INT):: nparts
             integer(C_INT),dimension(*) :: eptr, eind
             integer(C_INT),dimension(*) :: epart, npart
             type(C_PTR),value :: vwgt, vsize, tpwgts
             integer(C_INT) :: opts(0:40)
          end function METIS_PartMeshDual
       end interface    
    
    end module metisInterface
    

    Then, in the main program (or wherever you make the call to the METIS functions) you need to have (for completeness, I also added the call to METIS_PartMeshDual):

    use metisInterface
    
    integer :: metis_call_status
    .
    .
    .
    metis_call_status = METIS_SetDefaultOptions(opts)
    
    ! METIS_OPTION_NUMBERING for Fortran
    opts(17) = 1
    
    metis_call_status = METIS_PartMeshDual(metis_ne,metis_nn,eptr,eind, &
                        vwgt,vsize,ncommon,nparts,tpwgts,opts,objval,epart,npart)
    

    Note that epart and npart will have Fortran numbering as you want (starting at 1). However, the processors will also start numbering at 1. For example, if you are running in 4 processors, root processor is 1 and you may have epart(n)=4, and you will not have any epart(n)=0.

    Finally, a file metis.c is also needed with a single line:

    #include "metis.h"
    

    Compiling instructions

    1. Compile metis.c with a C compiler
    2. Compile metisInterface.F90 with a Fortran compiler linking with the compiled C object
    3. Compile main program with a Fortran compiler linking with metisInterface.o

提交回复
热议问题