From b312291c23c62b2f8773c7819ea84eeb9411a7c6 Mon Sep 17 00:00:00 2001 From: Ed Hartnett Date: Tue, 10 May 2016 13:11:14 -0400 Subject: [PATCH] added logging --- CMakeLists.txt | 9 +++ src/clib/config.h.in | 3 + src/clib/pio.h | 2 +- src/clib/pio_internal.h | 6 ++ src/clib/pio_msg.c | 6 ++ src/clib/pio_nc_async.c | 126 +++++++++++++++++++++++++----------- tests/unit/test_intercomm.c | 7 +- 7 files changed, 118 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b284128d2da6..b13a09dbebb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,18 +15,27 @@ mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH) option (PIO_ENABLE_FORTRAN "Enable the Fortran library builds" ON) option (PIO_ENABLE_TIMING "Enable the use of the GPTL timing library" ON) option (PIO_ENABLE_ASYNC "Enable the use of asychronus IO operations" OFF) +option (PIO_ENABLE_LOGGING "Enable debug logging (large output possible)" OFF) option (PIO_TEST_BIG_ENDIAN "Enable test to see if machine is big endian" ON) option (PIO_USE_MPIIO "Enable support for MPI-IO auto detect" ON) option (PIO_USE_MPISERIAL "Enable mpi-serial support (instead of MPI)" OFF) option (PIO_USE_MALLOC "Use native malloc (instead of bget package)" OFF) option (WITH_PNETCDF "Require the use of PnetCDF" ON) +# Set a variable that appears in the config.h.in file. if(PIO_USE_MALLOC) set(USE_MALLOC 1) else() set(USE_MALLOC 0) endif() +# Set a variable that appears in the config.h.in file. +if(PIO_ENABLE_LOGGING) + set(ENABLE_LOGGING 1) +else() + set(ENABLE_LOGGING 0) +endif() + #===== Library Variables ===== set (PIO_FILESYSTEM_HINTS IGNORE CACHE STRING "Filesystem hints (lustre or gpfs)") diff --git a/src/clib/config.h.in b/src/clib/config.h.in index e4be61d9e0c7..1722872c3056 100644 --- a/src/clib/config.h.in +++ b/src/clib/config.h.in @@ -19,4 +19,7 @@ * will use the included bget() package for memory management. */ #define PIO_USE_MALLOC @USE_MALLOC@ +/** Set to non-zero to turn on logging. Output may be large. */ +#define PIO_ENABLE_LOGGING @ENABLE_LOGGING@ + #endif /* _PIO_CONFIG_ */ diff --git a/src/clib/pio.h b/src/clib/pio.h index e96f754e57e7..44507edcdc71 100644 --- a/src/clib/pio.h +++ b/src/clib/pio.h @@ -647,7 +647,7 @@ int PIOc_set_blocksize(const int newblocksize); int PIOc_get_varm_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned long long *buf); int PIOc_get_var_schar (int ncid, int varid, signed char *buf); int PIOc_iotype_available(const int iotype); - + int PIOc_set_log_level(int level); #if defined(__cplusplus) } #endif diff --git a/src/clib/pio_internal.h b/src/clib/pio_internal.h index 3dbd28b61856..78297f54f9e7 100644 --- a/src/clib/pio_internal.h +++ b/src/clib/pio_internal.h @@ -17,6 +17,12 @@ #include #endif +#ifdef PIO_ENABLE_LOGGING +void nc_log(int severity, const char *fmt, ...); +#define LOG(e) pio_log e +#else +#define LOG(e) +#endif /* PIO_ENABLE_LOGGING */ #define max(a,b) \ ({ __typeof__ (a) _a = (a); \ diff --git a/src/clib/pio_msg.c b/src/clib/pio_msg.c index 58cfb9ffba8e..e29c6b769af6 100644 --- a/src/clib/pio_msg.c +++ b/src/clib/pio_msg.c @@ -7,9 +7,15 @@ * @see http://code.google.com/p/parallelio/ */ +#include #include #include +#ifdef PIO_ENABLE_LOGGING +extern int my_rank; +extern int pio_log_level; +#endif /* PIO_ENABLE_LOGGING */ + /** This function is run on the IO tasks to create a netCDF file. */ int create_file_handler(iosystem_desc_t *ios) { diff --git a/src/clib/pio_nc_async.c b/src/clib/pio_nc_async.c index f0830c17a078..144a5a2095fa 100644 --- a/src/clib/pio_nc_async.c +++ b/src/clib/pio_nc_async.c @@ -15,9 +15,80 @@ * @date Feburary 2014, April 2016 */ +#include +#ifdef PIO_ENABLE_LOGGING +#include +#endif /* PIO_ENABLE_LOGGING */ #include #include +#ifdef PIO_ENABLE_LOGGING +int pio_log_level = 0; +int my_rank; +#endif /* PIO_ENABLE_LOGGING */ + +/** Set the logging level. Set to -1 for nothing, 0 for errors only, 1 + * for important logging, and so on. Log levels below 1 are only + * printed on the io/component root. If the library is not built with + * logging, this function does nothing. */ +int PIOc_set_log_level(int level) +{ +#ifdef PIO_ENABLE_LOGGING + printf("setting log level to %d\n", level); + pio_log_level = level; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + return PIO_NOERR; +#endif /* PIO_ENABLE_LOGGING */ +} + +#ifdef PIO_ENABLE_LOGGING +/** This function prints out a message, if the severity of the message + is lower than the global pio_log_level. To use it, do something + like this: + + pio_log(0, "this computer will explode in %d seconds", i); + + After the first arg (the severity), use the rest like a normal + printf statement. Output will appear on stdout. + This function is heavily based on the function in section 15.5 of + the C FAQ. +*/ +void +pio_log(int severity, const char *fmt, ...) +{ + va_list argp; + int t; + + /* If the severity is greater than the log level, we don't print + this message. */ + if (severity > pio_log_level) + return; + + /* If the severity is 1 or less, only print on rank 0. */ + if (severity < 2 && my_rank != 0) + return; + + /* If the severity is zero, this is an error. Otherwise insert that + many tabs before the message. */ + if (!severity) + fprintf(stdout, "ERROR: "); + for (t = 0; t < severity; t++) + fprintf(stdout, "\t"); + + /* Show the rank. */ + fprintf(stdout, "%d ", my_rank); + + /* Print out the variable list of args with vprintf. */ + va_start(argp, fmt); + vfprintf(stdout, fmt, argp); + va_end(argp); + + /* Put on a final linefeed. */ + fprintf(stdout, "\n"); + fflush(stdout); +} +#endif /* PIO_ENABLE_LOGGING */ + /** * @ingroup PIOc_inq * The PIO-C interface for the NetCDF function nc_inq. @@ -44,10 +115,7 @@ int PIOc_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, int ierr = PIO_NOERR; /** Return code from function calls. */ int mpierr; /** Return code from MPI function codes. */ - /* For debugging purposes. */ - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_inq ncid = %d\n", my_rank, ncid); + LOG((1, "PIOc_inq ncid = %d", ncid)); /* Find the info about this file. */ if (!(file = pio_get_file_from_id(ncid))) @@ -67,15 +135,11 @@ int PIOc_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, if(ios->compmaster) mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast ncid = %d\n", my_rank, file->fh); mpierr = MPI_Bcast(&ndims_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast ndims_present = %d\n", my_rank, ndims_present); mpierr = MPI_Bcast(&nvars_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast nvars_present = %d\n", my_rank, nvars_present); mpierr = MPI_Bcast(&ngatts_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast ngatts_present = %d\n", my_rank, ngatts_present); mpierr = MPI_Bcast(&unlimdimid_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast unlimdimid_present = %d\n", my_rank, unlimdimid_present); + LOG((2, "PIOc_inq netcdf Bcast unlimdimid_present = %d", unlimdimid_present)); } /* If this is an IO task, then call the netCDF function. */ @@ -132,22 +196,22 @@ int PIOc_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, if (ndimsp) { mpierr = MPI_Bcast(ndimsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - printf("%d PIOc__inq bcast ndims = %d\n", my_rank, *ndimsp); + LOG((2, "PIOc__inq bcast ndims = %d\n", *ndimsp)); } if(nvarsp) { mpierr = MPI_Bcast(nvarsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - printf("%d PIOc__inq bcast nvars = %d\n", my_rank, *nvarsp); + LOG((2, "%d PIOc__inq bcast nvars = %d\n", my_rank, *nvarsp)); } if(ngattsp) { mpierr = MPI_Bcast(ngattsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - printf("%d PIOc__inq bcast ngatts = %d\n", my_rank, *ngattsp); + LOG((2, "%d PIOc__inq bcast ngatts = %d\n", my_rank, *ngattsp)); } if(unlimdimidp) { mpierr = MPI_Bcast(unlimdimidp, 1, MPI_INT, ios->ioroot, ios->my_comm); - printf("%d PIOc__inq bcast unlimdimid = %d\n", my_rank, *unlimdimidp); + LOG((2, "%d PIOc__inq bcast unlimdimid = %d\n", my_rank, *unlimdimidp)); } if(errstr) @@ -171,9 +235,7 @@ int PIOc_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, */ int PIOc_inq_ndims (int ncid, int *ndimsp) { - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d calling PIOc_inq_ndims\n", my_rank); + LOG((1, "PIOc_inq_ndims")); return PIOc_inq(ncid, ndimsp, NULL, NULL, NULL); } @@ -552,7 +614,7 @@ int PIOc_def_var (int ncid, const char *name, nc_type xtype, int ndims, mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); mpierr = MPI_Bcast(&(file->fh), 1, MPI_INT, ios->compmaster, ios->intercomm); namelen = strlen(name); - printf("bcasting namelen = %d name = %s\n", namelen, name); + LOG((2, "bcasting namelen = %d name = %s\n", namelen, name)); if (!ios->compmaster) ios->compmaster = MPI_PROC_NULL; mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); @@ -700,10 +762,7 @@ int PIOc_inq_dim(int ncid, int dimid, char *name, PIO_Offset *lenp) int msg = PIO_MSG_INQ_DIM; int mpierr; - /* For debugging purposes only... */ - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_inq_dim\n", my_rank); + LOG((1, "PIOc_inq_dim")); /* Get the file info, based on the ncid. */ if (!(file = pio_get_file_from_id(ncid))) @@ -720,9 +779,9 @@ int PIOc_inq_dim(int ncid, int dimid, char *name, PIO_Offset *lenp) mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&dimid, 1, MPI_INT, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast name_present = %d\n", my_rank, name_present); + LOG((2, "PIOc_inq netcdf Bcast name_present = %d", name_present)); mpierr = MPI_Bcast(&len_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq netcdf Bcast len_present = %d\n", my_rank, len_present); + LOG((2, "PIOc_inq netcdf Bcast len_present = %d", len_present)); } /* Make the call to the netCDF layer. */ @@ -1221,9 +1280,7 @@ int PIOc_inq_varid (int ncid, const char *name, int *varidp) ios = file->iosystem; msg = PIO_MSG_INQ_VARID; - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_inq_varid ncid = %d name = %s\n", my_rank, ncid, name); + LOG((1, "PIOc_inq_varid ncid = %d name = %s", ncid, name)); if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -1232,11 +1289,8 @@ int PIOc_inq_varid (int ncid, const char *name, int *varidp) mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); int namelen; namelen = strlen(name); - printf("%d PIOc_inq_varid BCast namelen = %d\n", my_rank, namelen); mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq_varid BCast name = %s\n", my_rank, name); mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq_varid BCast done\n", my_rank); } if(ios->ioproc){ @@ -1490,16 +1544,12 @@ int PIOc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, int msg = PIO_MSG_INQ_VAR; int mpierr; - /* For debugging purposes only... */ - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_inq_var\n", my_rank); + LOG((1, "PIOc_inq_var\n")); /* Get the file info, based on the ncid. */ if (!(file = pio_get_file_from_id(ncid))) return PIO_EBADID; ios = file->iosystem; - printf("%d PIOc_inq_var got file\n", my_rank); /* If using async, and this is not an IO task, send the parameters to the IO task. */ if (ios->async_interface && !ios->ioproc) @@ -1512,19 +1562,17 @@ int PIOc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, if(ios->compmaster) mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq_var ncid = %d\n", my_rank, ncid); mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&xtype_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&ndims_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&dimids_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast(&natts_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq_var name_present = %d xtype_present = %d ndims_present = %d dimids_present = %d, natts_present = %d nattsp = %d\n", - my_rank, name_present, xtype_present, ndims_present, dimids_present, natts_present, nattsp); + LOG((2, "PIOc_inq_var name_present = %d xtype_present = %d ndims_present = %d " + "dimids_present = %d, natts_present = %d nattsp = %d", + name_present, xtype_present, ndims_present, dimids_present, natts_present, nattsp)); } - printf("%d PIOc_inq_var ios->ioproc = %d nattsp = %d\n", my_rank, ios->ioproc, nattsp); - /* Call the netCDF layer. */ if (ios->ioproc) { diff --git a/tests/unit/test_intercomm.c b/tests/unit/test_intercomm.c index dbbc6c39e93f..6ab8cb03186c 100644 --- a/tests/unit/test_intercomm.c +++ b/tests/unit/test_intercomm.c @@ -321,7 +321,12 @@ main(int argc, char **argv) comp_task = 0; } - + + /* Turn on logging. */ + if ((ret = PIOc_set_log_level(2))) + ERR(ret); + + /* Initialize the async setup. */ if ((ret = PIOc_Init_Intercomm(COMPONENT_COUNT, MPI_COMM_WORLD, &comp_comms, io_comm, &iosysid))) ERR(ret);