xref: /petsc/src/mat/impls/aij/seq/inode2.c (revision 58d68138c660dfb4e9f5b03334792cd4f2ffd7cc)
1 
2 #include <../src/mat/impls/aij/seq/aij.h>
3 
4 extern PetscErrorCode MatInodeAdjustForInodes_SeqAIJ_Inode(Mat, IS *, IS *);
5 extern PetscErrorCode MatInodeGetInodeSizes_SeqAIJ_Inode(Mat, PetscInt *, PetscInt *[], PetscInt *);
6 
7 PetscErrorCode MatView_SeqAIJ_Inode(Mat A, PetscViewer viewer) {
8   Mat_SeqAIJ       *a = (Mat_SeqAIJ *)A->data;
9   PetscBool         iascii;
10   PetscViewerFormat format;
11 
12   PetscFunctionBegin;
13   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
14   if (iascii) {
15     PetscCall(PetscViewerGetFormat(viewer, &format));
16     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
17       if (a->inode.size) {
18         PetscCall(PetscViewerASCIIPrintf(viewer, "using I-node routines: found %" PetscInt_FMT " nodes, limit used is %" PetscInt_FMT "\n", a->inode.node_count, a->inode.limit));
19       } else {
20         PetscCall(PetscViewerASCIIPrintf(viewer, "not using I-node routines\n"));
21       }
22     }
23   }
24   PetscFunctionReturn(0);
25 }
26 
27 PetscErrorCode MatAssemblyEnd_SeqAIJ_Inode(Mat A, MatAssemblyType mode) {
28   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data;
29 
30   PetscFunctionBegin;
31   PetscCall(MatSeqAIJCheckInode(A));
32   a->inode.ibdiagvalid = PETSC_FALSE;
33   PetscFunctionReturn(0);
34 }
35 
36 PetscErrorCode MatDestroy_SeqAIJ_Inode(Mat A) {
37   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data;
38 
39   PetscFunctionBegin;
40   PetscCall(PetscFree(a->inode.size));
41   PetscCall(PetscFree3(a->inode.ibdiag, a->inode.bdiag, a->inode.ssor_work));
42   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatInodeAdjustForInodes_C", NULL));
43   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatInodeGetInodeSizes_C", NULL));
44   PetscFunctionReturn(0);
45 }
46 
47 /* MatCreate_SeqAIJ_Inode is not DLLEXPORTed because it is not a constructor for a complete type.    */
48 /* It is also not registered as a type for use within MatSetType.                             */
49 /* It is intended as a helper for the MATSEQAIJ class, so classes which desire Inodes should  */
50 /*    inherit off of MATSEQAIJ instead by calling MatSetType(MATSEQAIJ) in their constructor. */
51 /* Maybe this is a bad idea. (?) */
52 PetscErrorCode MatCreate_SeqAIJ_Inode(Mat B) {
53   Mat_SeqAIJ *b = (Mat_SeqAIJ *)B->data;
54   PetscBool   no_inode, no_unroll;
55 
56   PetscFunctionBegin;
57   no_inode             = PETSC_FALSE;
58   no_unroll            = PETSC_FALSE;
59   b->inode.checked     = PETSC_FALSE;
60   b->inode.node_count  = 0;
61   b->inode.size        = NULL;
62   b->inode.limit       = 5;
63   b->inode.max_limit   = 5;
64   b->inode.ibdiagvalid = PETSC_FALSE;
65   b->inode.ibdiag      = NULL;
66   b->inode.bdiag       = NULL;
67 
68   PetscOptionsBegin(PetscObjectComm((PetscObject)B), ((PetscObject)B)->prefix, "Options for SEQAIJ matrix", "Mat");
69   PetscCall(PetscOptionsBool("-mat_no_unroll", "Do not optimize for inodes (slower)", NULL, no_unroll, &no_unroll, NULL));
70   if (no_unroll) { PetscCall(PetscInfo(B, "Not using Inode routines due to -mat_no_unroll\n")); }
71   PetscCall(PetscOptionsBool("-mat_no_inode", "Do not optimize for inodes -slower-", NULL, no_inode, &no_inode, NULL));
72   if (no_inode) { PetscCall(PetscInfo(B, "Not using Inode routines due to -mat_no_inode\n")); }
73   PetscCall(PetscOptionsInt("-mat_inode_limit", "Do not use inodes larger then this value", NULL, b->inode.limit, &b->inode.limit, NULL));
74   PetscOptionsEnd();
75 
76   b->inode.use = (PetscBool)(!(no_unroll || no_inode));
77   if (b->inode.limit > b->inode.max_limit) b->inode.limit = b->inode.max_limit;
78 
79   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatInodeAdjustForInodes_C", MatInodeAdjustForInodes_SeqAIJ_Inode));
80   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatInodeGetInodeSizes_C", MatInodeGetInodeSizes_SeqAIJ_Inode));
81   PetscFunctionReturn(0);
82 }
83 
84 PetscErrorCode MatSetOption_SeqAIJ_Inode(Mat A, MatOption op, PetscBool flg) {
85   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data;
86 
87   PetscFunctionBegin;
88   switch (op) {
89   case MAT_USE_INODES: a->inode.use = flg; break;
90   default: break;
91   }
92   PetscFunctionReturn(0);
93 }
94