METIS seg faults when run from Fortran

牧云@^-^@ 提交于 2019-12-02 05:43:52

问题


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.


回答1:


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.




回答2:


There might be nothing to this, but perhaps the linked post in the second paragraph of the question is still pertinent.

A POINTER in Fortran and a pointer in C are not quite the same concept, particularly if the Fortran pointer is to an array. The implementation of a pointer to an array in Fortran needs to store additional information (array bounds or equivalent) beyond that stored in a C pointer (which is just the address of the data).

(Technically, unless the relevant dummy argument definitions for METIS_PartMeshDual have the optional or pointer attributes (impossible if it is a C function being called and the language standard is <= F2008) then the references to the dissociated pointers in the call in the Fortran is illegal. Again - implementation dependent as to what will happen - I can imagine implementation options where it will work and where it will not.)

Note that in the post that you linked to the declarations of the null pointers changed from being arrays to scalars as part of the solution (the first reply in the list - check the timing of the posts). In the example code posted as part of the question the declarations for the "null" things still show arrays. I suspect that change in declaration changes the "set-up" for the call to the C api and/or what a dissociated pointer looks like for your compiler.

These days, when calling C API's from Fortran I prefer (where possible) to write interface blocks for the C API using Fortran 2003's C interoperability features (BIND(C) and friends). This is much more robust and avoids this sort of platform dependent issue. It does require that once-off upfront work and also a Fortran compiler that supports this aspect of F2003. Library vendors that go to the trouble of providing such interface blocks for their Fortran users get a big tick and lots of kind thoughts from me.




回答3:


Fortran array sizes are more flexible than C. You can make Fortran arrays 0-indexed, or any starting index you want.

real, dimension (0:N-1) :: array
real, dimension (:), allocatable :: group
allocate (group (0:N-1))

If somehow disagreement about the starting index is the problem perhaps this will help.



来源:https://stackoverflow.com/questions/14078401/metis-seg-faults-when-run-from-fortran

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!