1

I'm trying to partition a mesh using METIS through Fortran, I built the lib file using Visual Studio 10.0 X64 on an X64 Windows 7 system, my program is as the following:

module metis_vars

     use iso_c_binding

    ! Variables
    integer                                        :: ia, ic
    integer(kind=c_int)                            :: ne, nn
    integer(kind=c_int)                            :: ncommon, objval
    integer(kind=c_int)                            :: nparts
    integer(kind=c_int), allocatable, dimension(:) :: eptr, eind
    integer(kind=c_int), allocatable, dimension(:) :: epart, npart
    type(c_ptr)                                    :: vwgt, vsize, tpwgts  
    integer                                        :: opts(0:40)

    interface

        subroutine METIS_PartMeshDual(ne,nn,eptr,eind,vwgt,vsize,ncommon,nparts,tpwgts,opts,objval,epart,npart) bind(C, name="METIS_PartMeshDual")

            ! use binding module
            use iso_c_binding
            ! declare variables with C++ types semantics
            integer(kind=c_int)               :: ne, nn, ncommon, objval
            integer(kind=c_int), dimension(*) :: eptr, eind
            integer(kind=c_int), dimension(*) :: epart, npart
            type(c_ptr), value                :: vwgt, vsize, tpwgts 
            integer(kind=c_int)               :: opts(0:40)

        end subroutine METIS_PartMeshDual

    end interface

end module

program METIS_PART_1

    use iso_c_binding
    use metis_vars

    implicit none

    open(unit=1, file='metis_test.mesh')

    read(1,*), ne

    nn = ne * 8

    allocate( eptr(ne), eind(8*ne) )
    allocate( epart(ne), npart(nn) )

    do ic=1,ne

        ia = (ic-1) * 8 + 1

        read(1,*), eind(ia:ia+7)

        eptr(ic) = ia

    enddo

    nparts = 4
    ncommon = 2

    vwgt   = c_null_ptr
    vsize  = c_null_ptr
    tpwgts = c_null_ptr
    opts(0)   = 1
    opts(7)   = 1

    call METIS_PartMeshDual(ne,nn,eptr,eind,vwgt,vsize,ncommon,nparts,tpwgts,opts,objval,epart,npart)

end program METIS_PART_1

I revised all the input arrays and they're correct (I already partitioned this mesh using the EXE's successfully), however, when I use the API, I get the following error:

Current memory used: zu bytes Maximum memory used: zu bytes ***Memory allocation failed for CreateGraphDual: nind. Requested size: zu bytes

I have no clue what's wrong or how to debug it

Alphajet
  • 53
  • 1
  • 7
  • 1
    Well, if you suspect a failure of memory allocation I suggest that you check the status returned by each of the `allocate` statements. Consider the optional argument `stat`. – High Performance Mark Jun 17 '13 at 21:50
  • You can also step by the code using any debugger and identify the line that cause the error. – Vladimir F Героям слава Jun 18 '13 at 08:03
  • @HighPerformanceMark, the documentation includes no such thing as "stat" optional argument, there's an option array argument called options[METIS_OPTION_DBGLVL] – Alphajet Jun 18 '13 at 13:38
  • `stat` is an optional argument for the Fortran `allocate` statement. I suspect that METIS (I have no clue what that is or what it does) allocates memory during execution; the error message you report is consistent with memory allocation failing. If you can't edit the source code and re-compile, I suggest you ask this question of whoever supplied the code. – High Performance Mark Jun 18 '13 at 13:45
  • @HighPerformanceMark, aha ! now I get you, actually the allocation process is a part of METIS itself for allocating its own variables – Alphajet Jun 18 '13 at 13:59

2 Answers2

1

I finally came to find out that allocation size of eptr was (nc), but it should be (nc+1), which is the number of elements+1

Alphajet
  • 53
  • 1
  • 7
0

A quick grep through Metis's source files (version 5.1.0) reveals the problem:

    void CreateGraphDual(idx_t ne, idx_t nn, idx_t *eptr, idx_t *eind, idx_t ncommon, 
              idx_t **r_xadj, idx_t **r_adjncy)
    {
      ...
      idx_t *nptr, *nind;
      ...

      /* construct the node-element list first */
      nptr = ismalloc(nn+1, 0, "CreateGraphDual: nptr");
      nind = imalloc(eptr[ne], "CreateGraphDual: nind");
      ...

suggesting that there may be something wrong with the eptr array (as you had already figured out).

knia
  • 463
  • 6
  • 16