Actual source code: symtranspose.c
1: /*
2: Defines symbolic transpose routines for SeqAIJ matrices.
4: Currently Get/Restore only allocates/frees memory for holding the
5: (i,j) info for the transpose. Someday, this info could be
6: maintained so successive calls to Get will not recompute the info.
8: Also defined is a "faster" implementation of MatTranspose for SeqAIJ
9: matrices which avoids calls to MatSetValues. This routine has not
10: been adopted as the standard yet as it is somewhat untested.
12: */
14: #include src/mat/impls/aij/seq/aij.h
16: static int logkey_matgetsymtranspose = 0;
17: static int logkey_mattranspose = 0;
22: int MatGetSymbolicTranspose_SeqAIJ(Mat A,int *Ati[],int *Atj[]) {
23: int ierr,i,j,anzj;
24: Mat_SeqAIJ *a=(Mat_SeqAIJ *)A->data;
25: int an=A->N,am=A->M;
26: int *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
30: PetscLogInfo(A,"Getting Symbolic Transpose.\n");
32: /* Set up timers */
33: if (!logkey_matgetsymtranspose) {
34: PetscLogEventRegister(&logkey_matgetsymtranspose,"MatGetSymbolicTranspose",MAT_COOKIE);
35: }
36: PetscLogEventBegin(logkey_matgetsymtranspose,A,0,0,0);
38: /* Allocate space for symbolic transpose info and work array */
39: PetscMalloc((an+1)*sizeof(int),&ati);
40: PetscMalloc(ai[am]*sizeof(int),&atj);
41: PetscMalloc(an*sizeof(int),&atfill);
42: PetscMemzero(ati,(an+1)*sizeof(int));
44: /* Walk through aj and count ## of non-zeros in each row of A^T. */
45: /* Note: offset by 1 for fast conversion into csr format. */
46: for (i=0;i<ai[am];i++) {
47: ati[aj[i]+1] += 1;
48: }
49: /* Form ati for csr format of A^T. */
50: for (i=0;i<an;i++) {
51: ati[i+1] += ati[i];
52: }
54: /* Copy ati into atfill so we have locations of the next free space in atj */
55: PetscMemcpy(atfill,ati,an*sizeof(int));
57: /* Walk through A row-wise and mark nonzero entries of A^T. */
58: for (i=0;i<am;i++) {
59: anzj = ai[i+1] - ai[i];
60: for (j=0;j<anzj;j++) {
61: atj[atfill[*aj]] = i;
62: atfill[*aj++] += 1;
63: }
64: }
66: /* Clean up temporary space and complete requests. */
67: PetscFree(atfill);
68: *Ati = ati;
69: *Atj = atj;
71: PetscLogEventEnd(logkey_matgetsymtranspose,A,0,0,0);
72: return(0);
73: }
77: int MatTranspose_SeqAIJ_FAST(Mat A,Mat *B) {
78: int ierr,i,j,anzj;
79: Mat At;
80: Mat_SeqAIJ *a=(Mat_SeqAIJ *)A->data,*at;
81: int an=A->N,am=A->M;
82: int *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
83: MatScalar *ata,*aa=a->a;
86: /* Set up timers */
87: if (!logkey_mattranspose) {
88: PetscLogEventRegister(&logkey_mattranspose,"MatTranspose_SeqAIJ_FAST",MAT_COOKIE);
89: }
90: PetscLogEventBegin(logkey_mattranspose,A,0,0,0);
92: /* Allocate space for symbolic transpose info and work array */
93: PetscMalloc((an+1)*sizeof(int),&ati);
94: PetscMalloc(ai[am]*sizeof(int),&atj);
95: PetscMalloc(ai[am]*sizeof(MatScalar),&ata);
96: PetscMalloc(an*sizeof(int),&atfill);
97: PetscMemzero(ati,(an+1)*sizeof(int));
98: /* Walk through aj and count ## of non-zeros in each row of A^T. */
99: /* Note: offset by 1 for fast conversion into csr format. */
100: for (i=0;i<ai[am];i++) {
101: ati[aj[i]+1] += 1;
102: }
103: /* Form ati for csr format of A^T. */
104: for (i=0;i<an;i++) {
105: ati[i+1] += ati[i];
106: }
108: /* Copy ati into atfill so we have locations of the next free space in atj */
109: PetscMemcpy(atfill,ati,an*sizeof(int));
111: /* Walk through A row-wise and mark nonzero entries of A^T. */
112: for (i=0;i<am;i++) {
113: anzj = ai[i+1] - ai[i];
114: for (j=0;j<anzj;j++) {
115: atj[atfill[*aj]] = i;
116: ata[atfill[*aj]] = *aa++;
117: atfill[*aj++] += 1;
118: }
119: }
121: /* Clean up temporary space and complete requests. */
122: PetscFree(atfill);
123: MatCreateSeqAIJWithArrays(A->comm,an,am,ati,atj,ata,&At);
124: at = (Mat_SeqAIJ *)(At->data);
125: at->freedata = PETSC_TRUE;
126: at->nonew = 0;
127: if (B) {
128: *B = At;
129: } else {
130: MatHeaderCopy(A,At);
131: }
132: PetscLogEventEnd(logkey_mattranspose,A,0,0,0);
133: return(0);
134: }
138: int MatRestoreSymbolicTranspose_SeqAIJ(Mat A,int *ati[],int *atj[]) {
142: PetscLogInfo(A,"Restoring Symbolic Transpose.\n");
143: PetscFree(*ati);
144: ati = PETSC_NULL;
145: PetscFree(*atj);
146: atj = PETSC_NULL;
147: return(0);
148: }