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