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