14c1414c8SBarry Smith #define PETSCMAT_DLL 24c1414c8SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 34c1414c8SBarry Smith 44c1414c8SBarry Smith EXTERN PetscErrorCode Mat_CheckInode(Mat,PetscTruth); 54c1414c8SBarry Smith EXTERN_C_BEGIN 64c1414c8SBarry Smith EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatInodeAdjustForInodes_Inode(Mat,IS*,IS*); 74c1414c8SBarry Smith EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatInodeGetInodeSizes_Inode(Mat,PetscInt*,PetscInt*[],PetscInt*); 84c1414c8SBarry Smith EXTERN_C_END 94c1414c8SBarry Smith 104c1414c8SBarry Smith #undef __FUNCT__ 114c1414c8SBarry Smith #define __FUNCT__ "MatView_Inode" 124c1414c8SBarry Smith PetscErrorCode MatView_Inode(Mat A,PetscViewer viewer) 134c1414c8SBarry Smith { 144c1414c8SBarry Smith Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 154c1414c8SBarry Smith PetscErrorCode ierr; 164c1414c8SBarry Smith PetscTruth iascii; 174c1414c8SBarry Smith PetscViewerFormat format; 184c1414c8SBarry Smith 194c1414c8SBarry Smith PetscFunctionBegin; 204c1414c8SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 214c1414c8SBarry Smith if (iascii) { 224c1414c8SBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 234c1414c8SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) { 244c1414c8SBarry Smith if (a->inode.size) { 254c1414c8SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"using I-node routines: found %D nodes, limit used is %D\n", 264c1414c8SBarry Smith a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 274c1414c8SBarry Smith } else { 284c1414c8SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 294c1414c8SBarry Smith } 304c1414c8SBarry Smith } 314c1414c8SBarry Smith } 324c1414c8SBarry Smith PetscFunctionReturn(0); 334c1414c8SBarry Smith } 344c1414c8SBarry Smith 354c1414c8SBarry Smith #undef __FUNCT__ 364c1414c8SBarry Smith #define __FUNCT__ "MatAssemblyEnd_Inode" 374c1414c8SBarry Smith PetscErrorCode MatAssemblyEnd_Inode(Mat A, MatAssemblyType mode) 384c1414c8SBarry Smith { 394c1414c8SBarry Smith PetscErrorCode ierr; 404c1414c8SBarry Smith PetscTruth samestructure; 414c1414c8SBarry Smith 424c1414c8SBarry Smith PetscFunctionBegin; 434c1414c8SBarry Smith /* info.nz_unneeded of zero denotes no structural change was made to the matrix during Assembly */ 444c1414c8SBarry Smith samestructure = (PetscTruth)(!A->info.nz_unneeded); 454c1414c8SBarry Smith /* check for identical nodes. If found, use inode functions */ 464c1414c8SBarry Smith ierr = Mat_CheckInode(A,samestructure);CHKERRQ(ierr); 474c1414c8SBarry Smith PetscFunctionReturn(0); 484c1414c8SBarry Smith } 494c1414c8SBarry Smith 504c1414c8SBarry Smith #undef __FUNCT__ 514c1414c8SBarry Smith #define __FUNCT__ "MatDestroy_Inode" 524c1414c8SBarry Smith PetscErrorCode MatDestroy_Inode(Mat A) 534c1414c8SBarry Smith { 544c1414c8SBarry Smith PetscErrorCode ierr; 554c1414c8SBarry Smith Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 564c1414c8SBarry Smith 574c1414c8SBarry Smith PetscFunctionBegin; 584c1414c8SBarry Smith ierr = PetscFree(a->inode.size);CHKERRQ(ierr); 594c1414c8SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatInodeAdjustForInodes_C","",PETSC_NULL);CHKERRQ(ierr); 604c1414c8SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatInodeGetInodeSizes_C","",PETSC_NULL);CHKERRQ(ierr); 614c1414c8SBarry Smith PetscFunctionReturn(0); 624c1414c8SBarry Smith } 634c1414c8SBarry Smith 644c1414c8SBarry Smith /* MatCreate_Inode is not DLLEXPORTed because it is not a constructor for a complete type. */ 654c1414c8SBarry Smith /* It is also not registered as a type for use within MatSetType. */ 664c1414c8SBarry Smith /* It is intended as a helper for the MATSEQAIJ class, so classes which desire Inodes should */ 674c1414c8SBarry Smith /* inherit off of MATSEQAIJ instead by calling MatSetType(MATSEQAIJ) in their constructor. */ 684c1414c8SBarry Smith /* Maybe this is a bad idea. (?) */ 694c1414c8SBarry Smith #undef __FUNCT__ 704c1414c8SBarry Smith #define __FUNCT__ "MatCreate_Inode" 714c1414c8SBarry Smith PetscErrorCode MatCreate_Inode(Mat B) 724c1414c8SBarry Smith { 734c1414c8SBarry Smith Mat_SeqAIJ *b=(Mat_SeqAIJ*)B->data; 744c1414c8SBarry Smith PetscErrorCode ierr; 75*da9f3051SSatish Balay PetscTruth no_inode,no_unroll; 764c1414c8SBarry Smith 774c1414c8SBarry Smith PetscFunctionBegin; 78*da9f3051SSatish Balay no_inode = PETSC_FALSE; 79*da9f3051SSatish Balay no_unroll = PETSC_FALSE; 804c1414c8SBarry Smith b->inode.node_count = 0; 814c1414c8SBarry Smith b->inode.size = 0; 824c1414c8SBarry Smith b->inode.limit = 5; 834c1414c8SBarry Smith b->inode.max_limit = 5; 844c1414c8SBarry Smith 85d74fe821SBarry Smith ierr = PetscOptionsBegin(B->comm,B->prefix,"Options for SEQAIJ matrix","Mat");CHKERRQ(ierr); 86*da9f3051SSatish Balay ierr = PetscOptionsTruth("-mat_no_unroll","Do not optimize for inodes (slower)",PETSC_NULL,no_unroll,&no_unroll,PETSC_NULL);CHKERRQ(ierr); 87*da9f3051SSatish Balay if (no_unroll) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_unroll\n");CHKERRQ(ierr);} 88*da9f3051SSatish Balay ierr = PetscOptionsTruth("-mat_no_inode","Do not optimize for inodes (slower)",PETSC_NULL,no_inode,&no_inode,PETSC_NULL);CHKERRQ(ierr); 89*da9f3051SSatish Balay if (no_inode) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_inode\n");CHKERRQ(ierr);} 90d74fe821SBarry Smith 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); 91d74fe821SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 92*da9f3051SSatish Balay b->inode.use = !(no_unroll || no_inode); 93d74fe821SBarry Smith if (b->inode.limit > b->inode.max_limit) b->inode.limit = b->inode.max_limit; 94d74fe821SBarry Smith 954c1414c8SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatInodeAdjustForInodes_C", 964c1414c8SBarry Smith "MatInodeAdjustForInodes_Inode", 974c1414c8SBarry Smith MatInodeAdjustForInodes_Inode);CHKERRQ(ierr); 984c1414c8SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatInodeGetInodeSizes_C", 994c1414c8SBarry Smith "MatInodeGetInodeSizes_Inode", 1004c1414c8SBarry Smith MatInodeGetInodeSizes_Inode);CHKERRQ(ierr); 1014c1414c8SBarry Smith PetscFunctionReturn(0); 1024c1414c8SBarry Smith } 1034c1414c8SBarry Smith 1044c1414c8SBarry Smith #undef __FUNCT__ 1054c1414c8SBarry Smith #define __FUNCT__ "MatSetOption_Inode" 1064c1414c8SBarry Smith PetscErrorCode MatSetOption_Inode(Mat A,MatOption op) 1074c1414c8SBarry Smith { 1084c1414c8SBarry Smith Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 109d74fe821SBarry Smith PetscErrorCode ierr; 110d74fe821SBarry Smith 1114c1414c8SBarry Smith PetscFunctionBegin; 1124c1414c8SBarry Smith switch(op) { 1134c1414c8SBarry Smith case MAT_USE_INODES: 1144c1414c8SBarry Smith a->inode.use = PETSC_TRUE; 1154c1414c8SBarry Smith break; 1164c1414c8SBarry Smith case MAT_DO_NOT_USE_INODES: 1174c1414c8SBarry Smith a->inode.use = PETSC_FALSE; 118d74fe821SBarry Smith ierr = PetscInfo(A,"Not using Inode routines due to MatSetOption(MAT_DO_NOT_USE_INODES\n");CHKERRQ(ierr); 1194c1414c8SBarry Smith break; 1204c1414c8SBarry Smith case MAT_INODE_LIMIT_1: 1214c1414c8SBarry Smith a->inode.limit = 1; 1224c1414c8SBarry Smith break; 1234c1414c8SBarry Smith case MAT_INODE_LIMIT_2: 1244c1414c8SBarry Smith a->inode.limit = 2; 1254c1414c8SBarry Smith break; 1264c1414c8SBarry Smith case MAT_INODE_LIMIT_3: 1274c1414c8SBarry Smith a->inode.limit = 3; 1284c1414c8SBarry Smith break; 1294c1414c8SBarry Smith case MAT_INODE_LIMIT_4: 1304c1414c8SBarry Smith a->inode.limit = 4; 1314c1414c8SBarry Smith break; 1324c1414c8SBarry Smith case MAT_INODE_LIMIT_5: 1334c1414c8SBarry Smith a->inode.limit = 5; 1344c1414c8SBarry Smith break; 1354c1414c8SBarry Smith default: 1364c1414c8SBarry Smith break; 1374c1414c8SBarry Smith } 1384c1414c8SBarry Smith PetscFunctionReturn(0); 1394c1414c8SBarry Smith } 1404c1414c8SBarry Smith 1414c1414c8SBarry Smith #undef __FUNCT__ 1424c1414c8SBarry Smith #define __FUNCT__ "MatDuplicate_Inode" 1434c1414c8SBarry Smith PetscErrorCode MatDuplicate_Inode(Mat A,MatDuplicateOption cpvalues,Mat *C) 1444c1414c8SBarry Smith { 1454c1414c8SBarry Smith Mat B=*C; 1464c1414c8SBarry Smith Mat_SeqAIJ *c=(Mat_SeqAIJ*)B->data,*a=(Mat_SeqAIJ*)A->data; 1474c1414c8SBarry Smith PetscErrorCode ierr; 1484c1414c8SBarry Smith PetscInt m=A->rmap.n; 1494c1414c8SBarry Smith 1504c1414c8SBarry Smith PetscFunctionBegin; 1514c1414c8SBarry Smith 1524c1414c8SBarry Smith c->inode.use = a->inode.use; 1534c1414c8SBarry Smith c->inode.limit = a->inode.limit; 1544c1414c8SBarry Smith c->inode.max_limit = a->inode.max_limit; 1554c1414c8SBarry Smith if (a->inode.size){ 1564c1414c8SBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->inode.size);CHKERRQ(ierr); 1574c1414c8SBarry Smith c->inode.node_count = a->inode.node_count; 1584c1414c8SBarry Smith ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 1594c1414c8SBarry Smith } else { 1604c1414c8SBarry Smith c->inode.size = 0; 1614c1414c8SBarry Smith c->inode.node_count = 0; 1624c1414c8SBarry Smith } 1634c1414c8SBarry Smith PetscFunctionReturn(0); 1644c1414c8SBarry Smith } 1654c1414c8SBarry Smith 1664c1414c8SBarry Smith #undef __FUNCT__ 1674c1414c8SBarry Smith #define __FUNCT__ "MatILUDTFactor_Inode" 1684c1414c8SBarry Smith PetscErrorCode MatILUDTFactor_Inode(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *fact) 1694c1414c8SBarry Smith { 1704c1414c8SBarry Smith PetscErrorCode ierr; 1714c1414c8SBarry Smith 1724c1414c8SBarry Smith PetscFunctionBegin; 1734c1414c8SBarry Smith /* check for identical nodes. If found, use inode functions */ 1744c1414c8SBarry Smith ierr = Mat_CheckInode(*fact,PETSC_FALSE);CHKERRQ(ierr); 1754c1414c8SBarry Smith PetscFunctionReturn(0); 1764c1414c8SBarry Smith } 1774c1414c8SBarry Smith 1784c1414c8SBarry Smith #undef __FUNCT__ 1794c1414c8SBarry Smith #define __FUNCT__ "MatLUFactorSymbolic_Inode" 1804c1414c8SBarry Smith PetscErrorCode MatLUFactorSymbolic_Inode(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *fact) 1814c1414c8SBarry Smith { 1824c1414c8SBarry Smith PetscErrorCode ierr; 1834c1414c8SBarry Smith 1844c1414c8SBarry Smith PetscFunctionBegin; 1854c1414c8SBarry Smith /* check for identical nodes. If found, use inode functions */ 1864c1414c8SBarry Smith ierr = Mat_CheckInode(*fact,PETSC_FALSE);CHKERRQ(ierr); 1874c1414c8SBarry Smith PetscFunctionReturn(0); 1884c1414c8SBarry Smith } 1894c1414c8SBarry Smith 1904c1414c8SBarry Smith #undef __FUNCT__ 1914c1414c8SBarry Smith #define __FUNCT__ "MatILUFactorSymbolic_Inode" 1924c1414c8SBarry Smith PetscErrorCode MatILUFactorSymbolic_Inode(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *fact) 1934c1414c8SBarry Smith { 1944c1414c8SBarry Smith PetscErrorCode ierr; 1954c1414c8SBarry Smith 1964c1414c8SBarry Smith PetscFunctionBegin; 1974c1414c8SBarry Smith /* check for identical nodes. If found, use inode functions */ 1984c1414c8SBarry Smith ierr = Mat_CheckInode(*fact,PETSC_FALSE);CHKERRQ(ierr); 1994c1414c8SBarry Smith PetscFunctionReturn(0); 2004c1414c8SBarry Smith } 2014c1414c8SBarry Smith 2024c1414c8SBarry Smith 203