Actual source code: matcoloring.c

  1: #include <petsc/private/matimpl.h>

  3: PetscFunctionList MatColoringList              = NULL;
  4: PetscBool         MatColoringRegisterAllCalled = PETSC_FALSE;
  5: const char *const MatColoringWeightTypes[] = {"RANDOM","LEXICAL","LF","SL","MatColoringWeightType","MAT_COLORING_WEIGHT_",NULL};

  7: /*@C
  8:    MatColoringRegister - Adds a new sparse matrix coloring to the  matrix package.

 10:    Not Collective

 12:    Input Parameters:
 13: +  sname - name of Coloring (for example MATCOLORINGSL)
 14: -  function - function pointer that creates the coloring

 16:    Level: developer

 18:    Sample usage:
 19: .vb
 20:    MatColoringRegister("my_color",MyColor);
 21: .ve

 23:    Then, your partitioner can be chosen with the procedural interface via
 24: $     MatColoringSetType(part,"my_color")
 25:    or at runtime via the option
 26: $     -mat_coloring_type my_color

 28: .seealso: MatColoringRegisterDestroy(), MatColoringRegisterAll()
 29: @*/
 30: PetscErrorCode  MatColoringRegister(const char sname[],PetscErrorCode (*function)(MatColoring))
 31: {
 32:   MatInitializePackage();
 33:   PetscFunctionListAdd(&MatColoringList,sname,function);
 34:   return 0;
 35: }

 37: /*@
 38:    MatColoringCreate - Creates a matrix coloring context.

 40:    Collective on MatColoring

 42:    Input Parameters:
 43: .  comm - MPI communicator

 45:    Output Parameter:
 46: .  mcptr - the new MatColoring context

 48:    Options Database Keys:
 49: +   -mat_coloring_type - the type of coloring algorithm used. See MatColoringType.
 50: .   -mat_coloring_maxcolors - the maximum number of relevant colors, all nodes not in a color are in maxcolors+1
 51: .   -mat_coloring_distance - compute a distance 1,2,... coloring.
 52: .   -mat_coloring_view - print information about the coloring and the produced index sets
 53: .   -mat_coloring_test - debugging option that prints all coloring incompatibilities
 54: -   -mat_is_coloring_test - debugging option that throws an error if MatColoringApply() generates an incorrect iscoloring

 56:    Level: beginner

 58:    Notes:
 59:     A distance one coloring is useful, for example, multi-color SOR. A distance two coloring is for the finite difference computation of Jacobians
 60:           (see MatFDColoringCreate()).

 62:        Coloring of matrices can be computed directly from the sparse matrix nonzero structure via the MatColoring object or from the mesh from which the
 63:        matrix comes from with DMCreateColoring(). In general using the mesh produces a more optimal coloring (fewer colors).

 65:           Some coloring types only support distance two colorings

 67: .seealso: MatColoring, MatColoringApply(), MatFDColoringCreate(), DMCreateColoring(), MatColoringType
 68: @*/
 69: PetscErrorCode MatColoringCreate(Mat m,MatColoring *mcptr)
 70: {
 71:   MatColoring    mc;

 75:   *mcptr = NULL;

 77:   MatInitializePackage();
 78:   PetscHeaderCreate(mc, MAT_COLORING_CLASSID,"MatColoring","Matrix coloring", "MatColoring",PetscObjectComm((PetscObject)m),MatColoringDestroy, MatColoringView);
 79:   PetscObjectReference((PetscObject)m);
 80:   mc->mat       = m;
 81:   mc->dist      = 2; /* default to Jacobian computation case */
 82:   mc->maxcolors = IS_COLORING_MAX;
 83:   *mcptr        = mc;
 84:   mc->valid     = PETSC_FALSE;
 85:   mc->weight_type = MAT_COLORING_WEIGHT_RANDOM;
 86:   mc->user_weights = NULL;
 87:   mc->user_lperm = NULL;
 88:   return 0;
 89: }

 91: /*@
 92:    MatColoringDestroy - Destroys the matrix coloring context

 94:    Collective on MatColoring

 96:    Input Parameter:
 97: .  mc - the MatColoring context

 99:    Level: beginner

101: .seealso: MatColoringCreate(), MatColoringApply()
102: @*/
103: PetscErrorCode MatColoringDestroy(MatColoring *mc)
104: {
105:   if (--((PetscObject)(*mc))->refct > 0) {*mc = NULL; return 0;}
106:   MatDestroy(&(*mc)->mat);
107:   if ((*mc)->ops->destroy) (*((*mc)->ops->destroy))(*mc);
108:   if ((*mc)->user_weights) PetscFree((*mc)->user_weights);
109:   if ((*mc)->user_lperm) PetscFree((*mc)->user_lperm);
110:   PetscHeaderDestroy(mc);
111:   return 0;
112: }

114: /*@C
115:    MatColoringSetType - Sets the type of coloring algorithm used

117:    Collective on MatColoring

119:    Input Parameters:
120: +  mc - the MatColoring context
121: -  type - the type of coloring

123:    Level: beginner

125:    Notes:
126:     Possible types include the sequential types MATCOLORINGLF,
127:    MATCOLORINGSL, and MATCOLORINGID from the MINPACK package as well
128:    as a parallel MATCOLORINGMIS algorithm.

130: .seealso: MatColoringCreate(), MatColoringApply()
131: @*/
132: PetscErrorCode MatColoringSetType(MatColoring mc,MatColoringType type)
133: {
134:   PetscBool      match;
135:   PetscErrorCode (*r)(MatColoring);

139:   PetscObjectTypeCompare((PetscObject)mc,type,&match);
140:   if (match) return 0;
141:   PetscFunctionListFind(MatColoringList,type,&r);
143:   if (mc->ops->destroy) {
144:     (*(mc)->ops->destroy)(mc);
145:     mc->ops->destroy = NULL;
146:   }
147:   mc->ops->apply            = NULL;
148:   mc->ops->view             = NULL;
149:   mc->ops->setfromoptions   = NULL;
150:   mc->ops->destroy          = NULL;

152:   PetscObjectChangeTypeName((PetscObject)mc,type);
153:   (*r)(mc);
154:   return 0;
155: }

157: /*@
158:    MatColoringSetFromOptions - Sets MatColoring options from user parameters

160:    Collective on MatColoring

162:    Input Parameter:
163: .  mc - MatColoring context

165:    Options Database Keys:
166: +   -mat_coloring_type - the type of coloring algorithm used. See MatColoringType.
167: .   -mat_coloring_maxcolors - the maximum number of relevant colors, all nodes not in a color are in maxcolors+1
168: .   -mat_coloring_distance - compute a distance 1,2,... coloring.
169: .   -mat_coloring_view - print information about the coloring and the produced index sets
170: .   -snes_fd_color - instruct SNES to using coloring and then MatFDColoring to compute the Jacobians
171: -   -snes_fd_color_use_mat - instruct SNES to color the matrix directly instead of the DM from which the matrix comes (the default)

173:    Level: beginner

175: .seealso: MatColoring, MatColoringApply(), MatColoringSetDistance(), SNESComputeJacobianDefaultColor(), MatColoringType
176: @*/
177: PetscErrorCode MatColoringSetFromOptions(MatColoring mc)
178: {
179:   PetscBool      flg;
180:   MatColoringType deft = MATCOLORINGSL;
181:   char           type[256];
183:   PetscInt       dist,maxcolors;

186:   MatColoringGetDistance(mc,&dist);
187:   if (dist == 2) deft = MATCOLORINGSL;
188:   else           deft = MATCOLORINGGREEDY;
189:   MatColoringGetMaxColors(mc,&maxcolors);
190:   MatColoringRegisterAll();
191:   PetscObjectOptionsBegin((PetscObject)mc);
192:   if (((PetscObject)mc)->type_name) deft = ((PetscObject)mc)->type_name;
193:   PetscOptionsFList("-mat_coloring_type","The coloring method used","MatColoringSetType",MatColoringList,deft,type,256,&flg);
194:   if (flg) {
195:     MatColoringSetType(mc,type);
196:   } else if (!((PetscObject)mc)->type_name) {
197:     MatColoringSetType(mc,deft);
198:   }
199:   PetscOptionsInt("-mat_coloring_distance","Distance of the coloring","MatColoringSetDistance",dist,&dist,&flg);
200:   if (flg) MatColoringSetDistance(mc,dist);
201:   PetscOptionsInt("-mat_coloring_maxcolors","Maximum colors returned at the end. 1 returns an independent set","MatColoringSetMaxColors",maxcolors,&maxcolors,&flg);
202:   if (flg) MatColoringSetMaxColors(mc,maxcolors);
203:   if (mc->ops->setfromoptions) {
204:     (*mc->ops->setfromoptions)(PetscOptionsObject,mc);
205:   }
206:   PetscOptionsBool("-mat_coloring_test","Check that a valid coloring has been produced","",mc->valid,&mc->valid,NULL);
207:   PetscOptionsBool("-mat_is_coloring_test","Check that a valid iscoloring has been produced","",mc->valid_iscoloring,&mc->valid_iscoloring,NULL);
208:   PetscOptionsEnum("-mat_coloring_weight_type","Sets the type of vertex weighting used","MatColoringSetWeightType",MatColoringWeightTypes,(PetscEnum)mc->weight_type,(PetscEnum*)&mc->weight_type,NULL);
209:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)mc);
210:   PetscOptionsEnd();
211:   return 0;
212: }

214: /*@
215:    MatColoringSetDistance - Sets the distance of the coloring

217:    Logically Collective on MatColoring

219:    Input Parameters:
220: +  mc - the MatColoring context
221: -  dist - the distance the coloring should compute

223:    Level: beginner

225:    Notes:
226:     The distance of the coloring denotes the minimum number
227:    of edges in the graph induced by the matrix any two vertices
228:    of the same color are.  Distance-1 colorings are the classical
229:    coloring, where no two vertices of the same color are adjacent.
230:    distance-2 colorings are useful for the computation of Jacobians.

232: .seealso: MatColoringGetDistance(), MatColoringApply()
233: @*/
234: PetscErrorCode MatColoringSetDistance(MatColoring mc,PetscInt dist)
235: {
237:   mc->dist = dist;
238:   return 0;
239: }

241: /*@
242:    MatColoringGetDistance - Gets the distance of the coloring

244:    Logically Collective on MatColoring

246:    Input Parameter:
247: .  mc - the MatColoring context

249:    Output Parameter:
250: .  dist - the current distance being used for the coloring.

252:    Level: beginner

254: .seealso: MatColoringSetDistance(), MatColoringApply()
255: @*/
256: PetscErrorCode MatColoringGetDistance(MatColoring mc,PetscInt *dist)
257: {
259:   if (dist) *dist = mc->dist;
260:   return 0;
261: }

263: /*@
264:    MatColoringSetMaxColors - Sets the maximum number of colors

266:    Logically Collective on MatColoring

268:    Input Parameters:
269: +  mc - the MatColoring context
270: -  maxcolors - the maximum number of colors to produce

272:    Level: beginner

274:    Notes:
275:     This may be used to compute a certain number of
276:    independent sets from the graph.  For instance, while using
277:    MATCOLORINGMIS and maxcolors = 1, one gets out an MIS.  Vertices
278:    not in a color are set to have color maxcolors+1, which is not
279:    a valid color as they may be adjacent.

281: .seealso: MatColoringGetMaxColors(), MatColoringApply()
282: @*/
283: PetscErrorCode MatColoringSetMaxColors(MatColoring mc,PetscInt maxcolors)
284: {
286:   mc->maxcolors = maxcolors;
287:   return 0;
288: }

290: /*@
291:    MatColoringGetMaxColors - Gets the maximum number of colors

293:    Logically Collective on MatColoring

295:    Input Parameter:
296: .  mc - the MatColoring context

298:    Output Parameter:
299: .  maxcolors - the current maximum number of colors to produce

301:    Level: beginner

303: .seealso: MatColoringSetMaxColors(), MatColoringApply()
304: @*/
305: PetscErrorCode MatColoringGetMaxColors(MatColoring mc,PetscInt *maxcolors)
306: {
308:   if (maxcolors) *maxcolors = mc->maxcolors;
309:   return 0;
310: }

312: /*@
313:    MatColoringApply - Apply the coloring to the matrix, producing index
314:    sets corresponding to a number of independent sets in the induced
315:    graph.

317:    Collective on MatColoring

319:    Input Parameters:
320: .  mc - the MatColoring context

322:    Output Parameter:
323: .  coloring - the ISColoring instance containing the coloring

325:    Level: beginner

327: .seealso: MatColoring, MatColoringCreate()
328: @*/
329: PetscErrorCode MatColoringApply(MatColoring mc,ISColoring *coloring)
330: {
331:   PetscBool         flg;
332:   PetscViewerFormat format;
333:   PetscViewer       viewer;
334:   PetscInt          nc,ncolors;

338:   PetscLogEventBegin(MATCOLORING_Apply,mc,0,0,0);
339:   (*mc->ops->apply)(mc,coloring);
340:   PetscLogEventEnd(MATCOLORING_Apply,mc,0,0,0);

342:   /* valid */
343:   if (mc->valid) {
344:     MatColoringTest(mc,*coloring);
345:   }
346:   if (mc->valid_iscoloring) {
347:     MatISColoringTest(mc->mat,*coloring);
348:   }

350:   /* view */
351:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)mc),((PetscObject)mc)->options,((PetscObject)mc)->prefix,"-mat_coloring_view",&viewer,&format,&flg);
352:   if (flg && !PetscPreLoadingOn) {
353:     PetscViewerPushFormat(viewer,format);
354:     MatColoringView(mc,viewer);
355:     MatGetSize(mc->mat,NULL,&nc);
356:     ISColoringGetIS(*coloring,PETSC_USE_POINTER,&ncolors,NULL);
357:     PetscViewerASCIIPrintf(viewer,"  Number of colors %" PetscInt_FMT "\n",ncolors);
358:     PetscViewerASCIIPrintf(viewer,"  Number of total columns %" PetscInt_FMT "\n",nc);
359:     if (nc <= 1000) ISColoringView(*coloring,viewer);
360:     PetscViewerPopFormat(viewer);
361:     PetscViewerDestroy(&viewer);
362:   }
363:   return 0;
364: }

366: /*@
367:    MatColoringView - Output details about the MatColoring.

369:    Collective on MatColoring

371:    Input Parameters:
372: -  mc - the MatColoring context
373: +  viewer - the Viewer context

375:    Level: beginner

377: .seealso: MatColoring, MatColoringApply()
378: @*/
379: PetscErrorCode MatColoringView(MatColoring mc,PetscViewer viewer)
380: {
381:   PetscBool      iascii;

384:   if (!viewer) {
385:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mc),&viewer);
386:   }

390:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
391:   if (iascii) {
392:     PetscObjectPrintClassNamePrefixType((PetscObject)mc,viewer);
393:     PetscViewerASCIIPrintf(viewer,"  Weight type: %s\n",MatColoringWeightTypes[mc->weight_type]);
394:     if (mc->maxcolors > 0) {
395:       PetscViewerASCIIPrintf(viewer,"  Distance %" PetscInt_FMT ", Max. Colors %" PetscInt_FMT "\n",mc->dist,mc->maxcolors);
396:     } else {
397:       PetscViewerASCIIPrintf(viewer,"  Distance %" PetscInt_FMT "\n",mc->dist);
398:     }
399:   }
400:   return 0;
401: }

403: /*@
404:    MatColoringSetWeightType - Set the type of weight computation used.

406:    Logically collective on MatColoring

408:    Input Parameters:
409: -  mc - the MatColoring context
410: +  wt - the weight type

412:    Level: beginner

414: .seealso: MatColoring, MatColoringWeightType
415: @*/
416: PetscErrorCode MatColoringSetWeightType(MatColoring mc,MatColoringWeightType wt)
417: {
418:   mc->weight_type = wt;
419:   return 0;

421: }