Search code examples
cfortranfortran90metis

METIS seg faults when run from Fortran


I'm trying to use the METIS library for mesh partitioning as part of a Fortran program I've written for finite element computations. METIS is written in C but it's supposed to work just fine with Fortran 90. But I keep getting seg faults.

One potential hiccup is that there are a few arguments to which I'm giving null pointers. Some other folks have had trouble getting a call to a C function from fortran to recognize a null pointer object. That was addressed here and I don't think that's the issue I'm having.

I think the problem is getting METIS to change the starting array index; in C it's 0, in Fortran it's 1. There's an options array passed to every function which is supposed to have a field METIS_OPTION_NUMBERING that you change to 1 if you want the Fortran convention. Failure to do so would then cause the C programs to try and access index 0, giving you the seg fault.

The post by edunlop1 here suggests that I just make an array options and some agreed-upon convention with METIS determines which element of that array is supposed to be set to 1 for it to renumber everythin. But what that is changes depending on which routine you're using, as does the array length.

Anyhow, here's my code:

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)

The relevant code in METIS for changing the numbering is in the file libmetis/meshpart.c :

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

Any thoughts? I can post Valgrind output if that's helpful.


Solution

  • Use:

    vwgt=>null() 
    

    instead of

    vwgt(:)=>null()
    

    for all nulls (i.e., vwgt, vsize, opts, tpwgts etc.). The problem is that vwgt(:) isnt really defined as opposed to just vwgt or vwgt(1). If you still have problems then use a debugger to check all values.

    I was the OP in the thread mentioned in the 2nd para. The final solution is unfortunately at the top of the replies (see the time stamp). Hope that helps.