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.
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.