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