1 #define PETSCMAT_DLL 2 #include "../src/mat/impls/aij/seq/aij.h" 3 4 EXTERN PetscErrorCode Mat_CheckInode(Mat,PetscTruth); 5 EXTERN_C_BEGIN 6 EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatInodeAdjustForInodes_Inode(Mat,IS*,IS*); 7 EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatInodeGetInodeSizes_Inode(Mat,PetscInt*,PetscInt*[],PetscInt*); 8 EXTERN_C_END 9 10 #undef __FUNCT__ 11 #define __FUNCT__ "MatView_Inode" 12 PetscErrorCode MatView_Inode(Mat A,PetscViewer viewer) 13 { 14 Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 15 PetscErrorCode ierr; 16 PetscTruth iascii; 17 PetscViewerFormat format; 18 19 PetscFunctionBegin; 20 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 21 if (iascii) { 22 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 23 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) { 24 if (a->inode.size) { 25 ierr = PetscViewerASCIIPrintf(viewer,"using I-node routines: found %D nodes, limit used is %D\n", 26 a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 27 } else { 28 ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 29 } 30 } 31 } 32 PetscFunctionReturn(0); 33 } 34 35 #undef __FUNCT__ 36 #define __FUNCT__ "MatAssemblyEnd_Inode" 37 PetscErrorCode MatAssemblyEnd_Inode(Mat A, MatAssemblyType mode) 38 { 39 Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 40 PetscErrorCode ierr; 41 PetscTruth samestructure; 42 43 PetscFunctionBegin; 44 /* info.nz_unneeded of zero denotes no structural change was made to the matrix during Assembly */ 45 samestructure = (PetscTruth)(!A->info.nz_unneeded); 46 /* check for identical nodes. If found, use inode functions */ 47 ierr = Mat_CheckInode(A,samestructure);CHKERRQ(ierr); 48 a->inode.ibdiagvalid = PETSC_FALSE; 49 PetscFunctionReturn(0); 50 } 51 52 #undef __FUNCT__ 53 #define __FUNCT__ "MatDestroy_Inode" 54 PetscErrorCode MatDestroy_Inode(Mat A) 55 { 56 PetscErrorCode ierr; 57 Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 58 59 PetscFunctionBegin; 60 ierr = PetscFree(a->inode.size);CHKERRQ(ierr); 61 ierr = PetscFree2(a->inode.ibdiag,a->inode.bdiag);CHKERRQ(ierr); 62 ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatInodeAdjustForInodes_C","",PETSC_NULL);CHKERRQ(ierr); 63 ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatInodeGetInodeSizes_C","",PETSC_NULL);CHKERRQ(ierr); 64 PetscFunctionReturn(0); 65 } 66 67 /* MatCreate_Inode is not DLLEXPORTed because it is not a constructor for a complete type. */ 68 /* It is also not registered as a type for use within MatSetType. */ 69 /* It is intended as a helper for the MATSEQAIJ class, so classes which desire Inodes should */ 70 /* inherit off of MATSEQAIJ instead by calling MatSetType(MATSEQAIJ) in their constructor. */ 71 /* Maybe this is a bad idea. (?) */ 72 #undef __FUNCT__ 73 #define __FUNCT__ "MatCreate_Inode" 74 PetscErrorCode MatCreate_Inode(Mat B) 75 { 76 Mat_SeqAIJ *b=(Mat_SeqAIJ*)B->data; 77 PetscErrorCode ierr; 78 PetscTruth no_inode,no_unroll; 79 80 PetscFunctionBegin; 81 no_inode = PETSC_FALSE; 82 no_unroll = PETSC_FALSE; 83 b->inode.node_count = 0; 84 b->inode.size = 0; 85 b->inode.limit = 5; 86 b->inode.max_limit = 5; 87 b->inode.ibdiagvalid = PETSC_FALSE; 88 b->inode.ibdiag = 0; 89 b->inode.bdiag = 0; 90 91 ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Options for SEQAIJ matrix","Mat");CHKERRQ(ierr); 92 ierr = PetscOptionsTruth("-mat_no_unroll","Do not optimize for inodes (slower)",PETSC_NULL,no_unroll,&no_unroll,PETSC_NULL);CHKERRQ(ierr); 93 if (no_unroll) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_unroll\n");CHKERRQ(ierr);} 94 ierr = PetscOptionsTruth("-mat_no_inode","Do not optimize for inodes (slower)",PETSC_NULL,no_inode,&no_inode,PETSC_NULL);CHKERRQ(ierr); 95 if (no_inode) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_inode\n");CHKERRQ(ierr);} 96 ierr = PetscOptionsInt("-mat_inode_limit","Do not use inodes larger then this value",PETSC_NULL,b->inode.limit,&b->inode.limit,PETSC_NULL);CHKERRQ(ierr); 97 ierr = PetscOptionsEnd();CHKERRQ(ierr); 98 b->inode.use = (PetscTruth)(!(no_unroll || no_inode)); 99 if (b->inode.limit > b->inode.max_limit) b->inode.limit = b->inode.max_limit; 100 101 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatInodeAdjustForInodes_C", 102 "MatInodeAdjustForInodes_Inode", 103 MatInodeAdjustForInodes_Inode);CHKERRQ(ierr); 104 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatInodeGetInodeSizes_C", 105 "MatInodeGetInodeSizes_Inode", 106 MatInodeGetInodeSizes_Inode);CHKERRQ(ierr); 107 PetscFunctionReturn(0); 108 } 109 110 #undef __FUNCT__ 111 #define __FUNCT__ "MatSetOption_Inode" 112 PetscErrorCode MatSetOption_Inode(Mat A,MatOption op,PetscTruth flg) 113 { 114 Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 115 116 PetscFunctionBegin; 117 switch(op) { 118 case MAT_USE_INODES: 119 a->inode.use = flg; 120 break; 121 default: 122 break; 123 } 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "MatDuplicate_Inode" 129 PetscErrorCode MatDuplicate_Inode(Mat A,MatDuplicateOption cpvalues,Mat *C) 130 { 131 Mat B=*C; 132 Mat_SeqAIJ *c=(Mat_SeqAIJ*)B->data,*a=(Mat_SeqAIJ*)A->data; 133 PetscErrorCode ierr; 134 PetscInt m=A->rmap->n; 135 136 PetscFunctionBegin; 137 138 c->inode.use = a->inode.use; 139 c->inode.limit = a->inode.limit; 140 c->inode.max_limit = a->inode.max_limit; 141 if (a->inode.size){ 142 ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->inode.size);CHKERRQ(ierr); 143 c->inode.node_count = a->inode.node_count; 144 ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 145 } else { 146 c->inode.size = 0; 147 c->inode.node_count = 0; 148 } 149 c->inode.ibdiagvalid = PETSC_FALSE; 150 c->inode.ibdiag = 0; 151 c->inode.bdiag = 0; 152 PetscFunctionReturn(0); 153 } 154 155 #undef __FUNCT__ 156 #define __FUNCT__ "MatILUDTFactor_Inode" 157 PetscErrorCode MatILUDTFactor_Inode(Mat A,IS isrow,IS iscol,const MatFactorInfo *info,Mat *fact) 158 { 159 PetscErrorCode ierr; 160 161 PetscFunctionBegin; 162 /* check for identical nodes. If found, use inode functions */ 163 ierr = Mat_CheckInode(*fact,PETSC_FALSE);CHKERRQ(ierr); 164 PetscFunctionReturn(0); 165 } 166 167 extern PetscErrorCode MatSolve_Inode(Mat,Vec,Vec); 168 extern PetscErrorCode MatLUFactorNumeric_Inode(Mat,Mat,const MatFactorInfo*); 169 170 #undef __FUNCT__ 171 #define __FUNCT__ "MatLUFactorSymbolic_Inode" 172 PetscErrorCode MatLUFactorSymbolic_Inode(Mat fact,Mat A,IS isrow,IS iscol,const MatFactorInfo *info) 173 { 174 PetscErrorCode ierr; 175 Mat_SeqAIJ *f = (Mat_SeqAIJ*)A->data; 176 177 PetscFunctionBegin; 178 /* check for identical nodes. If found, use inode functions */ 179 ierr = Mat_CheckInode(fact,PETSC_FALSE);CHKERRQ(ierr); 180 if (f->inode.use) { 181 (fact)->ops->lufactornumeric = MatLUFactorNumeric_Inode; 182 } 183 PetscFunctionReturn(0); 184 } 185 186 #undef __FUNCT__ 187 #define __FUNCT__ "MatILUFactorSymbolic_Inode" 188 PetscErrorCode MatILUFactorSymbolic_Inode(Mat fact,Mat A,IS isrow,IS iscol,const MatFactorInfo *info) 189 { 190 PetscErrorCode ierr; 191 Mat_SeqAIJ *f = (Mat_SeqAIJ*)A->data; 192 193 PetscFunctionBegin; 194 /* check for identical nodes. If found, use inode functions */ 195 ierr = Mat_CheckInode(fact,PETSC_FALSE);CHKERRQ(ierr); 196 if (f->inode.use) { 197 (fact)->ops->lufactornumeric = MatLUFactorNumeric_Inode; 198 } 199 PetscFunctionReturn(0); 200 } 201 202 203