1 2 /* 3 Defines symbolic transpose routines for SeqAIJ matrices. 4 5 Currently Get/Restore only allocates/frees memory for holding the 6 (i,j) info for the transpose. Someday, this info could be 7 maintained so successive calls to Get will not recompute the info. 8 9 Also defined is a "faster" implementation of MatTranspose for SeqAIJ 10 matrices which avoids calls to MatSetValues. This routine has not 11 been adopted as the standard yet as it is somewhat untested. 12 13 */ 14 15 #include <../src/mat/impls/aij/seq/aij.h> 16 17 18 PetscErrorCode MatGetSymbolicTranspose_SeqAIJ(Mat A,PetscInt *Ati[],PetscInt *Atj[]) 19 { 20 PetscErrorCode ierr; 21 PetscInt i,j,anzj; 22 Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 23 PetscInt an=A->cmap->N,am=A->rmap->N; 24 PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 25 26 PetscFunctionBegin; 27 ierr = PetscInfo(A,"Getting Symbolic Transpose.\n");CHKERRQ(ierr); 28 29 /* Set up timers */ 30 ierr = PetscLogEventBegin(MAT_Getsymtranspose,A,0,0,0);CHKERRQ(ierr); 31 32 /* Allocate space for symbolic transpose info and work array */ 33 ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 34 ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 35 ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 36 37 /* Walk through aj and count ## of non-zeros in each row of A^T. */ 38 /* Note: offset by 1 for fast conversion into csr format. */ 39 for (i=0;i<ai[am];i++) { 40 ati[aj[i]+1] += 1; 41 } 42 /* Form ati for csr format of A^T. */ 43 for (i=0;i<an;i++) { 44 ati[i+1] += ati[i]; 45 } 46 47 /* Copy ati into atfill so we have locations of the next free space in atj */ 48 ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 49 50 /* Walk through A row-wise and mark nonzero entries of A^T. */ 51 for (i=0; i<am; i++) { 52 anzj = ai[i+1] - ai[i]; 53 for (j=0; j<anzj; j++) { 54 atj[atfill[*aj]] = i; 55 atfill[*aj++] += 1; 56 } 57 } 58 59 /* Clean up temporary space and complete requests. */ 60 ierr = PetscFree(atfill);CHKERRQ(ierr); 61 *Ati = ati; 62 *Atj = atj; 63 64 ierr = PetscLogEventEnd(MAT_Getsymtranspose,A,0,0,0);CHKERRQ(ierr); 65 PetscFunctionReturn(0); 66 } 67 /* 68 MatGetSymbolicTransposeReduced_SeqAIJ() - Get symbolic matrix structure of submatrix A[rstart:rend,:], 69 modified from MatGetSymbolicTranspose_SeqAIJ() 70 */ 71 PetscErrorCode MatGetSymbolicTransposeReduced_SeqAIJ(Mat A,PetscInt rstart,PetscInt rend,PetscInt *Ati[],PetscInt *Atj[]) 72 { 73 PetscErrorCode ierr; 74 PetscInt i,j,anzj; 75 Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 76 PetscInt an=A->cmap->N; 77 PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 78 79 PetscFunctionBegin; 80 ierr = PetscInfo(A,"Getting Symbolic Transpose\n");CHKERRQ(ierr); 81 ierr = PetscLogEventBegin(MAT_Getsymtransreduced,A,0,0,0);CHKERRQ(ierr); 82 83 /* Allocate space for symbolic transpose info and work array */ 84 ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 85 anzj = ai[rend] - ai[rstart]; 86 ierr = PetscMalloc1(anzj+1,&atj);CHKERRQ(ierr); 87 ierr = PetscMalloc1(an+1,&atfill);CHKERRQ(ierr); 88 89 /* Walk through aj and count ## of non-zeros in each row of A^T. */ 90 /* Note: offset by 1 for fast conversion into csr format. */ 91 for (i=ai[rstart]; i<ai[rend]; i++) { 92 ati[aj[i]+1] += 1; 93 } 94 /* Form ati for csr format of A^T. */ 95 for (i=0;i<an;i++) { 96 ati[i+1] += ati[i]; 97 } 98 99 /* Copy ati into atfill so we have locations of the next free space in atj */ 100 ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 101 102 /* Walk through A row-wise and mark nonzero entries of A^T. */ 103 aj = aj + ai[rstart]; 104 for (i=rstart; i<rend; i++) { 105 anzj = ai[i+1] - ai[i]; 106 for (j=0; j<anzj; j++) { 107 atj[atfill[*aj]] = i-rstart; 108 atfill[*aj++] += 1; 109 } 110 } 111 112 /* Clean up temporary space and complete requests. */ 113 ierr = PetscFree(atfill);CHKERRQ(ierr); 114 *Ati = ati; 115 *Atj = atj; 116 117 ierr = PetscLogEventEnd(MAT_Getsymtransreduced,A,0,0,0);CHKERRQ(ierr); 118 PetscFunctionReturn(0); 119 } 120 121 PetscErrorCode MatTranspose_SeqAIJ_FAST(Mat A,MatReuse reuse,Mat *B) 122 { 123 PetscErrorCode ierr; 124 PetscInt i,j,anzj; 125 Mat At; 126 Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*at; 127 PetscInt an=A->cmap->N,am=A->rmap->N; 128 PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 129 MatScalar *ata,*aa=a->a; 130 131 PetscFunctionBegin; 132 ierr = PetscLogEventBegin(MAT_Transpose_SeqAIJ,A,0,0,0);CHKERRQ(ierr); 133 134 if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 135 /* Allocate space for symbolic transpose info and work array */ 136 ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 137 ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 138 ierr = PetscMalloc1(ai[am],&ata);CHKERRQ(ierr); 139 /* Walk through aj and count ## of non-zeros in each row of A^T. */ 140 /* Note: offset by 1 for fast conversion into csr format. */ 141 for (i=0;i<ai[am];i++) { 142 ati[aj[i]+1] += 1; 143 } 144 /* Form ati for csr format of A^T. */ 145 for (i=0;i<an;i++) { 146 ati[i+1] += ati[i]; 147 } 148 } else { 149 Mat_SeqAIJ *sub_B = (Mat_SeqAIJ*) (*B)->data; 150 ati = sub_B->i; 151 atj = sub_B->j; 152 ata = sub_B->a; 153 At = *B; 154 } 155 156 /* Copy ati into atfill so we have locations of the next free space in atj */ 157 ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 158 ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 159 160 /* Walk through A row-wise and mark nonzero entries of A^T. */ 161 for (i=0;i<am;i++) { 162 anzj = ai[i+1] - ai[i]; 163 for (j=0;j<anzj;j++) { 164 atj[atfill[*aj]] = i; 165 ata[atfill[*aj]] = *aa++; 166 atfill[*aj++] += 1; 167 } 168 } 169 170 /* Clean up temporary space and complete requests. */ 171 ierr = PetscFree(atfill);CHKERRQ(ierr); 172 if (reuse == MAT_INITIAL_MATRIX) { 173 ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,ata,&At);CHKERRQ(ierr); 174 175 at = (Mat_SeqAIJ*)(At->data); 176 at->free_a = PETSC_TRUE; 177 at->free_ij = PETSC_TRUE; 178 at->nonew = 0; 179 } 180 181 if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 182 *B = At; 183 } else { 184 ierr = MatHeaderMerge(A,&At);CHKERRQ(ierr); 185 } 186 ierr = PetscLogEventEnd(MAT_Transpose_SeqAIJ,A,0,0,0);CHKERRQ(ierr); 187 PetscFunctionReturn(0); 188 } 189 190 PetscErrorCode MatRestoreSymbolicTranspose_SeqAIJ(Mat A,PetscInt *ati[],PetscInt *atj[]) 191 { 192 PetscErrorCode ierr; 193 194 PetscFunctionBegin; 195 ierr = PetscInfo(A,"Restoring Symbolic Transpose.\n");CHKERRQ(ierr); 196 ierr = PetscFree(*ati);CHKERRQ(ierr); 197 ierr = PetscFree(*atj);CHKERRQ(ierr); 198 PetscFunctionReturn(0); 199 } 200 201