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;
20: int MatGetSymbolicTranspose_SeqAIJ(Mat A,int *Ati[],int *Atj[]) {
21: int ierr,i,j,anzj;
22: Mat_SeqAIJ *a=(Mat_SeqAIJ *)A->data;
23: int aishift = a->indexshift,an=A->N,am=A->M;
24: int *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
28: PetscLogInfo(A,"Getting Symbolic Transpose.n");
29: if (aishift) SETERRQ(PETSC_ERR_SUP,"Shifted matrix indices are not supported.");
31: /* Set up timers */
32: if (!logkey_matgetsymtranspose) {
33: PetscLogEventRegister(&logkey_matgetsymtranspose,"MatGetSymbolicTranspose",MAT_COOKIE);
34: }
35: PetscLogEventBegin(logkey_matgetsymtranspose,A,0,0,0);
37: /* Allocate space for symbolic transpose info and work array */
38: PetscMalloc((an+1)*sizeof(int),&ati);
39: PetscMalloc(ai[am]*sizeof(int),&atj);
40: PetscMalloc(an*sizeof(int),&atfill);
41: PetscMemzero(ati,(an+1)*sizeof(int));
43: /* Walk through aj and count ## of non-zeros in each row of A^T. */
44: /* Note: offset by 1 for fast conversion into csr format. */
45: for (i=0;i<ai[am];i++) {
46: ati[aj[i]+1] += 1;
47: }
48: /* Form ati for csr format of A^T. */
49: for (i=0;i<an;i++) {
50: ati[i+1] += ati[i];
51: }
53: /* Copy ati into atfill so we have locations of the next free space in atj */
54: PetscMemcpy(atfill,ati,an*sizeof(int));
56: /* Walk through A row-wise and mark nonzero entries of A^T. */
57: for (i=0;i<am;i++) {
58: anzj = ai[i+1] - ai[i];
59: for (j=0;j<anzj;j++) {
60: atj[atfill[*aj]] = i;
61: atfill[*aj++] += 1;
62: }
63: }
65: /* Clean up temporary space and complete requests. */
66: PetscFree(atfill);
67: *Ati = ati;
68: *Atj = atj;
70: PetscLogEventEnd(logkey_matgetsymtranspose,A,0,0,0);
71: return(0);
72: }
74: int MatTranspose_SeqAIJ_FAST(Mat A,Mat *B) {
75: int ierr,i,j,anzj;
76: Mat At;
77: Mat_SeqAIJ *a=(Mat_SeqAIJ *)A->data,*at;
78: int aishift = a->indexshift,an=A->N,am=A->M;
79: int *ati,*atj,*atfill,*ai=a->i,*aj=a->j;
80: MatScalar *ata,*aa=a->a;
83: if (aishift) SETERRQ(PETSC_ERR_SUP,"Shifted matrix indices are not supported.");
85: /* Set up timers */
86: if (!logkey_mattranspose) {
87: PetscLogEventRegister(&logkey_mattranspose,"MatTranspose_SeqAIJ_FAST",MAT_COOKIE);
88: }
89: PetscLogEventBegin(logkey_mattranspose,A,0,0,0);
91: /* Allocate space for symbolic transpose info and work array */
92: PetscMalloc((an+1)*sizeof(int),&ati);
93: PetscMalloc(ai[am]*sizeof(int),&atj);
94: PetscMalloc(ai[am]*sizeof(MatScalar),&ata);
95: PetscMalloc(an*sizeof(int),&atfill);
96: PetscMemzero(ati,(an+1)*sizeof(int));
97: /* Walk through aj and count ## of non-zeros in each row of A^T. */
98: /* Note: offset by 1 for fast conversion into csr format. */
99: for (i=0;i<ai[am];i++) {
100: ati[aj[i]+1] += 1;
101: }
102: /* Form ati for csr format of A^T. */
103: for (i=0;i<an;i++) {
104: ati[i+1] += ati[i];
105: }
107: /* Copy ati into atfill so we have locations of the next free space in atj */
108: PetscMemcpy(atfill,ati,an*sizeof(int));
110: /* Walk through A row-wise and mark nonzero entries of A^T. */
111: for (i=0;i<am;i++) {
112: anzj = ai[i+1] - ai[i];
113: for (j=0;j<anzj;j++) {
114: atj[atfill[*aj]] = i;
115: ata[atfill[*aj]] = *aa++;
116: atfill[*aj++] += 1;
117: }
118: }
120: /* Clean up temporary space and complete requests. */
121: PetscFree(atfill);
122: MatCreateSeqAIJWithArrays(A->comm,an,am,ati,atj,ata,&At);
123: at = (Mat_SeqAIJ *)(At->data);
124: at->freedata = PETSC_TRUE;
125: at->nonew = 0;
126: if (B) {
127: *B = At;
128: } else {
129: MatHeaderCopy(A,At);
130: }
131: PetscLogEventEnd(logkey_mattranspose,A,0,0,0);
132: return(0);
133: }
135: int MatRestoreSymbolicTranspose_SeqAIJ(Mat A,int *ati[],int *atj[]) {
139: PetscLogInfo(A,"Restoring Symbolic Transpose.n");
140: PetscFree(*ati);
141: ati = PETSC_NULL;
142: PetscFree(*atj);
143: atj = PETSC_NULL;
144: return(0);
145: }