Commit ac263795 authored by Shane Snyder's avatar Shane Snyder

Merge remote-tracking branch 'origin/dev-bgq-mod' into dev-modular

parents 3e3d2df8 7e0566b7
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef __DARSHAN_BGQ_LOG_FORMAT_H
#define __DARSHAN_BGQ_LOG_FORMAT_H
#include "darshan-log-format.h"
#define BGQ_COUNTERS \
X(BGQ_CSJOBID, "control system jobid") \
X(BGQ_NNODES, "number of BGQ compute nodes") \
X(BGQ_RANKSPERNODE, "number of MPI ranks per node") \
X(BGQ_DDRPERNODE, "size in MB of DDR3 per node") \
X(BGQ_INODES, "number of i/o nodes") \
X(BGQ_ANODES, "dimension of A torus") \
X(BGQ_BNODES, "dimension of B torus") \
X(BGQ_CNODES, "dimension of C torus") \
X(BGQ_DNODES, "dimension of D torus") \
X(BGQ_ENODES, "dimension of E torus") \
X(BGQ_TORUSENABLED, "which dimensions are torus") \
X(BGQ_NUM_INDICES, "end of counters")
#define BGQ_F_COUNTERS \
X(BGQ_F_TIMESTAMP, "timestamp when data was collected") \
X(BGQ_F_NUM_INDICES, "end of counters")
#define X(a, b) a,
/* integer counters for the "BGQ" example module */
enum darshan_bgq_indices
{
BGQ_COUNTERS
};
/* floating point counters for the "BGQ" example module */
enum darshan_bgq_f_indices
{
BGQ_F_COUNTERS
};
#undef X
/* the darshan_bgq_record structure encompasses the high-level data/counters
* which would actually be logged to file by Darshan for the "BGQ" example
* module. This example implementation logs the following data for each
* record:
* - a corresponding Darshan record identifier
* - the rank of the process responsible for the record
* - integer I/O counters (operation counts, I/O sizes, etc.)
* - floating point I/O counters (timestamps, cumulative timers, etc.)
*/
struct darshan_bgq_record
{
darshan_record_id f_id;
int64_t rank;
int alignment;
int64_t counters[BGQ_NUM_INDICES];
double fcounters[BGQ_F_NUM_INDICES];
};
#endif /* __DARSHAN_BGQ_LOG_FORMAT_H */
...@@ -48,7 +48,8 @@ ...@@ -48,7 +48,8 @@
X(DARSHAN_POSIX_MOD, "POSIX", posix_logutils) \ X(DARSHAN_POSIX_MOD, "POSIX", posix_logutils) \
X(DARSHAN_MPIIO_MOD, "MPI-IO", mpiio_logutils) \ X(DARSHAN_MPIIO_MOD, "MPI-IO", mpiio_logutils) \
X(DARSHAN_HDF5_MOD, "HDF5", hdf5_logutils) \ X(DARSHAN_HDF5_MOD, "HDF5", hdf5_logutils) \
X(DARSHAN_PNETCDF_MOD, "PNETCDF", pnetcdf_logutils) X(DARSHAN_PNETCDF_MOD, "PNETCDF", pnetcdf_logutils) \
X(DARSHAN_BGQ_MOD, "BG/Q", bgq_logutils)
/* unique identifiers to distinguish between available darshan modules */ /* unique identifiers to distinguish between available darshan modules */
/* NOTES: - valid ids range from [0...DARSHAN_MAX_MODS-1] /* NOTES: - valid ids range from [0...DARSHAN_MAX_MODS-1]
......
...@@ -69,6 +69,15 @@ lib/darshan-mpiio.o: lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdi ...@@ -69,6 +69,15 @@ lib/darshan-mpiio.o: lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdi
lib/darshan-mpiio.po: lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib lib/darshan-mpiio.po: lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@ $(CC) $(CFLAGS_SHARED) -c $< -o $@
#
# BG/Q module
#
lib/darshan-bgq.o: lib/darshan-bgq.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-bgq.po: lib/darshan-bgq.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-hdf5.o: lib/darshan-hdf5.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-hdf5-log-format.h | lib lib/darshan-hdf5.o: lib/darshan-hdf5.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-hdf5-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
...@@ -99,14 +108,15 @@ lib/lookup8.o: lib/lookup8.c ...@@ -99,14 +108,15 @@ lib/lookup8.o: lib/lookup8.c
lib/lookup8.po: lib/lookup8.c lib/lookup8.po: lib/lookup8.c
$(CC) $(CFLAGS_SHARED) -c $< -o $@ $(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/libdarshan.a: lib/darshan-core-init-finalize.o lib/darshan-core.o lib/darshan-common.o lib/darshan-posix.o lib/darshan-mpiio.o lib/darshan-hdf5.o lib/darshan-pnetcdf.o lib/lookup3.o lib/lookup8.o lib/libdarshan.a: lib/darshan-core-init-finalize.o lib/darshan-core.o lib/darshan-common.o lib/darshan-posix.o lib/darshan-mpiio.o lib/darshan-hdf5.o lib/darshan-pnetcdf.o lib/darshan-bgq.o lib/lookup3.o lib/lookup8.o
ar rcs $@ $^ ar rcs $@ $^
lib/libdarshan.so: lib/darshan-core-init-finalize.po lib/darshan-core.po lib/darshan-common.po lib/darshan-posix.po lib/darshan-mpiio.po lib/darshan-pnetcdf.po lib/darshan-bgq.po lib/lookup3.po lib/lookup8.po
$(CC) $(CFLAGS_SHARED) $(LDFLAGS) -o $@ $^ -lpthread -lrt -lz -ldl
lib/libdarshan-stubs.a: lib/darshan-hdf5-stubs.o lib/darshan-pnetcdf-stubs.o lib/libdarshan-stubs.a: lib/darshan-hdf5-stubs.o lib/darshan-pnetcdf-stubs.o
ar rcs $@ $^ ar rcs $@ $^
lib/libdarshan.so: lib/darshan-core-init-finalize.po lib/darshan-core.po lib/darshan-common.po lib/darshan-posix.po lib/darshan-mpiio.po lib/darshan-hdf5.po lib/darshan-pnetcdf.po lib/lookup3.po lib/lookup8.po
$(CC) $(CFLAGS_SHARED) $(LDFLAGS) -o $@ $^ -lpthread -lrt -lz -ldl
install:: all install:: all
install -d $(libdir) install -d $(libdir)
......
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE
#include "darshan-runtime-config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "uthash.h"
#include "darshan.h"
#include "darshan-bgq-log-format.h"
#ifdef __bgq__
#include <spi/include/kernel/location.h>
#include <spi/include/kernel/process.h>
#include <firmware/include/personality.h>
#endif
/*
* Simple module which captures BG/Q hardware specific information about
* the job.
*
* This module does not intercept any system calls. It just pulls data
* from the personality struct at initialization.
*/
/*
* Global runtime struct for tracking data needed at runtime
*/
struct bgq_runtime
{
struct darshan_bgq_record record;
};
static struct bgq_runtime *bgq_runtime = NULL;
static pthread_mutex_t bgq_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
/* the instrumentation_disabled flag is used to toggle functions on/off */
static int instrumentation_disabled = 0;
/* my_rank indicates the MPI rank of this process */
static int my_rank = -1;
static int darshan_mem_alignment = 1;
/* internal helper functions for the "NULL" module */
void bgq_runtime_initialize(void);
/* forward declaration for module functions needed to interface with darshan-core */
static void bgq_begin_shutdown(void);
static void bgq_get_output_data(MPI_Comm mod_comm, darshan_record_id *shared_recs, int shared_rec_count, void **buffer, int *size);
static void bgq_shutdown(void);
static void bgq_setup_reduction(darshan_record_id *shared_recs,int *shared_rec_count,void **send_buf,void **recv_buf,int *rec_size);
static void bgq_record_reduction_op(void* infile_v,void* inoutfile_v,int *len,MPI_Datatype *datatype);
/* macros for obtaining/releasing the "NULL" module lock */
#define BGQ_LOCK() pthread_mutex_lock(&bgq_runtime_mutex)
#define BGQ_UNLOCK() pthread_mutex_unlock(&bgq_runtime_mutex)
/*
* Function which updates all the counter data
*/
static void capture(struct darshan_bgq_record *rec)
{
#ifdef __bgq__
Personality_t person;
int r;
rec->counters[BGQ_CSJOBID] = Kernel_GetJobID();
rec->counters[BGQ_RANKSPERNODE] = Kernel_ProcessCount();
rec->counters[BGQ_INODES] = MPIX_IO_node_id();
r = Kernel_GetPersonality(&person, sizeof(person));
if (r == 0)
{
rec->counters[BGQ_NNODES] = ND_TORUS_SIZE(person.Network_Config);
rec->counters[BGQ_ANODES] = person.Network_Config.Anodes;
rec->counters[BGQ_BNODES] = person.Network_Config.Bnodes;
rec->counters[BGQ_CNODES] = person.Network_Config.Cnodes;
rec->counters[BGQ_DNODES] = person.Network_Config.Dnodes;
rec->counters[BGQ_ENODES] = person.Network_Config.Enodes;
rec->counters[BGQ_TORUSENABLED] =
(((person.Network_Config.NetFlags & ND_ENABLE_TORUS_DIM_A) == ND_ENABLE_TORUS_DIM_A) << 0) |
(((person.Network_Config.NetFlags & ND_ENABLE_TORUS_DIM_B) == ND_ENABLE_TORUS_DIM_B) << 1) |
(((person.Network_Config.NetFlags & ND_ENABLE_TORUS_DIM_C) == ND_ENABLE_TORUS_DIM_C) << 2) |
(((person.Network_Config.NetFlags & ND_ENABLE_TORUS_DIM_D) == ND_ENABLE_TORUS_DIM_D) << 3) |
(((person.Network_Config.NetFlags & ND_ENABLE_TORUS_DIM_E) == ND_ENABLE_TORUS_DIM_E) << 4);
rec->counters[BGQ_DDRPERNODE] = person.DDR_Config.DDRSizeMB;
}
#endif
rec->rank = my_rank;
rec->fcounters[BGQ_F_TIMESTAMP] = darshan_core_wtime();
return;
}
/**********************************************************
* Internal functions for manipulating BGQ module state *
**********************************************************/
void bgq_runtime_initialize()
{
/* struct of function pointers for interfacing with darshan-core */
struct darshan_module_funcs bgq_mod_fns =
{
.begin_shutdown = bgq_begin_shutdown,
.get_output_data = bgq_get_output_data,
.shutdown = bgq_shutdown
};
int mem_limit;
char *recname = "darshan-internal-bgq";
BGQ_LOCK();
/* don't do anything if already initialized or instrumenation is disabled */
if(bgq_runtime || instrumentation_disabled)
return;
/* register the "NULL" module with the darshan-core component */
darshan_core_register_module(
DARSHAN_BGQ_MOD,
&bgq_mod_fns,
&my_rank,
&mem_limit,
&darshan_mem_alignment);
/* return if no memory assigned by darshan-core */
if(mem_limit == 0)
{
instrumentation_disabled = 1;
return;
}
/* no enough memory to fit bgq module */
if (mem_limit < sizeof(*bgq_runtime))
{
instrumentation_disabled = 1;
return;
}
/* initialize module's global state */
bgq_runtime = malloc(sizeof(*bgq_runtime));
if(!bgq_runtime)
{
instrumentation_disabled = 1;
return;
}
memset(bgq_runtime, 0, sizeof(*bgq_runtime));
darshan_core_register_record(
recname,
strlen(recname),
1,
DARSHAN_BGQ_MOD,
&bgq_runtime->record.f_id,
&bgq_runtime->record.alignment);
DARSHAN_MPI_CALL(PMPI_Comm_rank)(MPI_COMM_WORLD, &my_rank);
capture(&bgq_runtime->record);
BGQ_UNLOCK();
return;
}
/* Perform any necessary steps prior to shutting down for the "NULL" module. */
static void bgq_begin_shutdown()
{
BGQ_LOCK();
/* In general, we want to disable all wrappers while Darshan shuts down.
* This is to avoid race conditions and ensure data consistency, as
* executing wrappers could potentially modify module state while Darshan
* is in the process of shutting down.
*/
instrumentation_disabled = 1;
BGQ_UNLOCK();
return;
}
static int cmpr(const void *p1, const void *p2)
{
const uint64_t *a = (uint64_t*) p1;
const uint64_t *b = (uint64_t*) p2;
return ((*a == *b) ? 0 : ((*a < *b) ? -1 : 1));
}
/* Pass output data for the "BGQ" module back to darshan-core to log to file. */
static void bgq_get_output_data(
MPI_Comm mod_comm,
darshan_record_id *shared_recs,
int shared_rec_count,
void **buffer,
int *size)
{
/* Just set the output buffer to point at the array of the "BGQ" module's
* I/O records, and set the output size according to the number of records
* currently being tracked.
*/
int nprocs;
int result;
uint64_t *ion_ids;
if (my_rank == 0)
{
DARSHAN_MPI_CALL(MPI_Comm_size)(mod_comm, &nprocs);
ion_ids = malloc(sizeof(*ion_ids)*nprocs);
result = (ion_ids != NULL);
}
DARSHAN_MPI_CALL(MPI_Bcast)(&result, 1, MPI_INT, 0, mod_comm);
if (bgq_runtime && result)
{
int i, found;
uint64_t val;
DARSHAN_MPI_CALL(MPI_Gather)(&bgq_runtime->record.counters[BGQ_INODES],
1,
MPI_LONG_LONG_INT,
ion_ids,
1,
MPI_LONG_LONG_INT,
0,
mod_comm);
if (my_rank == 0)
{
qsort(ion_ids, nprocs, sizeof(*ion_ids), cmpr);
for (i = 1, val = ion_ids[0], found = 1; i < nprocs; i++)
{
if (val != ion_ids[i])
{
val = ion_ids[i];
found += 1;
}
}
bgq_runtime->record.counters[BGQ_INODES] = found;
}
}
if ((bgq_runtime) && (my_rank == 0))
{
*buffer = &bgq_runtime->record;
*size = sizeof(struct darshan_bgq_record);
}
else
{
*buffer = NULL;
*size = 0;
}
return;
}
/* Shutdown the "BGQ" module by freeing up all data structures. */
static void bgq_shutdown()
{
if (bgq_runtime)
{
free(bgq_runtime);
bgq_runtime = NULL;
}
return;
}
static void bgq_record_reduction_op(
void* infile_v,
void* inoutfile_v,
int* len,
MPI_Datatype *datatype)
{
int i;
int j;
struct darshan_bgq_record *infile = infile_v;
struct darshan_bgq_record *inoutfile = inoutfile_v;
for (i = 0; i<*len; i++)
{
for (j = 0; j < BGQ_NUM_INDICES; j++)
{
if (infile->counters[j] != inoutfile->counters[j])
{
// unexpected
fprintf(stderr,
"%lu counter mismatch: %d [%lu] [%lu]\n",
infile->f_id,
j,
infile->counters[j],
inoutfile->counters[j]);
}
}
infile++;
inoutfile++;
}
return;
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ts=8 sts=4 sw=4 expandtab
*/
...@@ -208,6 +208,11 @@ void darshan_core_initialize(int argc, char **argv) ...@@ -208,6 +208,11 @@ void darshan_core_initialize(int argc, char **argv)
} }
} }
#ifdef __bgq__
extern void bgq_runtime_initialize();
bgq_runtime_initialize();
#endif
return; return;
} }
......
...@@ -69,10 +69,16 @@ darshan-pnetcdf-logutils.o: darshan-pnetcdf-logutils.c darshan-logutils.h darsha ...@@ -69,10 +69,16 @@ darshan-pnetcdf-logutils.o: darshan-pnetcdf-logutils.c darshan-logutils.h darsha
darshan-pnetcdf-logutils.po: darshan-pnetcdf-logutils.c darshan-logutils.h darshan-pnetcdf-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-pnetcdf-log-format.h | uthash-1.9.2 darshan-pnetcdf-logutils.po: darshan-pnetcdf-logutils.c darshan-logutils.h darshan-pnetcdf-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-pnetcdf-log-format.h | uthash-1.9.2
$(CC) $(CFLAGS_SHARED) -c $< -o $@ $(CC) $(CFLAGS_SHARED) -c $< -o $@
libdarshan-util.so: darshan-logutils.po darshan-posix-logutils.po darshan-mpiio-logutils.po darshan-hdf5-logutils.po darshan-pnetcdf-logutils.po darshan-bgq-logutils.o: darshan-bgq-logutils.c darshan-logutils.h darshan-bgq-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-bgq-log-format.h | uthash-1.9.2
$(CC) $(CFLAGS) -c $< -o $@
darshan-bgq-logutils.po: darshan-bgq-logutils.c darshan-logutils.h darshan-bgq-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-bgq-log-format.h | uthash-1.9.2
$(CC) $(CFLAGS_SHARED) -c $< -o $@
libdarshan-util.so: darshan-logutils.po darshan-posix-logutils.po darshan-mpiio-logutils.po darshan-hdf5-logutils.po darshan-pnetcdf-logutils.po darshan-bgq-logutils.po
$(CC) $(CFLAGS_SHARED) $(LDFLAGS) -o $@ $^ $(LIBS) $(CC) $(CFLAGS_SHARED) $(LDFLAGS) -o $@ $^ $(LIBS)
libdarshan-util.a: darshan-logutils.o darshan-posix-logutils.o darshan-mpiio-logutils.o darshan-hdf5-logutils.o darshan-pnetcdf-logutils.o libdarshan-util.a: darshan-logutils.o darshan-posix-logutils.o darshan-mpiio-logutils.o darshan-hdf5-logutils.o darshan-pnetcdf-logutils.o darshan-bgq-logutils.o
ar rcs libdarshan-util.a $^ ar rcs libdarshan-util.a $^
jenkins-hash-gen: jenkins-hash-gen.c lookup3.o jenkins-hash-gen: jenkins-hash-gen.c lookup3.o
......
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#define _GNU_SOURCE
#include "darshan-util-config.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "darshan-bgq-logutils.h"
/* counter name strings for the POSIX module */
#define X(a, b) #a,
char *bgq_counter_names[] = {
BGQ_COUNTERS
};
char *bgq_f_counter_names[] = {
BGQ_F_COUNTERS
};
#undef X
static int darshan_log_get_bgq_file(void** psx_buf_p, int* bytes_left,
void** file_rec, darshan_record_id* rec_id, int byte_swap_flag);
static void darshan_log_print_bgq_file(void *file_rec,
char *file_name, char *mnt_pt, char *fs_type);
struct darshan_mod_logutil_funcs bgq_logutils =
{
.log_get_record = &darshan_log_get_bgq_file,
.log_print_record = &darshan_log_print_bgq_file,
};
static int darshan_log_get_bgq_file(void** psx_buf_p, int* bytes_left,
void** file_rec, darshan_record_id* rec_id, int byte_swap_flag)
{
int i;
struct darshan_bgq_record *file = (struct darshan_bgq_record *)
(*psx_buf_p);
if(*bytes_left < sizeof(struct darshan_bgq_record))
return(-1);
if(byte_swap_flag)
{
/* swap bytes if necessary */
DARSHAN_BSWAP64(&file->f_id);
DARSHAN_BSWAP64(&file->rank);
for(i=0; i<BGQ_NUM_INDICES; i++)
DARSHAN_BSWAP64(&file->counters[i]);
for(i=0; i<BGQ_F_NUM_INDICES; i++)
DARSHAN_BSWAP64(&file->fcounters[i]);
}
/* update/set output variables */
*file_rec = (void *)file;
*rec_id = file->f_id;
*psx_buf_p = (file + 1); /* increment input buf by size of file record */
*bytes_left -= sizeof(struct darshan_bgq_record);
return(0);
}
static void darshan_log_print_bgq_file(void *file_rec, char *file_name,
char *mnt_pt, char *fs_type)
{
int i;
struct darshan_bgq_record *bgq_file_rec =
(struct darshan_bgq_record *)file_rec;
for(i=0; i<BGQ_NUM_INDICES; i++)
{
DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_BGQ_MOD],
bgq_file_rec->rank, bgq_file_rec->f_id, bgq_counter_names[i],
bgq_file_rec->counters[i], file_name, mnt_pt, fs_type);
}
for(i=0; i<BGQ_F_NUM_INDICES; i++)
{
DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_BGQ_MOD],
bgq_file_rec->rank, bgq_file_rec->f_id, bgq_f_counter_names[i],
bgq_file_rec->fcounters[i], file_name, mnt_pt, fs_type);
}
return;
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ts=8 sts=4 sw=4 expandtab
*/
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef __DARSHAN_BGQ_LOG_UTILS_H
#define __DARSHAN_BGQ_LOG_UTILS_H
#include "darshan-logutils.h"
#include "darshan-bgq-log-format.h"
extern char *bgq_counter_names[];
extern char *bgq_f_counter_names[];
extern struct darshan_mod_logutil_funcs bgq_logutils;
#endif
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <zlib.h>
#include <time.h>
#include <stdlib.h>
#include <getopt.h>
#include <assert.h>
#include "darshan-logutils.h"
#include "darshan-bgq-logutils.h"
#include "uthash-1.9.2/src/uthash.h"
int main(int argc, char **argv)
{
int ret;
int i;
char *filename;
char tmp_string[4096];
darshan_fd fd;
struct darshan_header header;
struct darshan_job job;
struct darshan_record_ref *rec_hash = NULL;
struct darshan_record_ref *ref;
int mount_count;
char** mnt_pts;
char** fs_types;
time_t tmp_time = 0;
char *token;
char *save;
char buffer[DARSHAN_JOB_METADATA_LEN];
struct darshan_bgq_record next_file;
assert(argc == 2);
filename = argv[1];
struct stat sbuf;
stat(filename, &sbuf);
fd = darshan_log_open(filename, "r");
if(!fd)
{
fprintf(stderr, "darshan_log_open() failed to open %s\n.", filename);
return(-1);
}
/* read darshan log header */
ret = darshan_log_getheader(fd, &header);
if(ret < 0)
{
fprintf(stderr, "darshan_log_getheader() failed to read log header.\n");
darshan_log_close(fd);
return(-1);
}
/* read darshan job info */
ret = darshan_log_getjob(fd, &job);
if(ret < 0)
{
fprintf(stderr, "darshan_log_getjob() failed to read job data.\n");
darshan_log_close(fd);
return(-1);
}
/* get the original command line for this job */
ret = darshan_log_getexe(fd, tmp_string);
if(ret < 0)
{
fprintf(stderr, "Error: unable to read trailing job information.\n");
darshan_log_close(fd);
return(-1);
}
/* print job summary */
printf("# darshan log version: %s\n", header.version_string);
printf("# size of BGQ file statistics: %zu bytes\n", sizeof(struct darshan_bgq_record));
printf("# size of job statistics: %zu bytes\n", sizeof(struct darshan_job));
printf("# exe: %s\n", tmp_string);
printf("# uid: %" PRId64 "\n", job.uid);
printf("# jobid: %" PRId64 "\n", job.jobid);
printf("# start_time: %" PRId64 "\n", job.start_time);
tmp_time += job.start_time;
printf("# start_time_asci: %s", ctime(&tmp_time));
printf("# end_time: %" PRId64 "\n", job.end_time);
tmp_time = 0;
tmp_time += job.end_time;
printf("# end_time_asci: %s", ctime(&tmp_time));
printf("# nprocs: %" PRId64 "\n", job.nprocs);
printf("# run time: %" PRId64 "\n", job.end_time - job.start_time + 1);
for(token=strtok_r(job.metadata, "\n", &save);
token != NULL;
token=strtok_r(NULL, "\n", &save))
{
char *key;
char *value;
/* NOTE: we intentionally only split on the first = character.
* There may be additional = characters in the value portion
* (for example, when storing mpi-io hints).
*/
strcpy(buffer, token);
key = buffer;
value = index(buffer, '=');
if(!value)
continue;
/* convert = to a null terminator to split key and value */
value[0] = '\0';
value++;
printf("# metadata: %s = %s\n", key, value);
}
/* get the mount information for this log */
ret = darshan_log_getmounts(fd, &mnt_pts, &fs_types, &mount_count);
if(ret < 0)
{
fprintf(stderr, "darshan_log_getmounts() failed to read mount information.\n");
darshan_log_close(fd);
return(-1);
}
/* print table of mounted file systems */
printf("\n# mounted file systems (mount point and fs type)\n");
printf("# -------------------------------------------------------\n");