Actual source code: bipartite.c
1: #include <petsc/private/matimpl.h>
2: #include <petscsf.h>
4: PETSC_EXTERN PetscErrorCode MatColoringCreateBipartiteGraph(MatColoring mc, PetscSF *etoc, PetscSF *etor)
5: {
6: PetscInt nentries, ncolentries, idx;
7: PetscInt i, j, rs, re, cs, ce, cn;
8: PetscInt *rowleaf, *colleaf, *rowdata;
9: PetscInt ncol;
10: const PetscScalar *vcol;
11: const PetscInt *icol;
12: const PetscInt *coldegrees, *rowdegrees;
13: Mat m = mc->mat;
15: MatGetOwnershipRange(m, &rs, &re);
16: MatGetOwnershipRangeColumn(m, &cs, &ce);
17: cn = ce - cs;
18: nentries = 0;
19: for (i = rs; i < re; i++) {
20: MatGetRow(m, i, &ncol, NULL, &vcol);
21: for (j = 0; j < ncol; j++) nentries++;
22: MatRestoreRow(m, i, &ncol, NULL, &vcol);
23: }
24: PetscMalloc1(nentries, &rowleaf);
25: PetscMalloc1(nentries, &rowdata);
26: idx = 0;
27: for (i = rs; i < re; i++) {
28: MatGetRow(m, i, &ncol, &icol, &vcol);
29: for (j = 0; j < ncol; j++) {
30: rowleaf[idx] = icol[j];
31: rowdata[idx] = i;
32: idx++;
33: }
34: MatRestoreRow(m, i, &ncol, &icol, &vcol);
35: }
37: PetscSFCreate(PetscObjectComm((PetscObject)m), etoc);
38: PetscSFCreate(PetscObjectComm((PetscObject)m), etor);
40: PetscSFSetGraphLayout(*etoc, m->cmap, nentries, NULL, PETSC_COPY_VALUES, rowleaf);
41: PetscSFSetFromOptions(*etoc);
43: /* determine the number of entries in the column matrix */
44: PetscLogEventBegin(MATCOLORING_Comm, *etoc, 0, 0, 0);
45: PetscSFComputeDegreeBegin(*etoc, &coldegrees);
46: PetscSFComputeDegreeEnd(*etoc, &coldegrees);
47: PetscLogEventEnd(MATCOLORING_Comm, *etoc, 0, 0, 0);
48: ncolentries = 0;
49: for (i = 0; i < cn; i++) ncolentries += coldegrees[i];
50: PetscMalloc1(ncolentries, &colleaf);
52: /* create the one going the other way by building the leaf set */
53: PetscLogEventBegin(MATCOLORING_Comm, *etoc, 0, 0, 0);
54: PetscSFGatherBegin(*etoc, MPIU_INT, rowdata, colleaf);
55: PetscSFGatherEnd(*etoc, MPIU_INT, rowdata, colleaf);
56: PetscLogEventEnd(MATCOLORING_Comm, *etoc, 0, 0, 0);
58: /* this one takes mat entries in *columns* to rows -- you never have to actually be able to order the leaf entries. */
59: PetscSFSetGraphLayout(*etor, m->rmap, ncolentries, NULL, PETSC_COPY_VALUES, colleaf);
60: PetscSFSetFromOptions(*etor);
62: PetscLogEventBegin(MATCOLORING_Comm, *etor, 0, 0, 0);
63: PetscSFComputeDegreeBegin(*etor, &rowdegrees);
64: PetscSFComputeDegreeEnd(*etor, &rowdegrees);
65: PetscLogEventEnd(MATCOLORING_Comm, *etor, 0, 0, 0);
67: PetscFree(rowdata);
68: PetscFree(rowleaf);
69: PetscFree(colleaf);
70: return 0;
71: }