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