SIONlib  1.7.1
Scalable I/O library for parallel access to task-local files
sion_debug.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2016 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** See the file COPYRIGHT in the package base directory for details **
8 ****************************************************************************/
9 
40 #include <stdlib.h>
41 #include <stdarg.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include "sion_lock.h"
45 
46 #include "sion_debug.h"
47 #include "sion_internal.h"
48 
49 #define SIONDEBFUNCNAMELEN 50
50 #define MAXOMPTHREADS 300
51 
52 
53 int _sion_get_thread_num_default();
54 static int (*_sion_my_get_thread_num)() = _sion_get_thread_num_default;
55 
57 static int _sion_debug_first[MAXOMPTHREADS] = {1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
58  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
59  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
60  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
61  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
62 
63  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
64  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
65  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
66  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
67  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
68 
69  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
70  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
71  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
72  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1,
73  1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1};
74 
76 static FILE *_sion_debug_out[MAXOMPTHREADS] = {NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
77  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
78  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
79  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
80  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
81  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
82  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
83  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
84  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
85  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
86 
87  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
88  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
89  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
90  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
91  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
92  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
93  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
94  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
95  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
96  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
97 
98  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
99  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
100  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
101  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
102  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
103  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
104  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
105  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
106  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,
107  NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL};
108 
110 static int _sion_debug_isdebug[MAXOMPTHREADS] = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
111  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
112  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
113  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
114  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
115 
116  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
117  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
118  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
119  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
120  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
121 
122  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
123  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
124  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
125  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
126  0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
127 
129 static int _sion_debug_myrank[MAXOMPTHREADS] = {-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
130  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
131  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
132  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
133  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
134 
135  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
136  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
137  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
138  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
139  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
140 
141  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
142  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
143  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
144  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1,
145  -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1, -1,-1,-1,-1,-1};
146 
147 static int _sion_debug_debmask = 1023;
148 static int _sion_debug_debrank1 = -1;
149 static int _sion_debug_debrank2 = -1;
150 static int _sion_debug_silent = 0;
151 static int _sion_debug_isinit = 0;
152 static char * _sion_debug_fn = NULL;
154 #define _DEBUG_INIT_THREAD \
155  int threadid=0; \
156  threadid = _sion_my_get_thread_num(); \
157  if(threadid>MAXOMPTHREADS) threadid=(MAXOMPTHREADS-1);
158 
159 
160 /* default thread number */
161 int _sion_get_thread_num_default() {
162  return(0);
163 }
164 
165 /* default thread number */
166 int _sion_debug_set_query_thread_num_function( int (*get_thread_num)() ) {
167  _sion_lock();
168  _sion_my_get_thread_num=get_thread_num;
169  _sion_unlock();
170  return(1);
171 }
172 
177 int sion_dprintf(int mask, const char *format, ...)
178 {
179  va_list ap;
180  _DEBUG_INIT_THREAD
181 
182  if (_sion_debug_first[threadid])
184 
185  if ((!_sion_debug_isdebug[threadid]) || !(mask & _sion_debug_debmask))
186  return 1;
187 
188  fprintf(_sion_debug_out[threadid], " ");
189 
190  va_start(ap, format);
191 
192  vfprintf(_sion_debug_out[threadid], format, ap);
193 
194  va_end(ap);
195 
196  return 1;
197 }
198 
203 int sion_dprintfp(int mask, const char *callfunction, int rank, const char *format, ...)
204 {
205  va_list ap;
206  char tmpfuncname[SIONDEBFUNCNAMELEN + 1];
207  char spec[20];
208  int setrank = 0, norank = 0;
209  _DEBUG_INIT_THREAD
210 
211  if ((_sion_debug_myrank[threadid] < 0) && (rank < 0)) {
212  return (0);
213  }
214 
215  /* no rank specified, used previous stored rank */
216  if (rank < 0) {
217  rank = _sion_debug_myrank[threadid];
218  norank = 1;
219  }
220 
221  /* if internal rank is not initialized used rank parameter, otherwise don't overwrite it */
222  if (_sion_debug_myrank[threadid] < 0) {
223  _sion_debug_myrank[threadid] = rank;
224  setrank = 1;
225  }
226  /* if(setrank) */
227  /* fprintf(stderr,"WF: in sion_dprintfp: mask=%d %s rank=%d myrank=%d setrank=%d norank=%d first=%d\n",mask,callfunction,rank,myrank,setrank,norank,_sion_debug_first); */
228 
229  if (_sion_debug_first[threadid])
231 
232  /* fprintf(stderr,"WF: in sion_dprintfp: mask=%d %s rank=%d debmask=%d and=%d\n",mask,callfunction,rank,debmask,mask & debmask); */
233 
234  if ((!_sion_debug_isdebug[threadid]) || !(mask & _sion_debug_debmask))
235  return 1;
236  if ((_sion_debug_debrank1 >= 0) && (_sion_debug_debrank2 >= 0)) {
237  if ((rank != _sion_debug_debrank1) && (rank != _sion_debug_debrank2))
238  return 1;
239  }
240  else if (_sion_debug_debrank1 >= 0) {
241  if (rank != _sion_debug_debrank1)
242  return 1;
243  }
244 
245  if (strlen(callfunction) > SIONDEBFUNCNAMELEN) {
246  strncpy(tmpfuncname, callfunction, SIONDEBFUNCNAMELEN);
247  tmpfuncname[SIONDEBFUNCNAMELEN] = '\0';
248  }
249  else
250  strcpy(tmpfuncname, callfunction);
251 
252  sprintf(spec, "SION[%s%s%%5d][%%-%ds] ", (setrank ? "S" : " "), (norank ? "N" : " "), SIONDEBFUNCNAMELEN);
253  fprintf(_sion_debug_out[threadid], spec, rank, tmpfuncname);
254  if (mask >= 8)
255  fprintf(_sion_debug_out[threadid], " ");
256  if (mask > 64)
257  fprintf(_sion_debug_out[threadid], " ");
258  if (mask >= 128)
259  fprintf(_sion_debug_out[threadid], " ");
260 
261  va_start(ap, format);
262 
263  vfprintf(_sion_debug_out[threadid], format, ap);
264 
265  va_end(ap);
266 
267  fflush(_sion_debug_out[threadid]);
268 
269  return 1;
270 }
271 
275 FILE *sion_get_dfile(void)
276 {
277  _DEBUG_INIT_THREAD
278  if (_sion_debug_first[threadid])
280 
281  return _sion_debug_out[threadid];
282 }
283 
287 void sion_dclose(void)
288 {
289  _DEBUG_INIT_THREAD
290  if (_sion_debug_out[threadid] && (_sion_debug_out[threadid] != stdout) && (_sion_debug_out[threadid] != stderr)) {
291  fclose(_sion_debug_out[threadid]);
292  _sion_debug_out[threadid] = NULL;
293  _sion_debug_first[threadid] = 1;
294  }
295 }
296 
297 int sion_isdebug(void)
298 {
299  _DEBUG_INIT_THREAD
300  if (_sion_debug_first[threadid])
302 
303  return _sion_debug_isdebug[threadid] ? _sion_debug_debmask : 0;
304 }
305 
306 
313 void sion_debug_on(int mask, const char *filename)
314 {
315  char *fname = 0;
316  _DEBUG_INIT_THREAD
317 
318  if (_sion_debug_out[threadid])
319  sion_dclose(); /* close previously opened logfile */
320 
321  _sion_debug_first[threadid] = 0; /* do not call _sion_debug_init() */
322 
323  if (filename) {
324  fname = (char *) malloc((strlen(filename) + 1) * sizeof(char));
325  strcpy(fname, filename);
326  }
327 
328  /* open debug output file (default is stderr) */
329  if (!fname || (strlen(fname) == 0) || !strcmp(fname, "stderr")) {
330  _sion_debug_out[threadid] = stderr;
331  }
332  else if (!strcmp(fname, "stdout")) {
333  _sion_debug_out[threadid] = stdout;
334  }
335  else if (!(_sion_debug_out[threadid] = fopen(fname, "w"))) {
336  fprintf(stderr, "sion_dprintf: failed to open '%s' for writing\n", fname);
337  _sion_debug_out[threadid] = stderr;
338  }
339 
340 #ifdef SION_DEBUG_EXTREME
341  fprintf(stderr, "Warning: you are using a version of SION that is configured with -DEBUG (current debug-mask is %d\n", debmask);
342 #endif
343 
344  if ((_sion_debug_out[threadid] != stdout) && (_sion_debug_out[threadid] != stderr))
345  fprintf(stderr, "Writing debug output to %s\n", fname);
346 
347  if (fname)
348  free(fname);
349 
350  _sion_debug_debmask = mask;
351  _sion_debug_isdebug[threadid] = 1;
352 }
353 
354 void sion_debug_off(void)
355 {
356  _DEBUG_INIT_THREAD
357  _sion_debug_isdebug[threadid] = 0;
358  sion_dclose();
359 }
360 
361 
370 {
371  int rvalue = 1;
372  _DEBUG_INIT_THREAD
373  {
374  if (_sion_debug_first[threadid]) {
375  char *filename = 0;
376 
377  _sion_debug_first[threadid] = 0;
378  _sion_debug_isdebug[threadid] = 0;
379 
380  /* get info from environment only once */
381  _sion_lock();
382  if(_sion_debug_isinit) {
383  _sion_unlock();
384  } else {
385  const char *t;
386 
387  t = _sion_getenv("SION_DEBUG_RANK");
388  if (t)
389  _sion_debug_debrank1 = atoi(t);
390 
391  t = _sion_getenv("SION_DEBUG_RANK1");
392  if (t)
393  _sion_debug_debrank1 = atoi(t);
394 
395  t = _sion_getenv("SION_DEBUG_RANK2");
396  if (t)
397  _sion_debug_debrank2 = atoi(t);
398 
399  t = _sion_getenv("SION_DEBUG");
400  if (t) {
401  _sion_debug_fn = (char *) t;
402  }
403 
404  t = _sion_getenv("SION_DEBUG_MASK");
405  if (t)
406  _sion_debug_debmask = atoi(t);
407 
408  t = _sion_getenv("SION_DEBUG_SILENT");
409  if (t)
410  _sion_debug_silent = atoi(t);
411 
412  _sion_debug_isinit=1;
413  _sion_unlock();
414  }
415 
416  if (_sion_debug_fn) {
417  _sion_debug_isdebug[threadid] = 1; /* set debug mode if SION_DEBUG ist set */
418  }
419 
420  if ((_sion_debug_debrank1 >= 0) && (_sion_debug_debrank2 >= 0)) {
421  if ((_sion_debug_myrank[threadid] != _sion_debug_debrank1) && (_sion_debug_myrank[threadid] != _sion_debug_debrank2))
422  _sion_debug_isdebug[threadid] = 0;
423  }
424  else if (_sion_debug_debrank1 >= 0) {
425  if (_sion_debug_myrank[threadid] != _sion_debug_debrank1)
426  _sion_debug_isdebug[threadid] = 0;
427  }
428 
429  if ((_sion_debug_debrank1 == -2) && (_sion_debug_debrank2 == -2)) {
430  _sion_debug_isdebug[threadid] = 1;
431  }
432  if (_sion_debug_isdebug[threadid]) {
433 
434  if ((_sion_debug_fn == 0) || (strlen(_sion_debug_fn) == 0) || !strcmp(_sion_debug_fn, "stderr")) {
435  _sion_debug_out[threadid] = stderr;
436  }
437  else if (!strcmp(_sion_debug_fn, "stdout")) {
438  _sion_debug_out[threadid] = stdout;
439  }
440  else {
441  filename=malloc((strlen(_sion_debug_fn) + 1 + 10) * sizeof(char));
442  sprintf(filename, "%s.%05d", _sion_debug_fn, _sion_debug_myrank[threadid]);
443 
444  if (!(_sion_debug_out[threadid] = fopen(filename, "a"))) {
445  fprintf(_sion_debug_out[threadid], "sion_dprintf: failed to open '%s' for writing\n", filename);
446  rvalue = 0;
447  }
448 
449  if( rvalue && ((_sion_debug_out[threadid] != stdout) && (_sion_debug_out[threadid] != stderr)) && (!_sion_debug_silent) )
450  fprintf(stderr, "Writing debug output to %s\n", filename);
451 
452  }
453 
454  if (filename) free(filename);
455 
456  /* print a warning (to avoid using accidentally
457  a library that is full of DPRINTFs) */
458 #ifdef SION_DEBUG_EXTREME
459  fprintf(stderr, "Warning: you are using a version of SION that is configured with --with-debug (current debug-mask is %d)\n", _sion_debug_debmask);
460 #endif
461 
462  } /* _sion_debug_isdebug[threadid] */
463 
464  } /* _sion_debug_first[threadid] */
465 
466  }
467 
468  return rvalue;
469 }
void sion_debug_on(int mask, const char *filename)
sets debug mode.
Definition: sion_debug.c:313
int sion_dprintf(int mask, const char *format,...)
Print debugging info formating the message like printf.
Definition: sion_debug.c:177
void sion_dclose(void)
Definition: sion_debug.c:287
char * _sion_getenv(const char *name)
int _sion_debug_init(void)
initialize the debug environment
Definition: sion_debug.c:369
int sion_dprintfp(int mask, const char *callfunction, int rank, const char *format,...)
Print debugging info formating the message like printf and including the name of the calling function...
Definition: sion_debug.c:203
FILE * sion_get_dfile(void)
Definition: sion_debug.c:275