Actual source code: metis.c
1: #include <../src/mat/impls/adj/mpi/mpiadj.h>
3: #include <metis.h>
5: #define PetscCallMETIS(n, func) \
6: do { \
7: PetscCheck(n != METIS_ERROR_INPUT, PETSC_COMM_SELF, PETSC_ERR_LIB, "METIS error due to wrong inputs and/or options for %s", func); \
8: PetscCheck(n != METIS_ERROR_MEMORY, PETSC_COMM_SELF, PETSC_ERR_LIB, "METIS error due to insufficient memory in %s", func); \
9: PetscCheck(n != METIS_ERROR, PETSC_COMM_SELF, PETSC_ERR_LIB, "METIS general error in %s", func); \
10: } while (0)
12: #define PetscCallMetis_(name, func, args) \
13: do { \
14: PetscStackPushExternal(name); \
15: int status = func args; \
16: PetscStackPop; \
17: PetscCallMETIS(status, name); \
18: } while (0)
20: #define PetscCallMetis(func, args) PetscCallMetis_(PetscStringize(func), func, args)
22: PETSC_EXTERN PetscErrorCode MatMeshToCellGraph_Metis(Mat mesh, PetscInt ncommonnodes, Mat *dual)
23: {
24: PetscInt *newxadj, *newadjncy;
25: PetscInt numflag = 0;
26: Mat_MPIAdj *adj = (Mat_MPIAdj *)mesh->data, *newadj;
27: PetscBool flg;
28: MPI_Comm comm;
29: PetscMPIInt size;
31: PetscFunctionBegin;
32: PetscCall(PetscObjectTypeCompare((PetscObject)mesh, MATMPIADJ, &flg));
33: PetscCall(PetscObjectGetComm((PetscObject)mesh, &comm));
34: PetscCheck(flg, comm, PETSC_ERR_SUP, "Must use MPIAdj matrix type");
36: PetscCallMPI(MPI_Comm_size(comm, &size));
37: PetscCheck(size == 1, comm, PETSC_ERR_SUP, "MatMeshToCellGraph_Metis() requires a sequential matrix (communicator size must be 1)");
39: {
40: idx_t ne = mesh->rmap->N;
41: idx_t nn = mesh->cmap->N;
43: PetscCallMetis(METIS_MeshToDual, (&ne, &nn, (idx_t *)adj->i, (idx_t *)adj->j, (idx_t *)&ncommonnodes, (idx_t *)&numflag, (idx_t **)&newxadj, (idx_t **)&newadjncy));
44: }
46: for (PetscInt i = 0; i < mesh->rmap->N; i++) PetscCall(PetscSortInt(newxadj[i + 1] - newxadj[i], newadjncy + newxadj[i]));
48: PetscCall(MatCreateMPIAdj(PetscObjectComm((PetscObject)mesh), mesh->rmap->n, mesh->rmap->N, newxadj, newadjncy, NULL, dual));
49: newadj = (Mat_MPIAdj *)(*dual)->data;
51: newadj->freeaijwithfree = PETSC_TRUE; /* signal the matrix should be freed with system free since space was allocated by METIS */
52: PetscFunctionReturn(PETSC_SUCCESS);
53: }