Skip to content

Commit a7465d4

Browse files
authored
Merge pull request #2216 from edwardhartnett/ejh_logging
Better handling of logging for parallel I/O builds
2 parents 53fdee6 + 4e4e167 commit a7465d4

File tree

6 files changed

+165
-98
lines changed

6 files changed

+165
-98
lines changed

libsrc4/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
# Process these files with m4.
88

99
SET(libsrc4_SOURCES nc4dispatch.c nc4attr.c nc4dim.c nc4grp.c
10-
nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c
11-
ncindex.c nc4cache.c)
10+
nc4internal.c nc4type.c nc4var.c ncfunc.c ncindex.c nc4cache.c)
1211

1312
add_library(netcdf4 OBJECT ${libsrc4_SOURCES})
1413

libsrc4/Makefile.am

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ libnetcdf4_la_CPPFLAGS = ${AM_CPPFLAGS}
1111
# This is our output. The netCDF-4 convenience library.
1212
noinst_LTLIBRARIES = libnetcdf4.la
1313
libnetcdf4_la_SOURCES = nc4dispatch.c nc4attr.c nc4dim.c nc4grp.c \
14-
nc4internal.c nc4type.c nc4var.c ncfunc.c error4.c \
15-
ncindex.c nc4cache.c
16-
14+
nc4internal.c nc4type.c nc4var.c ncfunc.c ncindex.c nc4cache.c
1715

1816
EXTRA_DIST = CMakeLists.txt

libsrc4/error4.c

-71
This file was deleted.

libsrc4/nc4internal.c

+159-17
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
#include "config.h"
1919
#include "netcdf.h"
2020
#include "netcdf_filter.h"
21+
#include "netcdf_meta.h"
2122
#include "nc4internal.h"
2223
#include "nc.h" /* from libsrc */
2324
#include "ncdispatch.h" /* from libdispatch */
2425
#include "ncutf8.h"
26+
#include <stdarg.h>
2527

2628
/** @internal Number of reserved attributes. These attributes are
2729
* hidden from the netcdf user, but exist in the implementation
@@ -58,12 +60,77 @@ float nc4_chunk_cache_preemption = CHUNK_CACHE_PREEMPTION; /**< Default chunk ca
5860

5961
static int NC4_move_in_NCList(NC* nc, int new_id);
6062

61-
#ifdef LOGGING
63+
#if NC_HAS_LOGGING
6264
/* This is the severity level of messages which will be logged. Use
6365
severity 0 for errors, 1 for important log messages, 2 for less
6466
important, etc. */
6567
int nc_log_level = NC_TURN_OFF_LOGGING;
66-
#endif /* LOGGING */
68+
#if NC_HAS_PARALLEL4
69+
/* File pointer for the parallel I/O log file. */
70+
FILE *LOG_FILE = NULL;
71+
#endif /* NC_HAS_PARALLEL4 */
72+
73+
/* This function prints out a message, if the severity of
74+
* the message is lower than the global nc_log_level. To use it, do
75+
* something like this:
76+
*
77+
* nc_log(0, "this computer will explode in %d seconds", i);
78+
*
79+
* After the first arg (the severity), use the rest like a normal
80+
* printf statement. Output will appear on stderr for sequential
81+
* builds, and in a file nc4_log_R.log for each process for a parallel
82+
* build, where R is the rank of the process.
83+
*
84+
* Ed Hartnett
85+
*/
86+
void
87+
nc_log(int severity, const char *fmt, ...)
88+
{
89+
va_list argp;
90+
int t;
91+
FILE *f = stderr;
92+
93+
/* If the severity is greater than the log level, we don't print
94+
* this message. */
95+
if (severity > nc_log_level)
96+
return;
97+
98+
#if NC_HAS_PARALLEL4
99+
/* For parallel I/O build, if MPI has been initialized, instead of
100+
* printing logging output to stderr, it goes to a file for each
101+
* process. */
102+
{
103+
int mpi_initialized;
104+
int mpierr;
105+
106+
/* Check to see if MPI has been initialized. */
107+
if ((mpierr = MPI_Initialized(&mpi_initialized)))
108+
return;
109+
110+
/* If MPI has been initialized use a log file. */
111+
assert(LOG_FILE);
112+
if (mpi_initialized)
113+
f = LOG_FILE;
114+
}
115+
#endif /* NC_HAS_PARALLEL4 */
116+
117+
/* If the severity is zero, this is an error. Otherwise insert that
118+
many tabs before the message. */
119+
if (!severity)
120+
fprintf(f, "ERROR: ");
121+
for (t = 0; t < severity; t++)
122+
fprintf(f, "\t");
123+
124+
/* Print out the variable list of args with vprintf. */
125+
va_start(argp, fmt);
126+
vfprintf(f, fmt, argp);
127+
va_end(argp);
128+
129+
/* Put on a final linefeed. */
130+
fprintf(f, "\n");
131+
fflush(f);
132+
}
133+
#endif /* NC_HAS_LOGGING */
67134

68135
/**
69136
* @internal Check and normalize and name.
@@ -1684,13 +1751,74 @@ nc4_normalize_name(const char *name, char *norm_name)
16841751
#ifdef ENABLE_SET_LOG_LEVEL
16851752

16861753
/**
1687-
* @internal Use this to set the global log level. Set it to
1688-
* NC_TURN_OFF_LOGGING (-1) to turn off all logging. Set it to 0 to
1689-
* show only errors, and to higher numbers to show more and more
1690-
* logging details. If logging is not enabled with --enable-logging at
1691-
* configure when building netCDF, this function will do nothing.
1692-
* Note that it is possible to set the log level using the environment
1693-
* variable named _NETCDF_LOG_LEVEL_ (e.g. _export NETCDF_LOG_LEVEL=4_).
1754+
* Initialize parallel I/O logging. For parallel I/O builds, open log
1755+
* file, if not opened yet, or increment ref count if already open.
1756+
*
1757+
* @author Ed Hartnett
1758+
*/
1759+
int
1760+
nc4_init_logging(void)
1761+
{
1762+
int ret = NC_NOERR;
1763+
1764+
#if NC_HAS_LOGGING
1765+
#if NC_HAS_PARALLEL4
1766+
if (!LOG_FILE && nc_log_level >= 0)
1767+
{
1768+
char log_filename[NC_MAX_NAME];
1769+
int my_rank = 0;
1770+
int mpierr;
1771+
int mpi_initialized;
1772+
1773+
/* If MPI has been initialized find the rank. */
1774+
if ((mpierr = MPI_Initialized(&mpi_initialized)))
1775+
return NC_EMPI;
1776+
if (mpi_initialized)
1777+
{
1778+
if ((mpierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_rank)))
1779+
return NC_EMPI;
1780+
}
1781+
1782+
/* Create a filename with the rank in it. */
1783+
sprintf(log_filename, "nc4_log_%d.log", my_rank);
1784+
1785+
/* Open a file for this rank to log messages. */
1786+
if (!(LOG_FILE = fopen(log_filename, "w")))
1787+
return NC_EINTERNAL;
1788+
}
1789+
#endif /* NC_HAS_PARALLEL4 */
1790+
#endif /* NC_HAS_LOGGING */
1791+
1792+
return ret;
1793+
}
1794+
1795+
/**
1796+
* Finalize logging - close parallel I/O log files, if open. This does
1797+
* nothing if logging is not enabled.
1798+
*
1799+
* @author Ed Hartnett
1800+
*/
1801+
void
1802+
nc4_finalize_logging(void)
1803+
{
1804+
#if NC_HAS_LOGGING
1805+
#if NC_HAS_PARALLEL4
1806+
if (LOG_FILE)
1807+
{
1808+
fclose(LOG_FILE);
1809+
LOG_FILE = NULL;
1810+
}
1811+
#endif /* NC_HAS_PARALLEL4 */
1812+
#endif /* NC_HAS_LOGGING */
1813+
}
1814+
1815+
/**
1816+
* Use this to set the global log level.
1817+
*
1818+
* Set it to NC_TURN_OFF_LOGGING (-1) to turn off all logging. Set it
1819+
* to 0 to show only errors, and to higher numbers to show more and
1820+
* more logging details. If logging is not enabled when building
1821+
* netCDF, this function will do nothing.
16941822
*
16951823
* @param new_level The new logging level.
16961824
*
@@ -1700,16 +1828,30 @@ nc4_normalize_name(const char *name, char *norm_name)
17001828
int
17011829
nc_set_log_level(int new_level)
17021830
{
1703-
#ifdef LOGGING
1831+
#if NC_HAS_LOGGING
17041832
/* Remember the new level. */
17051833
nc_log_level = new_level;
1706-
LOG((4, "log_level changed to %d", nc_log_level));
1707-
#endif /*LOGGING */
1708-
return 0;
1834+
1835+
#if NC_HAS_PARALLEL4
1836+
/* For parallel I/O builds, call the log init/finalize functions
1837+
* as needed, to open and close the log files. */
1838+
if (new_level >= 0)
1839+
{
1840+
if (!LOG_FILE)
1841+
nc4_init_logging();
1842+
}
1843+
else
1844+
nc4_finalize_logging();
1845+
#endif /* NC_HAS_PARALLEL4 */
1846+
1847+
LOG((1, "log_level changed to %d", nc_log_level));
1848+
#endif /*NC_HAS_LOGGING */
1849+
1850+
return NC_NOERR;
17091851
}
17101852
#endif /* ENABLE_SET_LOG_LEVEL */
17111853

1712-
#ifdef LOGGING
1854+
#if NC_HAS_LOGGING
17131855
#define MAX_NESTS 10
17141856
/**
17151857
* @internal Recursively print the metadata of a group.
@@ -1878,7 +2020,7 @@ log_metadata_nc(NC_FILE_INFO_T *h5)
18782020
return NC_NOERR;
18792021
}
18802022

1881-
#endif /*LOGGING */
2023+
#endif /*NC_HAS_LOGGING */
18822024

18832025
/**
18842026
* @internal Show the in-memory metadata for a netcdf file. This
@@ -1895,7 +2037,7 @@ int
18952037
NC4_show_metadata(int ncid)
18962038
{
18972039
int retval = NC_NOERR;
1898-
#ifdef LOGGING
2040+
#if NC_HAS_LOGGING
18992041
NC_FILE_INFO_T *h5;
19002042
int old_log_level = nc_log_level;
19012043

@@ -1907,7 +2049,7 @@ NC4_show_metadata(int ncid)
19072049
nc_log_level = 2;
19082050
retval = log_metadata_nc(h5);
19092051
nc_log_level = old_log_level;
1910-
#endif /*LOGGING*/
2052+
#endif /*NC_HAS_LOGGING*/
19112053
return retval;
19122054
}
19132055

nc_test4/tst_parallel5.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ main(int argc, char **argv)
5656
for (acc = 0; acc < NUM_ACCESS_TESTS; acc++)
5757
{
5858
/* Create a parallel netcdf-4 file. */
59-
/*nc_set_log_level(3);*/
59+
/* nc_set_log_level(3); */
6060
if (nc_create_par(FILE, NC_NETCDF4, comm, info, &ncid)) ERR;
6161

6262
/* Create a dimension. */
@@ -88,6 +88,7 @@ main(int argc, char **argv)
8888

8989
/* Close the netcdf file. */
9090
if (nc_close(ncid)) ERR;
91+
/* nc_set_log_level(-1); */
9192
}
9293
}
9394
if (!mpi_rank)
@@ -112,7 +113,6 @@ main(int argc, char **argv)
112113
unsigned long long data = 1000000, data_in = TEST_VAL_42;
113114

114115
/* Create a parallel netcdf-4 file. */
115-
/*nc_set_log_level(3);*/
116116
if (nc_create_par(FILE, NC_NETCDF4, comm, info, &ncid)) ERR;
117117

118118
/* Create a dimension. */
@@ -176,7 +176,6 @@ main(int argc, char **argv)
176176
int dim_size = NC_MAX_NAME + 1;
177177

178178
/* Create a parallel netcdf-4 file. */
179-
/*nc_set_log_level(3);*/
180179
if (nc_create_par(FILE, NC_NETCDF4, comm, info, &ncid)) ERR;
181180

182181
/* Create a dimension. */
@@ -368,7 +367,6 @@ main(int argc, char **argv)
368367
preemption != CHUNK_CACHE_PREEMPTION) ERR;
369368
if (nc_close(ncid)) ERR;
370369
}
371-
nc_set_log_level(0);
372370
}
373371
if (!mpi_rank)
374372
SUMMARIZE_ERR;

nc_test4/tst_vars4.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ main(int argc, char **argv)
3434
nc_type type_in;
3535
size_t len_in;
3636

37+
nc_set_log_level(3);
3738
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
3839
if (nc_def_dim(ncid, X_NAME, XDIM_LEN, &dims[0])) ERR;
3940
if (nc_def_dim(ncid, Y_NAME, YDIM_LEN, &dims[1])) ERR;
@@ -49,6 +50,7 @@ main(int argc, char **argv)
4950
if (strcmp(name_in, Y_NAME)) ERR;
5051
if (len_in != YDIM_LEN) ERR;
5152
if (nc_close(ncid)) ERR;
53+
nc_set_log_level(-1);
5254

5355
/* Open the file and check. */
5456
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
@@ -154,7 +156,6 @@ main(int argc, char **argv)
154156
int ndims, nvars, natts, unlimdimid;
155157

156158
/* Create the test file with two scalar vars. */
157-
/* nc_set_log_level(4); */
158159
if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR;
159160
if (nc_def_var(ncid, CLAIR, NC_INT, 0, NULL, &varid1)) ERR;
160161
if (nc_def_var(ncid, JAMIE, NC_INT, 0, NULL, &varid2)) ERR;

0 commit comments

Comments
 (0)