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