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