xref: /petsc/src/sys/error/pstack.c (revision c82b4e471ee2602ad975717c40559e312989d8d6)
1 
2 #include <petscsys.h>        /*I  "petscsys.h"   I*/
3 
4 
5 #if defined(PETSC_HAVE_PTHREADCLASSES)
6 #if defined(PETSC_PTHREAD_LOCAL)
7 PETSC_PTHREAD_LOCAL PetscStack *petscstack = 0;
8 #else
9 PetscThreadKey petscstack;
10 #endif
11 #else
12 PetscStack *petscstack = 0;
13 #endif
14 
15 #if defined(PETSC_HAVE_AMS)
16 
17 #  if defined(PETSC_USE_DEBUG)
18 
19 #include <petscviewerams.h>
20 
21 static AMS_Memory amsmemstack = -1;
22 
23 #undef __FUNCT__
24 #define __FUNCT__ "PetscStackAMSGrantAccess"
25 /*@C
26    PetscStackAMSGrantAccess - Grants access of the PETSc stack frames to the AMS publisher
27 
28    Collective on PETSC_COMM_WORLD?
29 
30    Level: developer
31 
32    Concepts: publishing object
33 
34    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscStackCallAMS() since it may be used within those routines
35 
36 .seealso: PetscObjectSetName(), PetscObjectAMSViewOff(), PetscObjectAMSTakeAccess()
37 
38 @*/
39 void  PetscStackAMSGrantAccess(void)
40 {
41   if (amsmemstack != -1) {
42     AMS_Memory_grant_access(amsmemstack);
43   }
44 }
45 
46 #undef __FUNCT__
47 #define __FUNCT__ "PetscStackAMSTakeAccess"
48 /*@C
49    PetscStackAMSTakeAccess - Takes access of the PETSc stack frames to the AMS publisher
50 
51    Collective on PETSC_COMM_WORLD?
52 
53    Level: developer
54 
55    Concepts: publishing object
56 
57    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscStackCallAMS() since it may be used within those routines
58 
59 .seealso: PetscObjectSetName(), PetscObjectAMSViewOff(), PetscObjectAMSTakeAccess()
60 
61 @*/
62 void  PetscStackAMSTakeAccess(void)
63 {
64   if (amsmemstack != -1) {
65     AMS_Memory_take_access(amsmemstack);
66   }
67 }
68 
69 PetscErrorCode PetscStackViewAMS(void)
70 {
71   AMS_Comm       acomm;
72   PetscErrorCode ierr;
73   AMS_Memory     mem;
74   PetscStack*    petscstackp;
75 
76   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
77   ierr = PetscViewerAMSGetAMSComm(PETSC_VIEWER_AMS_WORLD,&acomm);CHKERRQ(ierr);
78   PetscStackCallAMS(AMS_Memory_create,(acomm,"Stack",&mem));
79   PetscStackCallAMS(AMS_Memory_take_access,(mem));
80   PetscStackCallAMS(AMS_Memory_add_field,(mem,"functions",petscstackp->function,10,AMS_STRING,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
81   PetscStackCallAMS(AMS_Memory_add_field,(mem,"current size",&petscstackp->currentsize,1,AMS_INT,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
82   PetscStackCallAMS(AMS_Memory_publish,(mem));
83   PetscStackCallAMS(AMS_Memory_grant_access,(mem));
84   amsmemstack = mem;
85   return 0;
86 }
87 
88 #undef __FUNCT__
89 #define __FUNCT__ "PetscStackAMSViewOff"
90 PetscErrorCode PetscStackAMSViewOff(void)
91 {
92   PetscErrorCode ierr;
93 
94   PetscFunctionBegin;
95   if (amsmemstack == -1) PetscFunctionReturn(0);
96   ierr        = AMS_Memory_destroy(amsmemstack);CHKERRQ(ierr);
97   amsmemstack = -1;
98   PetscFunctionReturn(0);
99 }
100 
101 #  else
102 
103 /* AMS stack functions do nothing in optimized mode */
104 void PetscStackAMSGrantAccess(void) {}
105 void PetscStackAMSTakeAccess(void) {}
106 
107 PetscErrorCode PetscStackViewAMS(void)
108 {
109   return 0;
110 }
111 
112 #undef __FUNCT__
113 #define __FUNCT__ "PetscStackAMSViewOff"
114 PetscErrorCode  PetscStackAMSViewOff(void)
115 {
116   PetscFunctionBegin;
117   PetscFunctionReturn(0);
118 }
119 
120 #  endif
121 #endif
122 
123 PetscErrorCode PetscStackCreate(void)
124 {
125   PetscStack *petscstack_in;
126   if (PetscStackActive()) return 0;
127 
128   petscstack_in              = (PetscStack*)malloc(sizeof(PetscStack));
129   petscstack_in->currentsize = 0;
130   PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,petscstack_in);
131 
132 #if defined(PETSC_HAVE_AMS)
133   {
134   PetscBool flg = PETSC_FALSE;
135   PetscOptionsHasName(NULL,"-stack_view",&flg);
136   if (flg) PetscStackViewAMS();
137   }
138 #endif
139   return 0;
140 }
141 
142 
143 #undef __FUNCT__
144 #define __FUNCT__ "PetscStackView"
145 PetscErrorCode  PetscStackView(FILE *file)
146 {
147   int        i;
148   PetscStack *petscstackp;
149 
150   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
151   if (!file) file = PETSC_STDOUT;
152 
153   if (file == PETSC_STDOUT) {
154     (*PetscErrorPrintf)("Note: The EXACT line numbers in the stack are not available,\n");
155     (*PetscErrorPrintf)("      INSTEAD the line number of the start of the function\n");
156     (*PetscErrorPrintf)("      is given.\n");
157     for (i=petscstackp->currentsize-1; i>=0; i--) (*PetscErrorPrintf)("[%d] %s line %d %s%s\n",PetscGlobalRank,petscstackp->function[i],petscstackp->line[i],petscstackp->directory[i],petscstackp->file[i]);
158   } else {
159     fprintf(file,"Note: The EXACT line numbers in the stack are not available,\n");
160     fprintf(file,"      INSTEAD the line number of the start of the function\n");
161     fprintf(file,"      is given.\n");
162     for (i=petscstackp->currentsize-1; i>=0; i--) fprintf(file,"[%d] %s line %d %s%s\n",PetscGlobalRank,petscstackp->function[i],petscstackp->line[i],petscstackp->directory[i],petscstackp->file[i]);
163   }
164   return 0;
165 }
166 
167 PetscErrorCode PetscStackDestroy(void)
168 {
169   if (PetscStackActive()) {
170     PetscStack *petscstack_in;
171     petscstack_in = (PetscStack*)PetscThreadLocalGetValue(petscstack);
172     free(petscstack_in);
173     PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,NULL);
174   }
175   return 0;
176 }
177 
178 #undef __FUNCT__
179 #define __FUNCT__ "PetscStackCopy"
180 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
181 PetscErrorCode  PetscStackCopy(PetscStack *sint,PetscStack *sout)
182 {
183   int i;
184 
185   if (!sint) sout->currentsize = 0;
186   else {
187     for (i=0; i<sint->currentsize; i++) {
188       sout->function[i]     = sint->function[i];
189       sout->file[i]         = sint->file[i];
190       sout->directory[i]    = sint->directory[i];
191       sout->line[i]         = sint->line[i];
192       sout->petscroutine[i] = sint->petscroutine[i];
193     }
194     sout->currentsize = sint->currentsize;
195   }
196   return 0;
197 }
198 
199 #undef __FUNCT__
200 #define __FUNCT__ "PetscStackPrint"
201 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
202 PetscErrorCode  PetscStackPrint(PetscStack *sint,FILE *fp)
203 {
204   int i;
205 
206   if (!sint) return(0);
207   for (i=sint->currentsize-2; i>=0; i--) fprintf(fp,"      [%d]  %s() line %d in %s%s\n",PetscGlobalRank,sint->function[i],sint->line[i],sint->directory[i],sint->file[i]);
208   return 0;
209 }
210 
211