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: }