Package: mgmetis
Introductionmgmetisis a mesh and graph Partitioning suite wrapped on top ofMETIS & ParMETIS. It targets
at intermediate level of package developers who work in, e.g., finite element
libraries.mgmetisprovides all functionalities from original METIS/ParMETIS via 1) aCythoninterface and 2) a native Python interface
throughctypes.Installationmgmetiscan be installed viapip, i.e.,$pip3installmgmetis--userIf you have MPI andmpi4pyinstalled, then the parallel components will be built automatically. Note that
mpi4py isNOTan installation dependency.ExamplesIt’s worth noting thatmgmetissimply wraps around original METIS interfaces.mgmetisdoesn’t have complicated data structures for graphs and meshes,
everything is passed in as arrays as per CSR format. The variable names are
preserved as what they are in the original documentation. For more information,
please refer tohttp://glaros.dtc.umn.edu/gkhome/metis/metis/downloadandhttp://glaros.dtc.umn.edu/gkhome/metis/parmetis/downloadfor METIS and ParMETIS
original documentation PDF files, respectively.Python ModeFor graph Partitioning, eithermultilevel recursive bisectionormultilevel k-way partitioningmethods, the interfaces are exactly the same.
The mandatory parameters arenparts(number of partitions),xadj(the
starting positions of adjacent list) andadjncy(the compressed adjacent
list).Give a a directed graph based on the following structure:0---1---2
|   |   |
3---4---5
|   |   |
6---7---8We can have the set up a simple graph representation, which looks like>>>graph={...0:[1,3],...1:[0,2,4],...2:[1,5],...3:[0,4,6],...4:[1,3,5,7],...5:[2,4,8],...6:[3,7],...7:[4,6,8],...8:[5,7],...}We can then convert it into CSR graph>>>xadj=[0]>>>foredgesingraph.values():...xadj.append(xadj[-1]+len(edges))...>>>xadj[0,2,5,7,10,14,17,19,22,24]>>>adjncy=[nodeforedgesingraph.values()fornodeinedges]Then a partition of 2 with recursive algorithm can be simply done via>>>frommgmetisimportmetis>>>objval,part=metis.part_graph_recursive(2,xadj,adjncy)>>>partarray([0,0,1,0,0,1,1,1,1])Notice that the structure in this example can also be viewed as a mesh with 12
bar cells, of which the user may want to determine a element-wise partition.cells=[...[0,1],...[1,2],...[3,4],...[4,5],...[6,7],...[7,8],...[0,3],...[1,4],...[2,5],...[3,6],...[4,7],...[5,8],...]Then, partitoning the mesh into 2 components can be done viapart_mesh_dual>>>objval,epart,npart=metis.part_mesh_dual(2,cells)>>>epartarray([0,0,0,1,1,1,0,0,1,0,1,1])For other supported advanced features, such as weights, please consult the
METIS documentation. All the arguments are supported via keyword inputs. Here,
we further demonstrate how to customize options, a.k.a. control parameters, in
METIS. The parameters in metis are specified via a fixed length 40 integer
array.>>>opts=metis.get_default_options()>>>optsOptions([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],dtype=int32)If you are familiar with METIS, you can directly work with the parameters.mgmetisimplements a helper modulemgmetis.enumsto help the user work
with control parameters. Let’s say the user has a Fortran-based index graph>>>frommgmetis.enumsimportOPTION>>>opts[OPTION.NUMBERING]=1>>>xadj=[x+1forxinxadj]>>>adjncy=[x+1forxinadjncy]>>>objval,part=metis.part_graph_recursive(2,xadj,adjncy,options=opts)>>>partarray([1,1,2,1,1,2,2,2,2])Notemgmetiscan automatically handle Fortran index.ctypesModeA powerful feature ofmgmetisis that it allows the user to directly work
with the underlying C functions throughctypes. However, by dealing with
foreign C interfaces, the user needs to explicitly ensure the type consistency.mgmetissupports both 32-bit and 64-bit integer builds of METIS. The original
METIS functions all have prefixMETIS_, whereas inmgmetisctypesmodule, the prefix is trimmed out. Let’s see the following example to see how
to use thectypesinterface.>>>importnumpyasnp>>>xadj=np.asarray(xadj)# from list of ints, the dtype is int64>>>adjncy=np.asarray(adjncy)>>>part=np.empty(xadj.size-1,dtype=int)# output>>>opts=np.assarray(opts,dtype=int)Recall that the graph partitioning routine takes all arguments as their
references. This can be done viactypes>>>importctypesasc>>>nv=c.c_int64(part.size)>>>ncon=c.c_int64(1)>>>objval=c.c_int64(0)# output>>>nparts=c.c_int64(2)>>>xadj_ptr=xadj.ctypes.data_as(c.POINTER(c.c_int64))>>>adj_ptr=adjncy.ctypes.data_as(c.POINTER(c.c_ind64))>>>opts_ptr=opts.ctypes.data_as(c.POINTER(c.c_int64))>>>part_ptr=part.ctypes.data_as(c.POINTER(c.c_int64))# output addressWe now need to access the ctype interface inmgmetis>>>frommgmetis.metisimportlibmetis64# libmetis for 32bit int>>>libmetis64.PartGraphRecursive(...c.byref(nv),...c.byref(ncon),...xadj_ptr,...adj_ptr,...None,# NULL...None,...None,...c.byref(nparts),...None,...None,...opts_ptr,...c.byref(objval),...part_ptr,...)For more details forctypes, please refer tohttps://docs.python.org/3.8/library/ctypes.html.
Also, take a look atnp.ndarray.ctypes.Enable METIS in CythonEach of the METIS routine has a Cython interface, whose naming convention is
samilar as it’s inctypesmode.mgmetisresolves the issues regarding
linking to METIS. In addition, each of the Cython function is defined withnogilspecifier.The following code shows how to access theMETIS_PartGraphRecursivecimportmgmetis.libmetisasmetis# 32 bit# then each of the function in METIS public domain has a Cython interface# without prefix METIS_cdefintret=metis.PartGraphRecursive(...)ifret!=metis.OK:raiseValueErrorWhen you compile your Cython code, you don’t need to worry about linking to
METIS, Python will load the correct symbol in runtime.Work with MPIThe native Python mode supports parallel partitioning of a static graph or
mesh. The underlying routines are:ParMETIS_V3_PartKway,ParMETIS_V3_PartGeomKway,ParMETIS_V3_PartGeom, andParMETIS_V3_PartMeshKway.Their usage is similar to the serial version, please take a look at the unit
testing scripts.A complete support of ParMETIS can be done (for now) via eitherctypesmode or Cython mode. Forctypesmodefrommgmetis.parmetisimportlibparmetis# libparmetis64 for 64bithelp(libparmetis)and for the Cython modecimportmgmetis.parmetisasparmetis# mgmetis.parmetis64 for 64 bitcdefintret=parmetis.PartKway(...)Notice that for Cython mode, you will need to accessmpi4pyCython interface.
It will, then, require you to add its path during specifyingExtension, and
the compiler needs to be set tompicc.Licensemgmetisis considerred as a wrapper of METIS, and it is distributed under MIT
license. Users should also refer tohttp://glaros.dtc.umn.edu/gkhome/views/metisfor the licenses of METIS and ParMETIS.