Actual source code: matpreallocator.c

petsc-3.7.7 2017-09-25
Report Typos and Errors
  1: #include <petsc/private/matimpl.h>      /*I "petscmat.h" I*/
  2: #include <../src/sys/utils/hash.h>

  4: typedef struct {
  5:   PetscHashJK ht;
  6:   PetscInt   *dnz, *onz;
  7: } Mat_Preallocator;

 11: PetscErrorCode MatDestroy_Preallocator(Mat A)
 12: {
 13:   Mat_Preallocator *p = (Mat_Preallocator *) A->data;
 14:   PetscErrorCode    ierr;

 17:   MatStashDestroy_Private(&A->stash);
 18:   PetscHashJKDestroy(&p->ht);
 19:   PetscFree2(p->dnz, p->onz);
 20:   PetscFree(A->data);
 21:   PetscObjectChangeTypeName((PetscObject) A, 0);
 22:   PetscObjectComposeFunction((PetscObject) A, "MatPreallocatorPreallocate_C", NULL);
 23:   return(0);
 24: }

 28: PetscErrorCode MatSetUp_Preallocator(Mat A)
 29: {
 30:   Mat_Preallocator *p = (Mat_Preallocator *) A->data;
 31:   PetscInt          m, bs;
 32:   PetscErrorCode    ierr;

 35:   PetscLayoutSetUp(A->rmap);
 36:   PetscLayoutSetUp(A->cmap);
 37:   MatGetLocalSize(A, &m, NULL);
 38:   PetscHashJKCreate(&p->ht);
 39:   MatGetBlockSize(A, &bs);
 40:   MatStashCreate_Private(PetscObjectComm((PetscObject) A), bs, &A->stash);
 41:   PetscCalloc2(m, &p->dnz, m, &p->onz);
 42:   return(0);
 43: }

 47: PetscErrorCode MatSetValues_Preallocator(Mat A, PetscInt m, const PetscInt *rows, PetscInt n, const PetscInt *cols, const PetscScalar *values, InsertMode addv)
 48: {
 49:   Mat_Preallocator *p = (Mat_Preallocator *) A->data;
 50:   PetscInt          rStart, rEnd, r, cStart, cEnd, c;
 51:   PetscErrorCode    ierr;

 54:   /* TODO: Handle blocksize */
 55:   MatGetOwnershipRange(A, &rStart, &rEnd);
 56:   MatGetOwnershipRangeColumn(A, &cStart, &cEnd);
 57:   for (r = 0; r < m; ++r) {
 58:     PetscHashJKKey  key;
 59:     PetscHashJKIter missing, iter;

 61:     key.j = rows[r];
 62:     if (key.j < 0) continue;
 63:     if ((key.j < rStart) || (key.j >= rEnd)) {
 64:       MatStashValuesRow_Private(&A->stash, key.j, n, cols, values, PETSC_FALSE);
 65:     } else {
 66:       for (c = 0; c < n; ++c) {
 67:         key.k = cols[c];
 68:         if (key.k < 0) continue;
 69:         PetscHashJKPut(p->ht, key, &missing, &iter);
 70:         if (missing) {
 71:           PetscHashJKSet(p->ht, iter, 1);
 72:           if ((key.k >= cStart) && (key.k < cEnd)) ++p->dnz[key.j-rStart];
 73:           else                                     ++p->onz[key.j-rStart];
 74:         }
 75:       }
 76:     }
 77:   }
 78:   return(0);
 79: }

 83: PetscErrorCode MatAssemblyBegin_Preallocator(Mat A, MatAssemblyType type)
 84: {
 85:   PetscInt       nstash, reallocs;

 89:   PetscLayoutSetUp(A->rmap);
 90:   MatStashScatterBegin_Private(A, &A->stash, A->rmap->range);
 91:   MatStashGetInfo_Private(&A->stash, &nstash, &reallocs);
 92:   PetscInfo2(A, "Stash has %D entries, uses %D mallocs.\n", nstash, reallocs);
 93:   return(0);
 94: }

 98: PetscErrorCode MatAssemblyEnd_Preallocator(Mat A, MatAssemblyType type)
 99: {
100:   PetscScalar   *val;
101:   PetscInt      *row, *col;
102:   PetscInt       i, j, rstart, ncols, flg;
103:   PetscMPIInt    n;

107:   while (1) {
108:     MatStashScatterGetMesg_Private(&A->stash, &n, &row, &col, &val, &flg);
109:     if (!flg) break;

111:     for (i = 0; i < n; ) {
112:       /* Now identify the consecutive vals belonging to the same row */
113:       for (j = i, rstart = row[j]; j < n; j++) {
114:         if (row[j] != rstart) break;
115:       }
116:       if (j < n) ncols = j-i;
117:       else       ncols = n-i;
118:       /* Now assemble all these values with a single function call */
119:       MatSetValues_Preallocator(A, 1, row+i, ncols, col+i, val+i, INSERT_VALUES);
120:       i = j;
121:     }
122:   }
123:   MatStashScatterEnd_Private(&A->stash);
124:   return(0);
125: }

129: PetscErrorCode MatView_Preallocator(Mat A, PetscViewer viewer)
130: {
132:   return(0);
133: }

137: PetscErrorCode MatSetOption_Preallocator(Mat A, MatOption op, PetscBool flg)
138: {
140:   return(0);
141: }

145: PetscErrorCode MatPreallocatorPreallocate_Preallocator(Mat mat, PetscBool fill, Mat A)
146: {
147:   Mat_Preallocator *p = (Mat_Preallocator *) mat->data;
148:   PetscInt         *udnz = NULL, *uonz = NULL;
149:   PetscInt          bs;
150:   PetscErrorCode    ierr;

153:   MatGetBlockSize(mat, &bs);
154:   MatXAIJSetPreallocation(A, bs, p->dnz, p->onz, udnz, uonz);
155:   MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
156:   return(0);
157: }

161: /*@
162:   MatPreallocatorPreallocate - Preallocates the input matrix, optionally filling it with zeros

164:   Input Parameter:
165: + mat  - the preallocator
166: - fill - fill the matrix with zeros

168:   Output Parameter:
169: . A    - the matrix

171:   Level: advanced

173: .seealso: MATPREALLOCATOR
174: @*/
175: PetscErrorCode MatPreallocatorPreallocate(Mat mat, PetscBool fill, Mat A)
176: {

182:   PetscUseMethod(mat, "MatPreallocatorPreallocate_C", (Mat,PetscBool,Mat),(mat,fill,A));
183:   return(0);
184: }

186: /*MC
187:    MATPREALLOCATOR - MATPREALLOCATOR = "preallocator" - A matrix type to be used for computing a matrix preallocation.

189:    Operations Provided:
190: .  MatSetValues()

192:    Options Database Keys:
193: . -mat_type preallocator - sets the matrix type to "preallocator" during a call to MatSetFromOptions()

195:   Level: advanced

197: .seealso: Mat

199: M*/

203: PETSC_EXTERN PetscErrorCode MatCreate_Preallocator(Mat A)
204: {
205:   Mat_Preallocator *p;
206:   PetscErrorCode    ierr;

209:   PetscNewLog(A, &p);
210:   A->data = (void *) p;

212:   p->ht  = NULL;
213:   p->dnz = NULL;
214:   p->onz = NULL;

216:   /* matrix ops */
217:   PetscMemzero(A->ops, sizeof(struct _MatOps));
218:   A->ops->destroy                 = MatDestroy_Preallocator;
219:   A->ops->setup                   = MatSetUp_Preallocator;
220:   A->ops->setvalues               = MatSetValues_Preallocator;
221:   A->ops->assemblybegin           = MatAssemblyBegin_Preallocator;
222:   A->ops->assemblyend             = MatAssemblyEnd_Preallocator;
223:   A->ops->view                    = MatView_Preallocator;
224:   A->ops->setoption               = MatSetOption_Preallocator;

226:   /* special MATPREALLOCATOR functions */
227:   PetscObjectComposeFunction((PetscObject) A, "MatPreallocatorPreallocate_C", MatPreallocatorPreallocate_Preallocator);
228:   PetscObjectChangeTypeName((PetscObject) A, MATPREALLOCATOR);
229:   return(0);
230: }