xref: /petsc/src/mat/utils/compressedrow.c (revision 7c4f633dc6bb6149cca88d301ead35a99e103cbb)
1 #define PETSCMAT_DLL
2 
3 #include "private/matimpl.h"  /*I   "petscmat.h"  I*/
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "Mat_CheckCompressedRow"
7 /*@C
8    Mat_CheckCompressedRow - Determines whether the compressed row matrix format should be used.
9       If the format is to be used, this routine creates Mat_CompressedRow struct.
10       Compressed row format provides high performance routines by taking advantage of zero rows.
11       Supported types are MATAIJ, MATBAIJ and MATSBAIJ.
12 
13    Collective
14 
15    Input Parameters:
16 +  A             - the matrix
17 .  compressedrow - pointer to the struct Mat_CompressedRow
18 .  ai            - row pointer used by seqaij and seqbaij
19 .  mbs           - number of (block) rows represented by ai
20 -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
21 
22    Level: developer
23 @*/
24 PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio)
25 {
26   PetscErrorCode ierr;
27   PetscInt       nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row;
28 
29   PetscFunctionBegin;
30   if (!compressedrow->use) PetscFunctionReturn(0);
31   if (compressedrow->checked){
32     if (!A->same_nonzero){
33       ierr = PetscFree(compressedrow->i);CHKERRQ(ierr);
34       compressedrow->rindex = PETSC_NULL;
35       ierr = PetscInfo(A,"Mat structure might be changed. Free memory and recheck.\n");CHKERRQ(ierr);
36     } else if (!compressedrow->i) {
37       /* Don't know why this occures. For safe, recheck. */
38       ierr = PetscInfo(A,"compressedrow.checked, but compressedrow.i==null. Recheck.\n");CHKERRQ(ierr);
39     } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */
40       ierr = PetscInfo7(A,"Skip check. m: %d, n: %d,M: %d, N: %d,nrows: %d, ii: %p, type: %s\n",A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,compressedrow->nrows,compressedrow->i,((PetscObject)A)->type_name);CHKERRQ(ierr);
41       PetscFunctionReturn(0);
42     }
43   }
44   compressedrow->checked = PETSC_TRUE;
45 
46   /* compute number of zero rows */
47   nrows = 0;
48   for (i=0; i<mbs; i++){        /* for each row */
49     nz = ai[i+1] - ai[i];       /* number of nonzeros */
50     if (nz == 0) nrows++;
51   }
52   /* if a large number of zero rows is found, use compressedrow data structure */
53   if (nrows < ratio*mbs) {
54     compressedrow->use = PETSC_FALSE;
55     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) < %G. Do not use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
56   } else {
57     compressedrow->use = PETSC_TRUE;
58     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) > %G. Use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
59 
60     /* set compressed row format */
61     nrows = mbs - nrows; /* num of non-zero rows */
62     ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr);
63     ridx = cpi + nrows + 1;
64     row    = 0;
65     cpi[0] = 0;
66     for (i=0; i<mbs; i++){
67       nz = ai[i+1] - ai[i];
68       if (nz == 0) continue;
69       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
70       ridx[row++] = i;          /* compressed row local index */
71     }
72     compressedrow->nrows  = nrows;
73     compressedrow->i      = cpi;
74     compressedrow->rindex = ridx;
75   }
76 
77   PetscFunctionReturn(0);
78 }
79