xref: /petsc/src/mat/impls/sell/seq/sell.h (revision d4002b989b2d6051384fadc0d4465c98dea57b78)
1*d4002b98SHong Zhang 
2*d4002b98SHong Zhang #if !defined(__SELL_H)
3*d4002b98SHong Zhang #define __SELL_H
4*d4002b98SHong Zhang 
5*d4002b98SHong Zhang #include <petsc/private/matimpl.h>
6*d4002b98SHong Zhang #include <petscctable.h>
7*d4002b98SHong Zhang 
8*d4002b98SHong Zhang /*
9*d4002b98SHong Zhang  Struct header for SeqSELL matrix format
10*d4002b98SHong Zhang */
11*d4002b98SHong Zhang #define SEQSELLHEADER(datatype) \
12*d4002b98SHong Zhang PetscBool   roworiented;       /* if true, row-oriented input, default */ \
13*d4002b98SHong Zhang PetscInt    nonew;             /* 1 don't add new nonzeros, -1 generate error on new */ \
14*d4002b98SHong Zhang PetscInt    nounused;          /* -1 generate error on unused space */ \
15*d4002b98SHong Zhang PetscBool   singlemalloc;      /* if true a, i, and j have been obtained with one big malloc */ \
16*d4002b98SHong Zhang PetscInt    maxallocmat;       /* max allocated space for the matrix */ \
17*d4002b98SHong Zhang PetscInt    maxallocrow;       /* max allocated space for each row */ \
18*d4002b98SHong Zhang PetscInt    nz;                /* actual nonzeros */  \
19*d4002b98SHong Zhang PetscInt    rlenmax;           /* max actual row length, rmax cannot exceed maxallocrow */ \
20*d4002b98SHong Zhang PetscInt    *rlen;             /* actual length of each row (padding zeros excluded) */ \
21*d4002b98SHong Zhang PetscBool   free_rlen;         /* free rlen array ? */ \
22*d4002b98SHong Zhang PetscInt    reallocs;          /* number of mallocs done during MatSetValues() \
23*d4002b98SHong Zhang as more values are set than were prealloced */\
24*d4002b98SHong Zhang PetscBool   keepnonzeropattern;/* keeps matrix structure same in calls to MatZeroRows()*/ \
25*d4002b98SHong Zhang PetscBool   ignorezeroentries; \
26*d4002b98SHong Zhang PetscBool   free_colidx;       /* free the column indices colidx when the matrix is destroyed */ \
27*d4002b98SHong Zhang PetscBool   free_val;          /* free the numerical values when matrix is destroy */ \
28*d4002b98SHong Zhang PetscInt    *colidx;           /* column index */ \
29*d4002b98SHong Zhang PetscInt    *diag;             /* pointers to diagonal elements */ \
30*d4002b98SHong Zhang PetscInt    nonzerorowcnt;     /* how many rows have nonzero entries */ \
31*d4002b98SHong Zhang PetscBool   free_diag;         /* free diag ? */ \
32*d4002b98SHong Zhang datatype    *val;              /* elements including nonzeros and padding zeros */  \
33*d4002b98SHong Zhang PetscScalar *solve_work;       /* work space used in MatSolve */ \
34*d4002b98SHong Zhang IS          row, col, icol;    /* index sets, used for reorderings */ \
35*d4002b98SHong Zhang PetscBool   pivotinblocks;     /* pivot inside factorization of each diagonal block */ \
36*d4002b98SHong Zhang Mat         parent;            /* set if this matrix was formed with MatDuplicate(...,MAT_SHARE_NONZERO_PATTERN,....);
37*d4002b98SHong Zhang means that this shares some data structures with the parent including diag, ilen, imax, i, j */ \
38*d4002b98SHong Zhang PetscInt    *sliidx;           /* slice index */ \
39*d4002b98SHong Zhang PetscInt    totalslices;       /* total number of slices */ \
40*d4002b98SHong Zhang 
41*d4002b98SHong Zhang typedef struct {
42*d4002b98SHong Zhang   SEQSELLHEADER(MatScalar);
43*d4002b98SHong Zhang   MatScalar   *saved_values;             /* location for stashing nonzero values of matrix */
44*d4002b98SHong Zhang   PetscScalar *idiag,*mdiag,*ssor_work;  /* inverse of diagonal entries, diagonal values and workspace for Eisenstat trick */
45*d4002b98SHong Zhang   PetscBool   idiagvalid;                /* current idiag[] and mdiag[] are valid */
46*d4002b98SHong Zhang   PetscScalar *ibdiag;                   /* inverses of block diagonals */
47*d4002b98SHong Zhang   PetscBool   ibdiagvalid;               /* inverses of block diagonals are valid. */
48*d4002b98SHong Zhang   PetscScalar fshift,omega;              /* last used omega and fshift */
49*d4002b98SHong Zhang   ISColoring  coloring;                  /* set with MatADSetColoring() used by MatADSetValues() */
50*d4002b98SHong Zhang } Mat_SeqSELL;
51*d4002b98SHong Zhang 
52*d4002b98SHong Zhang /*
53*d4002b98SHong Zhang  Frees the arrays from the XSELLPACK matrix type
54*d4002b98SHong Zhang  */
55*d4002b98SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSeqXSELLFreeSELL(Mat AA,MatScalar **val,PetscInt **colidx)
56*d4002b98SHong Zhang {
57*d4002b98SHong Zhang   Mat_SeqSELL    *A = (Mat_SeqSELL*) AA->data;
58*d4002b98SHong Zhang   PetscErrorCode ierr;
59*d4002b98SHong Zhang   if (A->singlemalloc) {
60*d4002b98SHong Zhang     ierr = PetscFree2(*val,*colidx);CHKERRQ(ierr);
61*d4002b98SHong Zhang   } else {
62*d4002b98SHong Zhang     if (A->free_val) {ierr = PetscFree(*val);CHKERRQ(ierr);}
63*d4002b98SHong Zhang     if (A->free_colidx) {ierr = PetscFree(*colidx);CHKERRQ(ierr);}
64*d4002b98SHong Zhang   }
65*d4002b98SHong Zhang   return 0;
66*d4002b98SHong Zhang }
67*d4002b98SHong Zhang 
68*d4002b98SHong Zhang #define MatSeqXSELLReallocateSELL(Amat,AM,BS2,WIDTH,SIDX,SID,ROW,COL,COLIDX,VAL,CP,VP,NONEW,datatype) \
69*d4002b98SHong Zhang if (WIDTH >= (SIDX[SID+1]-SIDX[SID])/8) { \
70*d4002b98SHong Zhang Mat_SeqSELL *Ain = (Mat_SeqSELL*)Amat->data; \
71*d4002b98SHong Zhang /* there is no extra room in row, therefore enlarge 8 elements (1 slice column) */ \
72*d4002b98SHong Zhang PetscInt new_size=Ain->maxallocmat+8,*new_colidx; \
73*d4002b98SHong Zhang datatype *new_val; \
74*d4002b98SHong Zhang \
75*d4002b98SHong Zhang if (NONEW == -2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"New nonzero at (%D,%D) caused a malloc\nUse MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE) to turn off this check",ROW,COL); \
76*d4002b98SHong Zhang /* malloc new storage space */ \
77*d4002b98SHong Zhang ierr = PetscMalloc2(BS2*new_size,&new_val,BS2*new_size,&new_colidx);CHKERRQ(ierr); \
78*d4002b98SHong Zhang \
79*d4002b98SHong Zhang /* copy over old data into new slots by two steps: one step for data before the current slice and the other for the rest */ \
80*d4002b98SHong Zhang ierr = PetscMemcpy(new_val,VAL,SIDX[SID+1]*sizeof(datatype));CHKERRQ(ierr); \
81*d4002b98SHong Zhang ierr = PetscMemcpy(new_colidx,COLIDX,SIDX[SID+1]*sizeof(PetscInt));CHKERRQ(ierr); \
82*d4002b98SHong Zhang ierr = PetscMemcpy(new_val+SIDX[SID+1]+8,VAL+SIDX[SID+1],(SIDX[AM>>3]-SIDX[SID+1])*sizeof(datatype));CHKERRQ(ierr); \
83*d4002b98SHong Zhang ierr = PetscMemcpy(new_colidx+SIDX[SID+1]+8,COLIDX+SIDX[SID+1],(SIDX[AM>>3]-SIDX[SID+1])*sizeof(PetscInt));CHKERRQ(ierr); \
84*d4002b98SHong Zhang /* update slice_idx */ \
85*d4002b98SHong Zhang for (ii=SID+1;ii<=AM>>3;ii++) { SIDX[ii] += 8; } \
86*d4002b98SHong Zhang /* update pointers. Notice that they point to the FIRST postion of the row */ \
87*d4002b98SHong Zhang CP = new_colidx+SIDX[SID]+(ROW & 0x07); \
88*d4002b98SHong Zhang VP = new_val+SIDX[SID]+(ROW & 0x07); \
89*d4002b98SHong Zhang /* free up old matrix storage */ \
90*d4002b98SHong Zhang ierr              = MatSeqXSELLFreeSELL(A,&Ain->val,&Ain->colidx);CHKERRQ(ierr); \
91*d4002b98SHong Zhang Ain->val          = (MatScalar*) new_val; \
92*d4002b98SHong Zhang Ain->colidx       = new_colidx; \
93*d4002b98SHong Zhang Ain->singlemalloc = PETSC_TRUE; \
94*d4002b98SHong Zhang Ain->maxallocmat  = new_size; \
95*d4002b98SHong Zhang Ain->reallocs++; \
96*d4002b98SHong Zhang if (WIDTH>=Ain->maxallocrow) Ain->maxallocrow++; \
97*d4002b98SHong Zhang if (WIDTH>=Ain->rlenmax) Ain->rlenmax++; \
98*d4002b98SHong Zhang } \
99*d4002b98SHong Zhang 
100*d4002b98SHong Zhang #define MatSetValue_SeqSELL_Private(A,row,col,value,addv,orow,ocol,cp,vp,lastcol,low,high) \
101*d4002b98SHong Zhang { \
102*d4002b98SHong Zhang   Mat_SeqSELL  *a=(Mat_SeqSELL*)A->data; \
103*d4002b98SHong Zhang   found=PETSC_FALSE; \
104*d4002b98SHong Zhang   if (col <= lastcol) low = 0; \
105*d4002b98SHong Zhang   else high = a->rlen[row]; \
106*d4002b98SHong Zhang   lastcol = col; \
107*d4002b98SHong Zhang   while (high-low > 5) { \
108*d4002b98SHong Zhang     t = (low+high)/2; \
109*d4002b98SHong Zhang     if (*(cp+8*t) > col) high = t; \
110*d4002b98SHong Zhang     else low = t; \
111*d4002b98SHong Zhang   } \
112*d4002b98SHong Zhang   for (_i=low; _i<high; _i++) { \
113*d4002b98SHong Zhang     if (*(cp+8*_i) > col) break; \
114*d4002b98SHong Zhang     if (*(cp+8*_i) == col) { \
115*d4002b98SHong Zhang       if (addv == ADD_VALUES)*(vp+8*_i) += value; \
116*d4002b98SHong Zhang       else *(vp+8*_i) = value; \
117*d4002b98SHong Zhang       found = PETSC_TRUE; \
118*d4002b98SHong Zhang       break; \
119*d4002b98SHong Zhang     } \
120*d4002b98SHong Zhang   } \
121*d4002b98SHong Zhang   if (!found) { \
122*d4002b98SHong Zhang     if (a->nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at global row/column (%D, %D) into matrix", orow, ocol); \
123*d4002b98SHong Zhang     if (a->nonew != 1 && !(value == 0.0 && a->ignorezeroentries) && a->rlen[row] >= (a->sliidx[row/8+1]-a->sliidx[row/8])/8) { \
124*d4002b98SHong Zhang       /* there is no extra room in row, therefore enlarge 8 elements (1 slice column) */ \
125*d4002b98SHong Zhang       if (a->maxallocmat < a->sliidx[a->totalslices]+8) { \
126*d4002b98SHong Zhang         /* allocates a larger array for the XSELL matrix types; only extend the current slice by one more column. */ \
127*d4002b98SHong Zhang         PetscInt  new_size=a->maxallocmat+8,*new_colidx; \
128*d4002b98SHong Zhang         MatScalar *new_val; \
129*d4002b98SHong Zhang         if (a->nonew == -2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"New nonzero at (%D,%D) caused a malloc\nUse MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE) to turn off this check",orow,ocol); \
130*d4002b98SHong Zhang         /* malloc new storage space */ \
131*d4002b98SHong Zhang         ierr = PetscMalloc2(new_size,&new_val,new_size,&new_colidx);CHKERRQ(ierr); \
132*d4002b98SHong Zhang         /* copy over old data into new slots by two steps: one step for data before the current slice and the other for the rest */ \
133*d4002b98SHong Zhang         ierr = PetscMemcpy(new_val,a->val,a->sliidx[row/8+1]*sizeof(MatScalar));CHKERRQ(ierr); \
134*d4002b98SHong Zhang         ierr = PetscMemcpy(new_colidx,a->colidx,a->sliidx[row/8+1]*sizeof(PetscInt));CHKERRQ(ierr); \
135*d4002b98SHong Zhang         ierr = PetscMemcpy(new_val+a->sliidx[row/8+1]+8,a->val+a->sliidx[row/8+1],(a->sliidx[a->totalslices]-a->sliidx[row/8+1])*sizeof(MatScalar));CHKERRQ(ierr);  \
136*d4002b98SHong Zhang         ierr = PetscMemcpy(new_colidx+a->sliidx[row/8+1]+8,a->colidx+a->sliidx[row/8+1],(a->sliidx[a->totalslices]-a->sliidx[row/8+1])*sizeof(PetscInt));CHKERRQ(ierr); \
137*d4002b98SHong Zhang         /* update pointers. Notice that they point to the FIRST postion of the row */ \
138*d4002b98SHong Zhang         cp = new_colidx+a->sliidx[row/8]+(row & 0x07); \
139*d4002b98SHong Zhang         vp = new_val+a->sliidx[row/8]+(row & 0x07); \
140*d4002b98SHong Zhang         /* free up old matrix storage */ \
141*d4002b98SHong Zhang         ierr            = MatSeqXSELLFreeSELL(A,&a->val,&a->colidx);CHKERRQ(ierr); \
142*d4002b98SHong Zhang         a->val          = (MatScalar*)new_val; \
143*d4002b98SHong Zhang         a->colidx       = new_colidx; \
144*d4002b98SHong Zhang         a->singlemalloc = PETSC_TRUE; \
145*d4002b98SHong Zhang         a->maxallocmat  = new_size; \
146*d4002b98SHong Zhang         a->reallocs++; \
147*d4002b98SHong Zhang       } else { \
148*d4002b98SHong Zhang         /* no need to reallocate, just shift the following slices to create space for the added slice column */ \
149*d4002b98SHong Zhang         ierr = PetscMemmove(a->val+a->sliidx[row/8+1]+8,a->val+a->sliidx[row/8+1],(a->sliidx[a->totalslices]-a->sliidx[row/8+1])*sizeof(MatScalar));CHKERRQ(ierr);  \
150*d4002b98SHong Zhang         ierr = PetscMemmove(a->colidx+a->sliidx[row/8+1]+8,a->colidx+a->sliidx[row/8+1],(a->sliidx[a->totalslices]-a->sliidx[row/8+1])*sizeof(PetscInt));CHKERRQ(ierr); \
151*d4002b98SHong Zhang       } \
152*d4002b98SHong Zhang       /* update slice_idx */ \
153*d4002b98SHong Zhang       for (ii=row/8+1;ii<=a->totalslices;ii++) a->sliidx[ii] += 8; \
154*d4002b98SHong Zhang       if (a->rlen[row]>=a->maxallocrow) a->maxallocrow++; \
155*d4002b98SHong Zhang       if (a->rlen[row]>=a->rlenmax) a->rlenmax++; \
156*d4002b98SHong Zhang     } \
157*d4002b98SHong Zhang     /* shift up all the later entries in this row */ \
158*d4002b98SHong Zhang     for (ii=a->rlen[row]-1; ii>=_i; ii--) { \
159*d4002b98SHong Zhang       *(cp+8*(ii+1)) = *(cp+8*ii); \
160*d4002b98SHong Zhang       *(vp+8*(ii+1)) = *(vp+8*ii); \
161*d4002b98SHong Zhang     } \
162*d4002b98SHong Zhang     *(cp+8*_i) = col; \
163*d4002b98SHong Zhang     *(vp+8*_i) = value; \
164*d4002b98SHong Zhang     a->nz++; a->rlen[row]++; A->nonzerostate++; \
165*d4002b98SHong Zhang     low = _i+1; high++; \
166*d4002b98SHong Zhang   } \
167*d4002b98SHong Zhang } \
168*d4002b98SHong Zhang 
169*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSeqSELLSetPreallocation_SeqSELL(Mat,PetscInt,const PetscInt[]);
170*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatMult_SeqSELL(Mat,Vec,Vec);
171*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatMultAdd_SeqSELL(Mat,Vec,Vec,Vec);
172*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatMultTranspose_SeqSELL(Mat,Vec,Vec);
173*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatMultTransposeAdd_SeqSELL(Mat,Vec,Vec,Vec);
174*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatMissingDiagonal_SeqSELL(Mat,PetscBool*,PetscInt*);
175*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatMarkDiagonal_SeqSELL(Mat);
176*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatInvertDiagonal_SeqSELL(Mat,PetscScalar,PetscScalar);
177*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatZeroEntries_SeqSELL(Mat);
178*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatDestroy_SeqSELL(Mat);
179*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSetOption_SeqSELL(Mat,MatOption,PetscBool);
180*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatGetDiagonal_SeqSELL(Mat,Vec v);
181*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatGetValues_SeqSELL(Mat,PetscInt,const PetscInt [],PetscInt,const PetscInt[],PetscScalar[]);
182*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatView_SeqSELL(Mat,PetscViewer);
183*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatAssemblyEnd_SeqSELL(Mat,MatAssemblyType);
184*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatGetInfo_SeqSELL(Mat,MatInfoType,MatInfo*);
185*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSetValues_SeqSELL(Mat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],InsertMode);
186*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatCopy_SeqSELL(Mat,Mat,MatStructure);
187*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSetUp_SeqSELL(Mat);
188*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSeqSELLGetArray_SeqSELL(Mat,PetscScalar *[]);
189*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSeqSELLRestoreArray_SeqSELL(Mat,PetscScalar *[]);
190*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatShift_SeqSELL(Mat,PetscScalar);
191*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSOR_SeqSELL(Mat,Vec,PetscReal,MatSORType,PetscReal,PetscInt,PetscInt,Vec);
192*d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatCreate_SeqSELL(Mat);
193*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatDuplicate_SeqSELL(Mat,MatDuplicateOption,Mat*);
194*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatEqual_SeqSELL(Mat,Mat,PetscBool*);
195*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatSeqSELLInvalidateDiagonal(Mat);
196*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqSELL_SeqAIJ(Mat,MatType,MatReuse,Mat*);
197*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*);
198*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatFDColoringCreate_SeqSELL(Mat,ISColoring,MatFDColoring);
199*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatFDColoringSetUp_SeqSELL(Mat,ISColoring,MatFDColoring);
200*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatGetColumnIJ_SeqSELL_Color(Mat,PetscInt,PetscBool,PetscBool,PetscInt*,const PetscInt *[],const PetscInt *[],PetscInt *[],PetscBool*);
201*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatRestoreColumnIJ_SeqSELL_Color(Mat,PetscInt,PetscBool,PetscBool,PetscInt*,const PetscInt *[],const PetscInt *[],PetscInt *[],PetscBool*);
202*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatConjugate_SeqSELL(Mat A);
203*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatScale_SeqSELL(Mat,PetscScalar);
204*d4002b98SHong Zhang PETSC_INTERN PetscErrorCode MatDiagonalScale_SeqSELL(Mat,Vec,Vec);
205*d4002b98SHong Zhang #endif
206