xref: /petsc/src/mat/impls/preallocator/matpreallocator.c (revision c094ef4021e955ef5f85f7d8a1bbc6ed64ba7621)
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