1c094ef40SMatthew G. Knepley #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 2*e8f14785SLisandro Dalcin #include <petsc/private/hashsetij.h> 3c094ef40SMatthew G. Knepley 4c094ef40SMatthew G. Knepley typedef struct { 5*e8f14785SLisandro Dalcin PetscHSetIJ ht; 6c094ef40SMatthew G. Knepley PetscInt *dnz, *onz; 7c094ef40SMatthew G. Knepley } Mat_Preallocator; 8c094ef40SMatthew G. Knepley 9c094ef40SMatthew G. Knepley PetscErrorCode MatDestroy_Preallocator(Mat A) 10c094ef40SMatthew G. Knepley { 11c094ef40SMatthew G. Knepley Mat_Preallocator *p = (Mat_Preallocator *) A->data; 12c094ef40SMatthew G. Knepley PetscErrorCode ierr; 13c094ef40SMatthew G. Knepley 14c094ef40SMatthew G. Knepley PetscFunctionBegin; 15c094ef40SMatthew G. Knepley ierr = MatStashDestroy_Private(&A->stash);CHKERRQ(ierr); 16*e8f14785SLisandro Dalcin ierr = PetscHSetIJDestroy(&p->ht);CHKERRQ(ierr); 17c094ef40SMatthew G. Knepley ierr = PetscFree2(p->dnz, p->onz);CHKERRQ(ierr); 18c094ef40SMatthew G. Knepley ierr = PetscFree(A->data);CHKERRQ(ierr); 19c094ef40SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) A, 0);CHKERRQ(ierr); 20c094ef40SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) A, "MatPreallocatorPreallocate_C", NULL);CHKERRQ(ierr); 21c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 22c094ef40SMatthew G. Knepley } 23c094ef40SMatthew G. Knepley 24c094ef40SMatthew G. Knepley PetscErrorCode MatSetUp_Preallocator(Mat A) 25c094ef40SMatthew G. Knepley { 26c094ef40SMatthew G. Knepley Mat_Preallocator *p = (Mat_Preallocator *) A->data; 27c094ef40SMatthew G. Knepley PetscInt m, bs; 28c094ef40SMatthew G. Knepley PetscErrorCode ierr; 29c094ef40SMatthew G. Knepley 30c094ef40SMatthew G. Knepley PetscFunctionBegin; 31c094ef40SMatthew G. Knepley ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 32c094ef40SMatthew G. Knepley ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 33c094ef40SMatthew G. Knepley ierr = MatGetLocalSize(A, &m, NULL);CHKERRQ(ierr); 34*e8f14785SLisandro Dalcin ierr = PetscHSetIJCreate(&p->ht);CHKERRQ(ierr); 35c094ef40SMatthew G. Knepley ierr = MatGetBlockSize(A, &bs);CHKERRQ(ierr); 36c094ef40SMatthew G. Knepley ierr = MatStashCreate_Private(PetscObjectComm((PetscObject) A), bs, &A->stash);CHKERRQ(ierr); 37c094ef40SMatthew G. Knepley ierr = PetscCalloc2(m, &p->dnz, m, &p->onz);CHKERRQ(ierr); 38c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 39c094ef40SMatthew G. Knepley } 40c094ef40SMatthew G. Knepley 41c094ef40SMatthew G. Knepley PetscErrorCode MatSetValues_Preallocator(Mat A, PetscInt m, const PetscInt *rows, PetscInt n, const PetscInt *cols, const PetscScalar *values, InsertMode addv) 42c094ef40SMatthew G. Knepley { 43c094ef40SMatthew G. Knepley Mat_Preallocator *p = (Mat_Preallocator *) A->data; 44c094ef40SMatthew G. Knepley PetscInt rStart, rEnd, r, cStart, cEnd, c; 45c094ef40SMatthew G. Knepley PetscErrorCode ierr; 46c094ef40SMatthew G. Knepley 47c094ef40SMatthew G. Knepley PetscFunctionBegin; 48c094ef40SMatthew G. Knepley /* TODO: Handle blocksize */ 49c094ef40SMatthew G. Knepley ierr = MatGetOwnershipRange(A, &rStart, &rEnd);CHKERRQ(ierr); 50c094ef40SMatthew G. Knepley ierr = MatGetOwnershipRangeColumn(A, &cStart, &cEnd);CHKERRQ(ierr); 51c094ef40SMatthew G. Knepley for (r = 0; r < m; ++r) { 52*e8f14785SLisandro Dalcin PetscHashIJKey key; 53*e8f14785SLisandro Dalcin PetscBool missing; 54c094ef40SMatthew G. Knepley 55*e8f14785SLisandro Dalcin key.i = rows[r]; 56*e8f14785SLisandro Dalcin if (key.i < 0) continue; 57*e8f14785SLisandro Dalcin if ((key.i < rStart) || (key.i >= rEnd)) { 58*e8f14785SLisandro Dalcin ierr = MatStashValuesRow_Private(&A->stash, key.i, n, cols, values, PETSC_FALSE);CHKERRQ(ierr); 59c094ef40SMatthew G. Knepley } else { 60c094ef40SMatthew G. Knepley for (c = 0; c < n; ++c) { 61*e8f14785SLisandro Dalcin key.j = cols[c]; 62*e8f14785SLisandro Dalcin if (key.j < 0) continue; 63*e8f14785SLisandro Dalcin ierr = PetscHSetIJQueryAdd(p->ht, key, &missing);CHKERRQ(ierr); 64c094ef40SMatthew G. Knepley if (missing) { 65*e8f14785SLisandro Dalcin if ((key.j >= cStart) && (key.j < cEnd)) ++p->dnz[key.i-rStart]; 66*e8f14785SLisandro Dalcin else ++p->onz[key.i-rStart]; 67c094ef40SMatthew G. Knepley } 68c094ef40SMatthew G. Knepley } 69c094ef40SMatthew G. Knepley } 70c094ef40SMatthew G. Knepley } 71c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 72c094ef40SMatthew G. Knepley } 73c094ef40SMatthew G. Knepley 74c094ef40SMatthew G. Knepley PetscErrorCode MatAssemblyBegin_Preallocator(Mat A, MatAssemblyType type) 75c094ef40SMatthew G. Knepley { 76c094ef40SMatthew G. Knepley PetscInt nstash, reallocs; 77c094ef40SMatthew G. Knepley PetscErrorCode ierr; 78c094ef40SMatthew G. Knepley 79c094ef40SMatthew G. Knepley PetscFunctionBegin; 80c094ef40SMatthew G. Knepley ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 81c094ef40SMatthew G. Knepley ierr = MatStashScatterBegin_Private(A, &A->stash, A->rmap->range);CHKERRQ(ierr); 82c094ef40SMatthew G. Knepley ierr = MatStashGetInfo_Private(&A->stash, &nstash, &reallocs);CHKERRQ(ierr); 83c094ef40SMatthew G. Knepley ierr = PetscInfo2(A, "Stash has %D entries, uses %D mallocs.\n", nstash, reallocs);CHKERRQ(ierr); 84c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 85c094ef40SMatthew G. Knepley } 86c094ef40SMatthew G. Knepley 87c094ef40SMatthew G. Knepley PetscErrorCode MatAssemblyEnd_Preallocator(Mat A, MatAssemblyType type) 88c094ef40SMatthew G. Knepley { 89c094ef40SMatthew G. Knepley PetscScalar *val; 90c094ef40SMatthew G. Knepley PetscInt *row, *col; 91c094ef40SMatthew G. Knepley PetscInt i, j, rstart, ncols, flg; 92c094ef40SMatthew G. Knepley PetscMPIInt n; 93c094ef40SMatthew G. Knepley PetscErrorCode ierr; 94c094ef40SMatthew G. Knepley 95c094ef40SMatthew G. Knepley PetscFunctionBegin; 96c094ef40SMatthew G. Knepley while (1) { 97c094ef40SMatthew G. Knepley ierr = MatStashScatterGetMesg_Private(&A->stash, &n, &row, &col, &val, &flg);CHKERRQ(ierr); 98c094ef40SMatthew G. Knepley if (!flg) break; 99c094ef40SMatthew G. Knepley 100c094ef40SMatthew G. Knepley for (i = 0; i < n; ) { 101c094ef40SMatthew G. Knepley /* Now identify the consecutive vals belonging to the same row */ 102c094ef40SMatthew G. Knepley for (j = i, rstart = row[j]; j < n; j++) { 103c094ef40SMatthew G. Knepley if (row[j] != rstart) break; 104c094ef40SMatthew G. Knepley } 105c094ef40SMatthew G. Knepley if (j < n) ncols = j-i; 106c094ef40SMatthew G. Knepley else ncols = n-i; 107c094ef40SMatthew G. Knepley /* Now assemble all these values with a single function call */ 108c094ef40SMatthew G. Knepley ierr = MatSetValues_Preallocator(A, 1, row+i, ncols, col+i, val+i, INSERT_VALUES);CHKERRQ(ierr); 109c094ef40SMatthew G. Knepley i = j; 110c094ef40SMatthew G. Knepley } 111c094ef40SMatthew G. Knepley } 112c094ef40SMatthew G. Knepley ierr = MatStashScatterEnd_Private(&A->stash);CHKERRQ(ierr); 113c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 114c094ef40SMatthew G. Knepley } 115c094ef40SMatthew G. Knepley 116c094ef40SMatthew G. Knepley PetscErrorCode MatView_Preallocator(Mat A, PetscViewer viewer) 117c094ef40SMatthew G. Knepley { 118c094ef40SMatthew G. Knepley PetscFunctionBegin; 119c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 120c094ef40SMatthew G. Knepley } 121c094ef40SMatthew G. Knepley 122c094ef40SMatthew G. Knepley PetscErrorCode MatSetOption_Preallocator(Mat A, MatOption op, PetscBool flg) 123c094ef40SMatthew G. Knepley { 124c094ef40SMatthew G. Knepley PetscFunctionBegin; 125c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 126c094ef40SMatthew G. Knepley } 127c094ef40SMatthew G. Knepley 128c094ef40SMatthew G. Knepley PetscErrorCode MatPreallocatorPreallocate_Preallocator(Mat mat, PetscBool fill, Mat A) 129c094ef40SMatthew G. Knepley { 130c094ef40SMatthew G. Knepley Mat_Preallocator *p = (Mat_Preallocator *) mat->data; 131c094ef40SMatthew G. Knepley PetscInt *udnz = NULL, *uonz = NULL; 132c094ef40SMatthew G. Knepley PetscInt bs; 133c094ef40SMatthew G. Knepley PetscErrorCode ierr; 134c094ef40SMatthew G. Knepley 135c094ef40SMatthew G. Knepley PetscFunctionBegin; 136c094ef40SMatthew G. Knepley ierr = MatGetBlockSize(mat, &bs);CHKERRQ(ierr); 137c094ef40SMatthew G. Knepley ierr = MatXAIJSetPreallocation(A, bs, p->dnz, p->onz, udnz, uonz);CHKERRQ(ierr); 138c094ef40SMatthew G. Knepley ierr = MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 139c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 140c094ef40SMatthew G. Knepley } 141c094ef40SMatthew G. Knepley 142c094ef40SMatthew G. Knepley /*@ 143c094ef40SMatthew G. Knepley MatPreallocatorPreallocate - Preallocates the input matrix, optionally filling it with zeros 144c094ef40SMatthew G. Knepley 145c094ef40SMatthew G. Knepley Input Parameter: 146c094ef40SMatthew G. Knepley + mat - the preallocator 147c094ef40SMatthew G. Knepley - fill - fill the matrix with zeros 148c094ef40SMatthew G. Knepley 149c094ef40SMatthew G. Knepley Output Parameter: 150c094ef40SMatthew G. Knepley . A - the matrix 151c094ef40SMatthew G. Knepley 152c094ef40SMatthew G. Knepley Level: advanced 153c094ef40SMatthew G. Knepley 154c094ef40SMatthew G. Knepley .seealso: MATPREALLOCATOR 155c094ef40SMatthew G. Knepley @*/ 156c094ef40SMatthew G. Knepley PetscErrorCode MatPreallocatorPreallocate(Mat mat, PetscBool fill, Mat A) 157c094ef40SMatthew G. Knepley { 158c094ef40SMatthew G. Knepley PetscErrorCode ierr; 159c094ef40SMatthew G. Knepley 160c094ef40SMatthew G. Knepley PetscFunctionBegin; 161c094ef40SMatthew G. Knepley PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 162c094ef40SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 3); 163c094ef40SMatthew G. Knepley ierr = PetscUseMethod(mat, "MatPreallocatorPreallocate_C", (Mat,PetscBool,Mat),(mat,fill,A));CHKERRQ(ierr); 164c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 165c094ef40SMatthew G. Knepley } 166c094ef40SMatthew G. Knepley 167c094ef40SMatthew G. Knepley /*MC 168c094ef40SMatthew G. Knepley MATPREALLOCATOR - MATPREALLOCATOR = "preallocator" - A matrix type to be used for computing a matrix preallocation. 169c094ef40SMatthew G. Knepley 170c094ef40SMatthew G. Knepley Operations Provided: 171c094ef40SMatthew G. Knepley . MatSetValues() 172c094ef40SMatthew G. Knepley 173c094ef40SMatthew G. Knepley Options Database Keys: 174c094ef40SMatthew G. Knepley . -mat_type preallocator - sets the matrix type to "preallocator" during a call to MatSetFromOptions() 175c094ef40SMatthew G. Knepley 176c094ef40SMatthew G. Knepley Level: advanced 177c094ef40SMatthew G. Knepley 178c094ef40SMatthew G. Knepley .seealso: Mat 179c094ef40SMatthew G. Knepley 180c094ef40SMatthew G. Knepley M*/ 181c094ef40SMatthew G. Knepley 182c094ef40SMatthew G. Knepley PETSC_EXTERN PetscErrorCode MatCreate_Preallocator(Mat A) 183c094ef40SMatthew G. Knepley { 184c094ef40SMatthew G. Knepley Mat_Preallocator *p; 185c094ef40SMatthew G. Knepley PetscErrorCode ierr; 186c094ef40SMatthew G. Knepley 187c094ef40SMatthew G. Knepley PetscFunctionBegin; 188c094ef40SMatthew G. Knepley ierr = PetscNewLog(A, &p);CHKERRQ(ierr); 189c094ef40SMatthew G. Knepley A->data = (void *) p; 190c094ef40SMatthew G. Knepley 191c094ef40SMatthew G. Knepley p->ht = NULL; 192c094ef40SMatthew G. Knepley p->dnz = NULL; 193c094ef40SMatthew G. Knepley p->onz = NULL; 194c094ef40SMatthew G. Knepley 195c094ef40SMatthew G. Knepley /* matrix ops */ 196c094ef40SMatthew G. Knepley ierr = PetscMemzero(A->ops, sizeof(struct _MatOps));CHKERRQ(ierr); 197c094ef40SMatthew G. Knepley A->ops->destroy = MatDestroy_Preallocator; 198c094ef40SMatthew G. Knepley A->ops->setup = MatSetUp_Preallocator; 199c094ef40SMatthew G. Knepley A->ops->setvalues = MatSetValues_Preallocator; 200c094ef40SMatthew G. Knepley A->ops->assemblybegin = MatAssemblyBegin_Preallocator; 201c094ef40SMatthew G. Knepley A->ops->assemblyend = MatAssemblyEnd_Preallocator; 202c094ef40SMatthew G. Knepley A->ops->view = MatView_Preallocator; 203c094ef40SMatthew G. Knepley A->ops->setoption = MatSetOption_Preallocator; 204c094ef40SMatthew G. Knepley 205c094ef40SMatthew G. Knepley /* special MATPREALLOCATOR functions */ 206c094ef40SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) A, "MatPreallocatorPreallocate_C", MatPreallocatorPreallocate_Preallocator);CHKERRQ(ierr); 207c094ef40SMatthew G. Knepley ierr = PetscObjectChangeTypeName((PetscObject) A, MATPREALLOCATOR);CHKERRQ(ierr); 208c094ef40SMatthew G. Knepley PetscFunctionReturn(0); 209c094ef40SMatthew G. Knepley } 210