Actual source code: inode2.c

  1: #define PETSCMAT_DLL

 3:  #include src/mat/impls/csr/inode/inode.h
  4: EXTERN PetscErrorCode Mat_CheckInode(Mat,PetscTruth);
  6: EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatInodeAdjustForInodes_Inode(Mat,IS*,IS*);
  7: EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatInodeGetInodeSizes_Inode(Mat,PetscInt*,PetscInt*[],PetscInt*);

 12: PetscErrorCode MatView_Inode(Mat A,PetscViewer viewer)
 13: {
 14:   Mat_inode         *a=(Mat_inode*)A->data;
 15:   PetscErrorCode    ierr;
 16:   PetscTruth        iascii;
 17:   PetscViewerFormat format;

 20:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
 21:   if (iascii) {
 22:     PetscViewerGetFormat(viewer,&format);
 23:     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
 24:       if (a->inode.size) {
 25:         PetscViewerASCIIPrintf(viewer,"using I-node routines: found %D nodes, limit used is %D\n",
 26:                                       a->inode.node_count,a->inode.limit);
 27:       } else {
 28:         PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");
 29:       }
 30:     }
 31:   }
 32:   return(0);
 33: }

 37: PetscErrorCode MatAssemblyEnd_Inode(Mat A, MatAssemblyType mode)
 38: {
 40:   PetscTruth     samestructure;

 43:   /* info.nz_unneeded of zero denotes no structural change was made to the matrix during Assembly */
 44:   samestructure = (PetscTruth)(!A->info.nz_unneeded);
 45:   /* check for identical nodes. If found, use inode functions */
 46:   Mat_CheckInode(A,samestructure);
 47:   return(0);
 48: }

 52: PetscErrorCode MatDestroy_Inode(Mat A)
 53: {
 55:   Mat_inode      *a=(Mat_inode*)A->data;

 58:   if (a->inode.size) {
 59:     PetscFree(a->inode.size);
 60:   }
 61:   PetscObjectComposeFunctionDynamic((PetscObject)A,"MatInodeAdjustForInodes_C","",PETSC_NULL);
 62:   PetscObjectComposeFunctionDynamic((PetscObject)A,"MatInodeGetInodeSizes_C","",PETSC_NULL);
 63:   return(0);
 64: }

 66: /* MatCreate_Inode is not DLLEXPORTed because it is not a constructor for a complete type.    */
 67: /* It is also not registered as a type for use within MatSetType.                             */
 68: /* It is intended as a helper for the MATSEQAIJ class, so classes which desire Inodes should  */
 69: /*    inherit off of MATSEQAIJ instead by calling MatSetType(MATSEQAIJ) in their constructor. */
 70: /* Maybe this is a bad idea. (?) */
 73: PetscErrorCode MatCreate_Inode(Mat B)
 74: {
 75:   Mat_inode      *b=(Mat_inode*)B->data;

 79:   b->inode.use         = PETSC_TRUE;
 80:   b->inode.node_count  = 0;
 81:   b->inode.size        = 0;
 82:   b->inode.limit       = 5;
 83:   b->inode.max_limit   = 5;

 85:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatInodeAdjustForInodes_C",
 86:                                      "MatInodeAdjustForInodes_Inode",
 87:                                       MatInodeAdjustForInodes_Inode);
 88:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatInodeGetInodeSizes_C",
 89:                                      "MatInodeGetInodeSizes_Inode",
 90:                                       MatInodeGetInodeSizes_Inode);
 91:   return(0);
 92: }

 96: PetscErrorCode MatSetOption_Inode(Mat A,MatOption op)
 97: {
 98:   Mat_inode *a=(Mat_inode*)A->data;
100:   switch(op) {
101:     case MAT_USE_INODES:
102:       a->inode.use         = PETSC_TRUE;
103:       break;
104:     case MAT_DO_NOT_USE_INODES:
105:       a->inode.use         = PETSC_FALSE;
106:       break;
107:     case MAT_INODE_LIMIT_1:
108:       a->inode.limit  = 1;
109:       break;
110:     case MAT_INODE_LIMIT_2:
111:       a->inode.limit  = 2;
112:       break;
113:     case MAT_INODE_LIMIT_3:
114:       a->inode.limit  = 3;
115:       break;
116:     case MAT_INODE_LIMIT_4:
117:       a->inode.limit  = 4;
118:       break;
119:     case MAT_INODE_LIMIT_5:
120:       a->inode.limit  = 5;
121:       break;
122:     default:
123:       break;
124:   }
125:   return(0);
126: }

130: PetscErrorCode MatPrintHelp_Inode(Mat A)
131: {
132:   static PetscTruth called=PETSC_FALSE;
133:   MPI_Comm          comm=A->comm;
134:   PetscErrorCode    ierr;

137:   if (!called) {
138:     called = PETSC_TRUE;
139:     (*PetscHelpPrintf)(comm," Inode related options (the defaults):\n");
140:     (*PetscHelpPrintf)(comm,"  -mat_inode_limit <limit>: Set inode limit (max limit=5)\n");
141:     (*PetscHelpPrintf)(comm,"  -mat_no_inode: Do not use inodes\n");
142:   }
143:   return(0);
144: }

148: PetscErrorCode MatDuplicate_Inode(Mat A,MatDuplicateOption cpvalues,Mat *C)
149: {
150:   Mat            B=*C;
151:   Mat_inode      *c=(Mat_inode*)B->data,*a=(Mat_inode*)A->data;
153:   PetscInt       m=A->m;


157:   c->inode.use          = a->inode.use;
158:   c->inode.limit        = a->inode.limit;
159:   c->inode.max_limit    = a->inode.max_limit;
160:   if (a->inode.size){
161:     PetscMalloc((m+1)*sizeof(PetscInt),&c->inode.size);
162:     c->inode.node_count = a->inode.node_count;
163:     PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(PetscInt));
164:   } else {
165:     c->inode.size       = 0;
166:     c->inode.node_count = 0;
167:   }
168:   return(0);
169: }

173: PetscErrorCode MatILUDTFactor_Inode(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *fact)
174: {

178:     /* check for identical nodes. If found, use inode functions */
179:   Mat_CheckInode(*fact,PETSC_FALSE);
180:   return(0);
181: }

185: PetscErrorCode MatLUFactorSymbolic_Inode(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *fact)
186: {

190:     /* check for identical nodes. If found, use inode functions */
191:   Mat_CheckInode(*fact,PETSC_FALSE);
192:   return(0);
193: }

197: PetscErrorCode MatILUFactorSymbolic_Inode(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *fact)
198: {

202:     /* check for identical nodes. If found, use inode functions */
203:   Mat_CheckInode(*fact,PETSC_FALSE);
204:   return(0);
205: }