Date: 2013-07-02T14:41:32+00:00

Actual source code: fdaij.c
petsc-3.4.2 2013-07-02

      2: #include <../src/mat/impls/aij/seq/aij.h>

      6: /*
      7:     This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks.
      8:     This is why it has the ugly code with the MatGetBlockSize()
      9: */
     10: PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c)
     11: {
     13:   PetscInt       i,n,nrows,N,j,k,m,ncols,col;
     14:   const PetscInt *is,*rows,*ci,*cj;
     15:   PetscInt       nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1;
     16:   IS             *isa;
     17:   PetscBool      done,flg = PETSC_FALSE;
     18:   PetscBool      flg1,flg2;

     21:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();");

     23:   ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);
     24:   /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */
     25:   PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);
     26:   PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);
     27:   if (flg1 || flg2) {
     28:     MatGetBlockSize(mat,&bs);
     29:   }

     31:   N         = mat->cmap->N/bs;
     32:   c->M      = mat->rmap->N/bs;   /* set total rows, columns and local rows */
     33:   c->N      = mat->cmap->N/bs;
     34:   c->m      = mat->rmap->N/bs;
     35:   c->rstart = 0;

     37:   c->ncolors = nis;
     38:   PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);
     39:   PetscMalloc(nis*sizeof(PetscInt*),&c->columns);
     40:   PetscMalloc(nis*sizeof(PetscInt),&c->nrows);
     41:   PetscMalloc(nis*sizeof(PetscInt*),&c->rows);
     42:   PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);

     44:   MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);
     45:   if (!done) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name);

     47:   /*
     48:      Temporary option to allow for debugging/testing
     49:   */
     50:   PetscOptionsGetBool(NULL,"-matfdcoloring_slow",&flg,NULL);

     52:   PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);
     53:   PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);

     55:   for (i=0; i<nis; i++) {
     56:     ISGetLocalSize(isa[i],&n);
     57:     ISGetIndices(isa[i],&is);

     59:     c->ncolumns[i] = n;
     60:     if (n) {
     61:       PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);
     62:       PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));
     63:     } else {
     64:       c->columns[i] = 0;
     65:     }

     67:     if (!flg) { /* ------------------------------------------------------------------------------*/
     68:       /* fast, crude version requires O(N*N) work */
     69:       PetscMemzero(rowhit,N*sizeof(PetscInt));
     70:       /* loop over columns*/
     71:       for (j=0; j<n; j++) {
     72:         col  = is[j];
     73:         rows = cj + ci[col];
     74:         m    = ci[col+1] - ci[col];
     75:         /* loop over columns marking them in rowhit */
     76:         for (k=0; k<m; k++) {
     77:           rowhit[*rows++] = col + 1;
     78:         }
     79:       }
     80:       /* count the number of hits */
     81:       nrows = 0;
     82:       for (j=0; j<N; j++) {
     83:         if (rowhit[j]) nrows++;
     84:       }
     85:       c->nrows[i] = nrows;
     86:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);
     87:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);
     88:       nrows       = 0;
     89:       for (j=0; j<N; j++) {
     90:         if (rowhit[j]) {
     91:           c->rows[i][nrows]          = j;
     92:           c->columnsforrow[i][nrows] = rowhit[j] - 1;
     93:           nrows++;
     94:         }
     95:       }
     96:     } else {  /*-------------------------------------------------------------------------------*/
     97:       /* slow version, using rowhit as a linked list */
     98:       PetscInt currentcol,fm,mfm;
     99:       rowhit[N] = N;
    100:       nrows     = 0;
    101:       /* loop over columns */
    102:       for (j=0; j<n; j++) {
    103:         col  = is[j];
    104:         rows = cj + ci[col];
    105:         m    = ci[col+1] - ci[col];
    106:         /* loop over columns marking them in rowhit */
    107:         fm = N;    /* fm points to first entry in linked list */
    108:         for (k=0; k<m; k++) {
    109:           currentcol = *rows++;
    110:           /* is it already in the list? */
    111:           do {
    112:             mfm = fm;
    113:             fm  = rowhit[fm];
    114:           } while (fm < currentcol);
    115:           /* not in list so add it */
    116:           if (fm != currentcol) {
    117:             nrows++;
    118:             columnsforrow[currentcol] = col;
    119:             /* next three lines insert new entry into linked list */
    120:             rowhit[mfm]        = currentcol;
    121:             rowhit[currentcol] = fm;
    122:             fm                 = currentcol;
    123:             /* fm points to present position in list since we know the columns are sorted */
    124:           } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring");
    125:         }
    126:       }
    127:       c->nrows[i] = nrows;
    128:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);
    129:       PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);
    130:       /* now store the linked list of rows into c->rows[i] */
    131:       nrows = 0;
    132:       fm    = rowhit[N];
    133:       do {
    134:         c->rows[i][nrows]            = fm;
    135:         c->columnsforrow[i][nrows++] = columnsforrow[fm];
    136:         fm                           = rowhit[fm];
    137:       } while (fm < N);
    138:     } /* ---------------------------------------------------------------------------------------*/
    139:     ISRestoreIndices(isa[i],&is);
    140:   }
    141:   MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);

    143:   PetscFree(rowhit);
    144:   PetscFree(columnsforrow);

    146:   /* Optimize by adding the vscale, and scaleforrow[][] fields */
    147:   /*
    148:        see the version for MPIAIJ
    149:   */
    150:   VecCreateGhost(PetscObjectComm((PetscObject)mat),mat->rmap->n,PETSC_DETERMINE,0,NULL,&c->vscale);
    151:   PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);
    152:   for (k=0; k<c->ncolors; k++) {
    153:     PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);
    154:     for (l=0; l<c->nrows[k]; l++) {
    155:       col = c->columnsforrow[k][l];

    157:       c->vscaleforrow[k][l] = col;
    158:     }
    159:   }
    160:   ISColoringRestoreIS(iscoloring,&isa);
    161:   return(0);
    162: }