Actual source code: chaco.c
2: #include <../src/mat/impls/adj/mpi/mpiadj.h>
4: #if defined(PETSC_HAVE_UNISTD_H)
5: #include <unistd.h>
6: #endif
8: #if defined(PETSC_HAVE_CHACO_INT_ASSIGNMENT)
9: #include <chaco.h>
10: #else
11: /* Older versions of Chaco do not have an include file */
12: PETSC_EXTERN int interface(int nvtxs, int *start, int *adjacency, int *vwgts, float *ewgts, float *x, float *y, float *z, char *outassignname, char *outfilename, short *assignment, int architecture, int ndims_tot, int mesh_dims[3], double *goal, int global_method, int local_method, int rqi_flag, int vmax, int ndims, double eigtol, long seed);
13: #endif
15: extern int FREE_GRAPH;
17: /*
18: int nvtxs; number of vertices in full graph
19: int *start; start of edge list for each vertex
20: int *adjacency; edge list data
21: int *vwgts; weights for all vertices
22: float *ewgts; weights for all edges
23: float *x, *y, *z; coordinates for inertial method
24: char *outassignname; name of assignment output file
25: char *outfilename; output file name
26: short *assignment; set number of each vtx (length n)
27: int architecture; 0 => hypercube, d => d-dimensional mesh
28: int ndims_tot; total number of cube dimensions to divide
29: int mesh_dims[3]; dimensions of mesh of processors
30: double *goal; desired set sizes for each set
31: int global_method; global partitioning algorithm
32: int local_method; local partitioning algorithm
33: int rqi_flag; should I use RQI/Symmlq eigensolver?
34: int vmax; how many vertices to coarsen down to?
35: int ndims; number of eigenvectors (2^d sets)
36: double eigtol; tolerance on eigenvectors
37: long seed; for random graph mutations
38: */
40: typedef struct {
41: PetscBool verbose;
42: PetscInt eignum;
43: PetscReal eigtol;
44: MPChacoGlobalType global_method; /* global method */
45: MPChacoLocalType local_method; /* local method */
46: MPChacoEigenType eigen_method; /* eigensolver */
47: PetscInt nbvtxcoarsed; /* number of vertices for the coarse graph */
48: } MatPartitioning_Chaco;
50: #define SIZE_LOG 10000 /* size of buffer for mesg_log */
52: static PetscErrorCode MatPartitioningApply_Chaco(MatPartitioning part, IS *partitioning)
53: {
54: int cerr;
55: PetscInt *parttab, *locals, i, nb_locals, M, N;
56: PetscMPIInt size, rank;
57: Mat mat = part->adj, matAdj, matSeq, *A;
58: Mat_MPIAdj *adj;
59: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
60: PetscBool flg;
61: IS isrow, iscol;
62: int nvtxs, *start, *adjacency, *vwgts, architecture, ndims_tot;
63: int mesh_dims[3], global_method, local_method, rqi_flag, vmax, ndims;
64: #if defined(PETSC_HAVE_CHACO_INT_ASSIGNMENT)
65: int *assignment;
66: #else
67: short *assignment;
68: #endif
69: double eigtol;
70: long seed;
71: char *mesg_log;
72: #if defined(PETSC_HAVE_UNISTD_H)
73: int fd_stdout, fd_pipe[2], count;
74: #endif
76: PetscFunctionBegin;
77: PetscCheck(!part->use_edge_weights, PetscObjectComm((PetscObject)part), PETSC_ERR_SUP, "Chaco does not support edge weights");
78: FREE_GRAPH = 0; /* otherwise Chaco will attempt to free memory for adjacency graph */
79: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size));
80: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)mat), &rank));
81: PetscCall(PetscObjectTypeCompare((PetscObject)mat, MATMPIADJ, &flg));
82: if (size > 1) {
83: if (flg) {
84: PetscCall(MatMPIAdjToSeq(mat, &matSeq));
85: } else {
86: PetscCall(PetscInfo(part, "Converting distributed matrix to sequential: this could be a performance loss\n"));
87: PetscCall(MatGetSize(mat, &M, &N));
88: PetscCall(ISCreateStride(PETSC_COMM_SELF, M, 0, 1, &isrow));
89: PetscCall(ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol));
90: PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscol, MAT_INITIAL_MATRIX, &A));
91: PetscCall(ISDestroy(&isrow));
92: PetscCall(ISDestroy(&iscol));
93: matSeq = *A;
94: PetscCall(PetscFree(A));
95: }
96: } else {
97: PetscCall(PetscObjectReference((PetscObject)mat));
98: matSeq = mat;
99: }
101: if (!flg) { /* convert regular matrix to MPIADJ */
102: PetscCall(MatConvert(matSeq, MATMPIADJ, MAT_INITIAL_MATRIX, &matAdj));
103: } else {
104: PetscCall(PetscObjectReference((PetscObject)matSeq));
105: matAdj = matSeq;
106: }
108: adj = (Mat_MPIAdj *)matAdj->data; /* finally adj contains adjacency graph */
110: /* arguments for Chaco library */
111: nvtxs = mat->rmap->N; /* number of vertices in full graph */
112: start = adj->i; /* start of edge list for each vertex */
113: vwgts = part->vertex_weights; /* weights for all vertices */
114: architecture = 1; /* 0 => hypercube, d => d-dimensional mesh */
115: ndims_tot = 0; /* total number of cube dimensions to divide */
116: mesh_dims[0] = part->n; /* dimensions of mesh of processors */
117: global_method = chaco->global_method; /* global partitioning algorithm */
118: local_method = chaco->local_method; /* local partitioning algorithm */
119: rqi_flag = chaco->eigen_method; /* should I use RQI/Symmlq eigensolver? */
120: vmax = chaco->nbvtxcoarsed; /* how many vertices to coarsen down to? */
121: ndims = chaco->eignum; /* number of eigenvectors (2^d sets) */
122: eigtol = chaco->eigtol; /* tolerance on eigenvectors */
123: seed = 123636512; /* for random graph mutations */
125: PetscCall(PetscMalloc1(mat->rmap->N, &assignment));
126: PetscCall(PetscMalloc1(start[nvtxs], &adjacency));
127: for (i = 0; i < start[nvtxs]; i++) adjacency[i] = (adj->j)[i] + 1; /* 1-based indexing */
129: /* redirect output to buffer */
130: #if defined(PETSC_HAVE_UNISTD_H)
131: fd_stdout = dup(1);
132: PetscCheck(!pipe(fd_pipe), PETSC_COMM_SELF, PETSC_ERR_SYS, "Could not open pipe");
133: close(1);
134: dup2(fd_pipe[1], 1);
135: PetscCall(PetscMalloc1(SIZE_LOG, &mesg_log));
136: #endif
138: /* library call */
139: cerr = interface(nvtxs, start, adjacency, vwgts, NULL, NULL, NULL, NULL, NULL, NULL, assignment, architecture, ndims_tot, mesh_dims, NULL, global_method, local_method, rqi_flag, vmax, ndims, eigtol, seed);
141: #if defined(PETSC_HAVE_UNISTD_H)
142: PetscCall(PetscFFlush(stdout));
143: count = read(fd_pipe[0], mesg_log, (SIZE_LOG - 1) * sizeof(char));
144: if (count < 0) count = 0;
145: mesg_log[count] = 0;
146: close(1);
147: dup2(fd_stdout, 1);
148: close(fd_stdout);
149: close(fd_pipe[0]);
150: close(fd_pipe[1]);
151: if (chaco->verbose) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "%s", mesg_log));
152: PetscCall(PetscFree(mesg_log));
153: #endif
154: PetscCheck(!cerr, PETSC_COMM_SELF, PETSC_ERR_LIB, "Chaco failed");
156: PetscCall(PetscMalloc1(mat->rmap->N, &parttab));
157: for (i = 0; i < nvtxs; i++) parttab[i] = assignment[i];
159: /* creation of the index set */
160: nb_locals = mat->rmap->n;
161: locals = parttab + mat->rmap->rstart;
162: PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)part), nb_locals, locals, PETSC_COPY_VALUES, partitioning));
164: /* clean up */
165: PetscCall(PetscFree(parttab));
166: PetscCall(PetscFree(adjacency));
167: PetscCall(PetscFree(assignment));
168: PetscCall(MatDestroy(&matSeq));
169: PetscCall(MatDestroy(&matAdj));
170: PetscFunctionReturn(PETSC_SUCCESS);
171: }
173: PetscErrorCode MatPartitioningView_Chaco(MatPartitioning part, PetscViewer viewer)
174: {
175: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
176: PetscBool isascii;
178: PetscFunctionBegin;
179: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
180: if (isascii) {
181: PetscCall(PetscViewerASCIIPrintf(viewer, " Global method: %s\n", MPChacoGlobalTypes[chaco->global_method]));
182: PetscCall(PetscViewerASCIIPrintf(viewer, " Local method: %s\n", MPChacoLocalTypes[chaco->local_method]));
183: PetscCall(PetscViewerASCIIPrintf(viewer, " Number of vertices for the coarse graph: %" PetscInt_FMT "\n", chaco->nbvtxcoarsed));
184: PetscCall(PetscViewerASCIIPrintf(viewer, " Eigensolver: %s\n", MPChacoEigenTypes[chaco->eigen_method]));
185: PetscCall(PetscViewerASCIIPrintf(viewer, " Tolerance for eigensolver: %g\n", chaco->eigtol));
186: PetscCall(PetscViewerASCIIPrintf(viewer, " Number of eigenvectors: %" PetscInt_FMT "\n", chaco->eignum));
187: }
188: PetscFunctionReturn(PETSC_SUCCESS);
189: }
191: /*@
192: MatPartitioningChacoSetGlobal - Set the global method for Chaco partitioner.
194: Collective
196: Input Parameters:
197: + part - the partitioning context
198: - method - one of `MP_CHACO_MULTILEVEL`, `MP_CHACO_SPECTRAL`, `MP_CHACO_LINEAR`,
199: `MP_CHACO_RANDOM` or `MP_CHACO_SCATTERED`
201: Options Database Key:
202: . -mat_partitioning_chaco_global <method> - the global method
204: Level: advanced
206: Note:
207: The default is the multi-level method. See Chaco documentation for
208: additional details.
210: .seealso: `MatPartitioning`, `MatPartioningSetType()`, `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetLocal()`, `MatPartitioningChacoGetGlobal()`
211: @*/
212: PetscErrorCode MatPartitioningChacoSetGlobal(MatPartitioning part, MPChacoGlobalType method)
213: {
214: PetscFunctionBegin;
217: PetscTryMethod(part, "MatPartitioningChacoSetGlobal_C", (MatPartitioning, MPChacoGlobalType), (part, method));
218: PetscFunctionReturn(PETSC_SUCCESS);
219: }
221: PetscErrorCode MatPartitioningChacoSetGlobal_Chaco(MatPartitioning part, MPChacoGlobalType method)
222: {
223: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
225: PetscFunctionBegin;
226: switch (method) {
227: case MP_CHACO_MULTILEVEL:
228: case MP_CHACO_SPECTRAL:
229: case MP_CHACO_LINEAR:
230: case MP_CHACO_RANDOM:
231: case MP_CHACO_SCATTERED:
232: chaco->global_method = method;
233: break;
234: default:
235: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
236: }
237: PetscFunctionReturn(PETSC_SUCCESS);
238: }
240: /*@
241: MatPartitioningChacoGetGlobal - Get the global method used by the Chaco partitioner.
243: Not Collective
245: Input Parameter:
246: . part - the partitioning context
248: Output Parameter:
249: . method - the method
251: Level: advanced
253: .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetGlobal()`
254: @*/
255: PetscErrorCode MatPartitioningChacoGetGlobal(MatPartitioning part, MPChacoGlobalType *method)
256: {
257: PetscFunctionBegin;
260: PetscTryMethod(part, "MatPartitioningChacoGetGlobal_C", (MatPartitioning, MPChacoGlobalType *), (part, method));
261: PetscFunctionReturn(PETSC_SUCCESS);
262: }
264: PetscErrorCode MatPartitioningChacoGetGlobal_Chaco(MatPartitioning part, MPChacoGlobalType *method)
265: {
266: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
268: PetscFunctionBegin;
269: *method = chaco->global_method;
270: PetscFunctionReturn(PETSC_SUCCESS);
271: }
273: /*@
274: MatPartitioningChacoSetLocal - Set the local method for the Chaco partitioner.
276: Collective
278: Input Parameters:
279: + part - the partitioning context
280: - method - one of `MP_CHACO_KERNIGHAN` or `MP_CHACO_NONE`
282: Options Database Key:
283: . -mat_partitioning_chaco_local <method> - the local method
285: Level: advanced
287: Note:
288: The default is to apply the Kernighan-Lin heuristic. See Chaco documentation
289: for additional details.
291: .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetGlobal()`, `MatPartitioningChacoGetLocal()`
292: @*/
293: PetscErrorCode MatPartitioningChacoSetLocal(MatPartitioning part, MPChacoLocalType method)
294: {
295: PetscFunctionBegin;
298: PetscTryMethod(part, "MatPartitioningChacoSetLocal_C", (MatPartitioning, MPChacoLocalType), (part, method));
299: PetscFunctionReturn(PETSC_SUCCESS);
300: }
302: PetscErrorCode MatPartitioningChacoSetLocal_Chaco(MatPartitioning part, MPChacoLocalType method)
303: {
304: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
306: PetscFunctionBegin;
307: switch (method) {
308: case MP_CHACO_KERNIGHAN:
309: case MP_CHACO_NONE:
310: chaco->local_method = method;
311: break;
312: default:
313: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
314: }
315: PetscFunctionReturn(PETSC_SUCCESS);
316: }
318: /*@
319: MatPartitioningChacoGetLocal - Get local method used by the Chaco partitioner.
321: Not Collective
323: Input Parameter:
324: . part - the partitioning context
326: Output Parameter:
327: . method - the method
329: Level: advanced
331: .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetLocal()`
332: @*/
333: PetscErrorCode MatPartitioningChacoGetLocal(MatPartitioning part, MPChacoLocalType *method)
334: {
335: PetscFunctionBegin;
338: PetscUseMethod(part, "MatPartitioningChacoGetLocal_C", (MatPartitioning, MPChacoLocalType *), (part, method));
339: PetscFunctionReturn(PETSC_SUCCESS);
340: }
342: PetscErrorCode MatPartitioningChacoGetLocal_Chaco(MatPartitioning part, MPChacoLocalType *method)
343: {
344: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
346: PetscFunctionBegin;
347: *method = chaco->local_method;
348: PetscFunctionReturn(PETSC_SUCCESS);
349: }
351: /*@
352: MatPartitioningChacoSetCoarseLevel - Set the coarse level parameter for the
353: Chaco partitioner.
355: Collective
357: Input Parameters:
358: + part - the partitioning context
359: - level - the coarse level in range [0.0,1.0]
361: Options Database Key:
362: . -mat_partitioning_chaco_coarse <l> - Coarse level
364: Level: advanced
366: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`
367: @*/
368: PetscErrorCode MatPartitioningChacoSetCoarseLevel(MatPartitioning part, PetscReal level)
369: {
370: PetscFunctionBegin;
373: PetscTryMethod(part, "MatPartitioningChacoSetCoarseLevel_C", (MatPartitioning, PetscReal), (part, level));
374: PetscFunctionReturn(PETSC_SUCCESS);
375: }
377: PetscErrorCode MatPartitioningChacoSetCoarseLevel_Chaco(MatPartitioning part, PetscReal level)
378: {
379: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
381: PetscFunctionBegin;
382: PetscCheck(level >= 0.0 && level < 1.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Chaco: level of coarsening out of range [0.0-1.0]");
383: chaco->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
384: if (chaco->nbvtxcoarsed < 20) chaco->nbvtxcoarsed = 20;
385: PetscFunctionReturn(PETSC_SUCCESS);
386: }
388: /*@
389: MatPartitioningChacoSetEigenSolver - Set the eigensolver method for Chaco partitioner.
391: Collective
393: Input Parameters:
394: + part - the partitioning context
395: - method - one of `MP_CHACO_LANCZOS` or `MP_CHACO_RQI`
397: Options Database Key:
398: . -mat_partitioning_chaco_eigen_solver <method> - the eigensolver
400: Level: advanced
402: Note:
403: The default is to use a Lanczos method. See Chaco documentation for details.
405: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenTol()`, `MatPartitioningChacoSetEigenNumber()`,
406: `MatPartitioningChacoGetEigenSolver()`
407: @*/
408: PetscErrorCode MatPartitioningChacoSetEigenSolver(MatPartitioning part, MPChacoEigenType method)
409: {
410: PetscFunctionBegin;
413: PetscTryMethod(part, "MatPartitioningChacoSetEigenSolver_C", (MatPartitioning, MPChacoEigenType), (part, method));
414: PetscFunctionReturn(PETSC_SUCCESS);
415: }
417: PetscErrorCode MatPartitioningChacoSetEigenSolver_Chaco(MatPartitioning part, MPChacoEigenType method)
418: {
419: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
421: PetscFunctionBegin;
422: switch (method) {
423: case MP_CHACO_LANCZOS:
424: case MP_CHACO_RQI:
425: chaco->eigen_method = method;
426: break;
427: default:
428: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
429: }
430: PetscFunctionReturn(PETSC_SUCCESS);
431: }
433: /*@
434: MatPartitioningChacoGetEigenSolver - Get the eigensolver used by the Chaco partitioner.
436: Not Collective
438: Input Parameter:
439: . part - the partitioning context
441: Output Parameter:
442: . method - the method
444: Level: advanced
446: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`
447: @*/
448: PetscErrorCode MatPartitioningChacoGetEigenSolver(MatPartitioning part, MPChacoEigenType *method)
449: {
450: PetscFunctionBegin;
453: PetscUseMethod(part, "MatPartitioningChacoGetEigenSolver_C", (MatPartitioning, MPChacoEigenType *), (part, method));
454: PetscFunctionReturn(PETSC_SUCCESS);
455: }
457: PetscErrorCode MatPartitioningChacoGetEigenSolver_Chaco(MatPartitioning part, MPChacoEigenType *method)
458: {
459: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
461: PetscFunctionBegin;
462: *method = chaco->eigen_method;
463: PetscFunctionReturn(PETSC_SUCCESS);
464: }
466: /*@
467: MatPartitioningChacoSetEigenTol - Sets the tolerance for the eigensolver used by Chaco
469: Collective
471: Input Parameters:
472: + part - the partitioning context
473: - tol - the tolerance
475: Options Database Key:
476: . -mat_partitioning_chaco_eigen_tol <tol> - Tolerance for eigensolver
478: Note:
479: Must be positive. The default value is 0.001.
481: Level: advanced
483: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`, `MatPartitioningChacoGetEigenTol()`
484: @*/
485: PetscErrorCode MatPartitioningChacoSetEigenTol(MatPartitioning part, PetscReal tol)
486: {
487: PetscFunctionBegin;
490: PetscTryMethod(part, "MatPartitioningChacoSetEigenTol_C", (MatPartitioning, PetscReal), (part, tol));
491: PetscFunctionReturn(PETSC_SUCCESS);
492: }
494: PetscErrorCode MatPartitioningChacoSetEigenTol_Chaco(MatPartitioning part, PetscReal tol)
495: {
496: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
498: PetscFunctionBegin;
499: if (tol == PETSC_DEFAULT) chaco->eigtol = 0.001;
500: else {
501: PetscCheck(tol > 0.0, PetscObjectComm((PetscObject)part), PETSC_ERR_ARG_OUTOFRANGE, "Tolerance must be positive");
502: chaco->eigtol = tol;
503: }
504: PetscFunctionReturn(PETSC_SUCCESS);
505: }
507: /*@
508: MatPartitioningChacoGetEigenTol - Gets the eigensolver tolerance used by Chaco
510: Not Collective
512: Input Parameter:
513: . part - the partitioning context
515: Output Parameter:
516: . tol - the tolerance
518: Level: advanced
520: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenTol()`
521: @*/
522: PetscErrorCode MatPartitioningChacoGetEigenTol(MatPartitioning part, PetscReal *tol)
523: {
524: PetscFunctionBegin;
527: PetscUseMethod(part, "MatPartitioningChacoGetEigenTol_C", (MatPartitioning, PetscReal *), (part, tol));
528: PetscFunctionReturn(PETSC_SUCCESS);
529: }
531: PetscErrorCode MatPartitioningChacoGetEigenTol_Chaco(MatPartitioning part, PetscReal *tol)
532: {
533: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
535: PetscFunctionBegin;
536: *tol = chaco->eigtol;
537: PetscFunctionReturn(PETSC_SUCCESS);
538: }
540: /*@
541: MatPartitioningChacoSetEigenNumber - Sets the number of eigenvectors to compute by Chaco during partitioning
542: during partitioning.
544: Collective
546: Input Parameters:
547: + part - the partitioning context
548: - num - the number of eigenvectors
550: Options Database Key:
551: . -mat_partitioning_chaco_eigen_number <n> - Number of eigenvectors
553: Note:
554: Accepted values are 1, 2 or 3, indicating partitioning by bisection,
555: quadrisection, or octosection.
557: Level: advanced
559: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`, `MatPartitioningChacoGetEigenTol()`
560: @*/
561: PetscErrorCode MatPartitioningChacoSetEigenNumber(MatPartitioning part, PetscInt num)
562: {
563: PetscFunctionBegin;
566: PetscTryMethod(part, "MatPartitioningChacoSetEigenNumber_C", (MatPartitioning, PetscInt), (part, num));
567: PetscFunctionReturn(PETSC_SUCCESS);
568: }
570: PetscErrorCode MatPartitioningChacoSetEigenNumber_Chaco(MatPartitioning part, PetscInt num)
571: {
572: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
574: PetscFunctionBegin;
575: if (num == PETSC_DEFAULT) chaco->eignum = 1;
576: else {
577: PetscCheck(num >= 1 && num <= 3, PetscObjectComm((PetscObject)part), PETSC_ERR_ARG_OUTOFRANGE, "Can only specify 1, 2 or 3 eigenvectors");
578: chaco->eignum = num;
579: }
580: PetscFunctionReturn(PETSC_SUCCESS);
581: }
583: /*@
584: MatPartitioningChacoGetEigenNumber - Gets the number of eigenvectors used by Chaco.
586: Not Collective
588: Input Parameter:
589: . part - the partitioning context
591: Output Parameter:
592: . num - number of eigenvectors
594: Level: advanced
596: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenNumber()`
597: @*/
598: PetscErrorCode MatPartitioningChacoGetEigenNumber(MatPartitioning part, PetscInt *num)
599: {
600: PetscFunctionBegin;
603: PetscUseMethod(part, "MatPartitioningChacoGetEigenNumber_C", (MatPartitioning, PetscInt *), (part, num));
604: PetscFunctionReturn(PETSC_SUCCESS);
605: }
607: PetscErrorCode MatPartitioningChacoGetEigenNumber_Chaco(MatPartitioning part, PetscInt *num)
608: {
609: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
611: PetscFunctionBegin;
612: *num = chaco->eignum;
613: PetscFunctionReturn(PETSC_SUCCESS);
614: }
616: PetscErrorCode MatPartitioningSetFromOptions_Chaco(MatPartitioning part, PetscOptionItems *PetscOptionsObject)
617: {
618: PetscInt i;
619: PetscReal r;
620: PetscBool flag;
621: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
622: MPChacoGlobalType global;
623: MPChacoLocalType local;
624: MPChacoEigenType eigen;
626: PetscFunctionBegin;
627: PetscOptionsHeadBegin(PetscOptionsObject, "Chaco partitioning options");
628: PetscCall(PetscOptionsEnum("-mat_partitioning_chaco_global", "Global method", "MatPartitioningChacoSetGlobal", MPChacoGlobalTypes, (PetscEnum)chaco->global_method, (PetscEnum *)&global, &flag));
629: if (flag) PetscCall(MatPartitioningChacoSetGlobal(part, global));
630: PetscCall(PetscOptionsEnum("-mat_partitioning_chaco_local", "Local method", "MatPartitioningChacoSetLocal", MPChacoLocalTypes, (PetscEnum)chaco->local_method, (PetscEnum *)&local, &flag));
631: if (flag) PetscCall(MatPartitioningChacoSetLocal(part, local));
632: PetscCall(PetscOptionsReal("-mat_partitioning_chaco_coarse", "Coarse level", "MatPartitioningChacoSetCoarseLevel", 0.0, &r, &flag));
633: if (flag) PetscCall(MatPartitioningChacoSetCoarseLevel(part, r));
634: PetscCall(PetscOptionsEnum("-mat_partitioning_chaco_eigen_solver", "Eigensolver method", "MatPartitioningChacoSetEigenSolver", MPChacoEigenTypes, (PetscEnum)chaco->eigen_method, (PetscEnum *)&eigen, &flag));
635: if (flag) PetscCall(MatPartitioningChacoSetEigenSolver(part, eigen));
636: PetscCall(PetscOptionsReal("-mat_partitioning_chaco_eigen_tol", "Eigensolver tolerance", "MatPartitioningChacoSetEigenTol", chaco->eigtol, &r, &flag));
637: if (flag) PetscCall(MatPartitioningChacoSetEigenTol(part, r));
638: PetscCall(PetscOptionsInt("-mat_partitioning_chaco_eigen_number", "Number of eigenvectors: 1, 2, or 3 (bi-, quadri-, or octosection)", "MatPartitioningChacoSetEigenNumber", chaco->eignum, &i, &flag));
639: if (flag) PetscCall(MatPartitioningChacoSetEigenNumber(part, i));
640: PetscCall(PetscOptionsBool("-mat_partitioning_chaco_verbose", "Show library output", "", chaco->verbose, &chaco->verbose, NULL));
641: PetscOptionsHeadEnd();
642: PetscFunctionReturn(PETSC_SUCCESS);
643: }
645: PetscErrorCode MatPartitioningDestroy_Chaco(MatPartitioning part)
646: {
647: MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
649: PetscFunctionBegin;
650: PetscCall(PetscFree(chaco));
651: /* clear composed functions */
652: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetGlobal_C", NULL));
653: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetGlobal_C", NULL));
654: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetLocal_C", NULL));
655: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetLocal_C", NULL));
656: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetCoarseLevel_C", NULL));
657: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenSolver_C", NULL));
658: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenSolver_C", NULL));
659: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenTol_C", NULL));
660: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenTol_C", NULL));
661: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenNumber_C", NULL));
662: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenNumber_C", NULL));
663: PetscFunctionReturn(PETSC_SUCCESS);
664: }
666: /*MC
667: MATPARTITIONINGCHACO - Creates a partitioning context that uses the external package Chaco.
669: Level: beginner
671: Note:
672: Does not use the `MatPartitioningSetUseEdgeWeights()` option
674: References:
675: . * - http://www.cs.sandia.gov/CRF/chac.html
677: .seealso: `MatPartitioningSetType()`, `MatPartitioningType`
678: M*/
680: PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Chaco(MatPartitioning part)
681: {
682: MatPartitioning_Chaco *chaco;
684: PetscFunctionBegin;
685: PetscCall(PetscNew(&chaco));
686: part->data = (void *)chaco;
688: chaco->global_method = MP_CHACO_MULTILEVEL;
689: chaco->local_method = MP_CHACO_KERNIGHAN;
690: chaco->eigen_method = MP_CHACO_LANCZOS;
691: chaco->nbvtxcoarsed = 200;
692: chaco->eignum = 1;
693: chaco->eigtol = 0.001;
694: chaco->verbose = PETSC_FALSE;
696: part->ops->apply = MatPartitioningApply_Chaco;
697: part->ops->view = MatPartitioningView_Chaco;
698: part->ops->destroy = MatPartitioningDestroy_Chaco;
699: part->ops->setfromoptions = MatPartitioningSetFromOptions_Chaco;
701: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetGlobal_C", MatPartitioningChacoSetGlobal_Chaco));
702: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetGlobal_C", MatPartitioningChacoGetGlobal_Chaco));
703: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetLocal_C", MatPartitioningChacoSetLocal_Chaco));
704: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetLocal_C", MatPartitioningChacoGetLocal_Chaco));
705: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetCoarseLevel_C", MatPartitioningChacoSetCoarseLevel_Chaco));
706: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenSolver_C", MatPartitioningChacoSetEigenSolver_Chaco));
707: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenSolver_C", MatPartitioningChacoGetEigenSolver_Chaco));
708: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenTol_C", MatPartitioningChacoSetEigenTol_Chaco));
709: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenTol_C", MatPartitioningChacoGetEigenTol_Chaco));
710: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenNumber_C", MatPartitioningChacoSetEigenNumber_Chaco));
711: PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenNumber_C", MatPartitioningChacoGetEigenNumber_Chaco));
712: PetscFunctionReturn(PETSC_SUCCESS);
713: }