xref: /petsc/src/mat/tests/ex152.c (revision 586b08f30011f7ed16b96bd03e7bf3dc3615a7bd)
1c4762a1bSJed Brown static const char help[] = "Test ParMETIS handling of negative weights.\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown /* Test contributed by John Fettig */
4c4762a1bSJed Brown 
5c4762a1bSJed Brown /*
61d27aa22SBarry Smith   Implements two tests for a bug reported in ParMETIS. These tests are not expected to pass without the
71d27aa22SBarry Smith   patches in the PETSc distribution of ParMetis. See parmetis.py
81d27aa22SBarry Smith 
91d27aa22SBarry Smith  The bug was reported upstream, but has received no action so far.
101d27aa22SBarry Smith 
111d27aa22SBarry Smith  http://glaros.dtc.umn.edu/gkhome/node/837
12c4762a1bSJed Brown */
13c4762a1bSJed Brown 
14c4762a1bSJed Brown #include <petscsys.h>
15c4762a1bSJed Brown #include <parmetis.h>
16c4762a1bSJed Brown 
179371c9d4SSatish Balay #define PetscCallPARMETIS(...) \
189371c9d4SSatish Balay   do { \
195f80ce2aSJacob Faibussowitsch     int metis_ierr = __VA_ARGS__; \
205f80ce2aSJacob Faibussowitsch     PetscCheck(metis_ierr != METIS_ERROR_INPUT, PETSC_COMM_SELF, PETSC_ERR_LIB, "ParMETIS error due to wrong inputs and/or options"); \
215f80ce2aSJacob Faibussowitsch     PetscCheck(metis_ierr != METIS_ERROR_MEMORY, PETSC_COMM_SELF, PETSC_ERR_LIB, "ParMETIS error due to insufficient memory"); \
225f80ce2aSJacob Faibussowitsch     PetscCheck(metis_ierr != METIS_ERROR, PETSC_COMM_SELF, PETSC_ERR_LIB, "ParMETIS general error"); \
235f80ce2aSJacob Faibussowitsch   } while (0)
24c4762a1bSJed Brown 
main(int argc,char * argv[])25d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
26d71ae5a4SJacob Faibussowitsch {
27c4762a1bSJed Brown   PetscBool   flg;
28c4762a1bSJed Brown   PetscMPIInt rank, size;
29c4762a1bSJed Brown   idx_t       ni, isize, *vtxdist, *xadj, *adjncy, *vwgt, *part;
30c4762a1bSJed Brown   idx_t       wgtflag = 0, numflag = 0, ncon = 1, ndims = 3, edgecut = 0;
31c4762a1bSJed Brown   idx_t       options[5];
32c4762a1bSJed Brown   PetscReal  *xyz;
33c4762a1bSJed Brown   real_t     *sxyz, *tpwgts, ubvec[1];
34c4762a1bSJed Brown   MPI_Comm    comm;
35c4762a1bSJed Brown   FILE       *fp;
36c4762a1bSJed Brown   char        fname[PETSC_MAX_PATH_LEN], prefix[PETSC_MAX_PATH_LEN] = "";
37c4762a1bSJed Brown   size_t      red;
38c4762a1bSJed Brown 
39327415f7SBarry Smith   PetscFunctionBeginUser;
409566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
41c4762a1bSJed Brown #if defined(PETSC_USE_64BIT_INDICES)
427de69702SBarry Smith   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "This example only works with 32-bit indices\n"));
439566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
44b122ec5aSJacob Faibussowitsch   return 0;
45c4762a1bSJed Brown #endif
46*458b0db5SMartin Diehl   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
47*458b0db5SMartin Diehl   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
48c4762a1bSJed Brown 
49d0609cedSBarry Smith   PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "Parmetis test options", "");
509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-prefix", "Path and prefix of test file", "", prefix, prefix, sizeof(prefix), &flg));
5128b400f6SJacob Faibussowitsch   PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_USER, "Must specify -prefix");
52d0609cedSBarry Smith   PetscOptionsEnd();
53c4762a1bSJed Brown 
549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(size + 1, &vtxdist));
55c4762a1bSJed Brown 
569566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(fname, sizeof(fname), "%s.%d.graph", prefix, rank));
57c4762a1bSJed Brown 
589566063dSJacob Faibussowitsch   PetscCall(PetscFOpen(PETSC_COMM_SELF, fname, "r", &fp));
59c4762a1bSJed Brown 
609371c9d4SSatish Balay   red = fread(vtxdist, sizeof(idx_t), size + 1, fp);
619371c9d4SSatish Balay   PetscCheck(red == (size_t)(size + 1), PETSC_COMM_SELF, PETSC_ERR_SYS, "Unable to read from data file");
62c4762a1bSJed Brown 
63c4762a1bSJed Brown   ni = vtxdist[rank + 1] - vtxdist[rank];
64c4762a1bSJed Brown 
659566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ni + 1, &xadj));
66c4762a1bSJed Brown 
679371c9d4SSatish Balay   red = fread(xadj, sizeof(idx_t), ni + 1, fp);
689371c9d4SSatish Balay   PetscCheck(red == (size_t)(ni + 1), PETSC_COMM_SELF, PETSC_ERR_SYS, "Unable to read from data file");
69c4762a1bSJed Brown 
709566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(xadj[ni], &adjncy));
71c4762a1bSJed Brown 
725f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < ni; i++) {
739371c9d4SSatish Balay     red = fread(&adjncy[xadj[i]], sizeof(idx_t), xadj[i + 1] - xadj[i], fp);
749371c9d4SSatish Balay     PetscCheck(red == (size_t)(xadj[i + 1] - xadj[i]), PETSC_COMM_SELF, PETSC_ERR_SYS, "Unable to read from data file");
75c4762a1bSJed Brown   }
76c4762a1bSJed Brown 
779566063dSJacob Faibussowitsch   PetscCall(PetscFClose(PETSC_COMM_SELF, fp));
78c4762a1bSJed Brown 
799566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(fname, sizeof(fname), "%s.%d.graph.xyz", prefix, rank));
809566063dSJacob Faibussowitsch   PetscCall(PetscFOpen(PETSC_COMM_SELF, fname, "r", &fp));
81c4762a1bSJed Brown 
829566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(ni * ndims, &xyz, ni, &part, size, &tpwgts));
839566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ni * ndims, &sxyz));
84c4762a1bSJed Brown 
859371c9d4SSatish Balay   red = fread(xyz, sizeof(PetscReal), ndims * ni, fp);
869371c9d4SSatish Balay   PetscCheck(red == (size_t)(ndims * ni), PETSC_COMM_SELF, PETSC_ERR_SYS, "Unable to read from data file");
87810441c8SPierre Jolivet   for (PetscInt i = 0; i < ni * ndims; i++) sxyz[i] = (real_t)xyz[i];
88c4762a1bSJed Brown 
899566063dSJacob Faibussowitsch   PetscCall(PetscFClose(PETSC_COMM_SELF, fp));
90c4762a1bSJed Brown 
91c4762a1bSJed Brown   vwgt = NULL;
92c4762a1bSJed Brown 
936497c311SBarry Smith   for (PetscInt i = 0; i < size; i++) tpwgts[i] = (real_t)(1. / size);
94c4762a1bSJed Brown   isize = size;
95c4762a1bSJed Brown 
966497c311SBarry Smith   ubvec[0]   = (real_t)1.05;
97c4762a1bSJed Brown   options[0] = 0;
98c4762a1bSJed Brown   options[1] = 2;
99c4762a1bSJed Brown   options[2] = 15;
100c4762a1bSJed Brown   options[3] = 0;
101c4762a1bSJed Brown   options[4] = 0;
102c4762a1bSJed Brown 
1039566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_dup(MPI_COMM_WORLD, &comm));
1049566063dSJacob Faibussowitsch   PetscCallPARMETIS(ParMETIS_V3_PartGeomKway(vtxdist, xadj, adjncy, vwgt, NULL, &wgtflag, &numflag, &ndims, sxyz, &ncon, &isize, tpwgts, ubvec, options, &edgecut, part, &comm));
1059566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_free(&comm));
106c4762a1bSJed Brown 
1079566063dSJacob Faibussowitsch   PetscCall(PetscFree(vtxdist));
1089566063dSJacob Faibussowitsch   PetscCall(PetscFree(xadj));
1099566063dSJacob Faibussowitsch   PetscCall(PetscFree(adjncy));
1109566063dSJacob Faibussowitsch   PetscCall(PetscFree3(xyz, part, tpwgts));
1119566063dSJacob Faibussowitsch   PetscCall(PetscFree(sxyz));
1129566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
113b122ec5aSJacob Faibussowitsch   return 0;
114c4762a1bSJed Brown }
115c4762a1bSJed Brown 
116c4762a1bSJed Brown /*TEST
117c4762a1bSJed Brown 
118c4762a1bSJed Brown    build:
119c4762a1bSJed Brown       requires: parmetis
120c4762a1bSJed Brown 
121c4762a1bSJed Brown    test:
122c4762a1bSJed Brown       nsize: 2
123dfd57a17SPierre Jolivet       requires: parmetis datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
124c4762a1bSJed Brown       args: -prefix ${DATAFILESPATH}/parmetis-test/testnp2
1253886731fSPierre Jolivet       output_file: output/empty.out
126c4762a1bSJed Brown 
127c4762a1bSJed Brown    test:
128c4762a1bSJed Brown       suffix: 2
129c4762a1bSJed Brown       nsize: 4
130dfd57a17SPierre Jolivet       requires: parmetis datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
131c4762a1bSJed Brown       args: -prefix ${DATAFILESPATH}/parmetis-test/testnp4
1323886731fSPierre Jolivet       output_file: output/empty.out
133c4762a1bSJed Brown 
134c4762a1bSJed Brown TEST*/
135