/* * (C) 2009 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ #define _GNU_SOURCE #include "darshan-runtime-config.h" #include #ifdef HAVE_MNTENT_H #include #endif #include #include #include #include #include #include #include #include #include #include #include "uthash.h" #include "darshan-core.h" /* TODO is __progname_full needed here */ extern char* __progname; /* internal variable delcarations */ static struct darshan_core_runtime *darshan_core_job = NULL; static pthread_mutex_t darshan_core_mutex = PTHREAD_MUTEX_INITIALIZER; static int my_rank = -1; static int nprocs = -1; /* prototypes for internal helper functions */ static void darshan_core_initialize( int *argc, char ***argv); static void darshan_core_shutdown( void); static void darshan_core_cleanup( struct darshan_core_runtime* job); static void darshan_get_logfile_name( char* logfile_name, int jobid, struct tm* start_tm); static void darshan_log_record_hints_and_ver( struct darshan_core_runtime* job); static int darshan_get_shared_record_ids( struct darshan_core_runtime *job, darshan_record_id *shared_recs); static int darshan_log_write_record_map( MPI_File log_fh, struct darshan_core_record_ref *rec_hash, darshan_record_id *shared_recs, struct darshan_log_map *map); static int darshan_log_coll_write( MPI_File log_fh, void *buf, int count, struct darshan_log_map *map); #define DARSHAN_CORE_LOCK() pthread_mutex_lock(&darshan_core_mutex) #define DARSHAN_CORE_UNLOCK() pthread_mutex_unlock(&darshan_core_mutex) /* intercept MPI initialize and finalize to manage darshan core runtime */ int MPI_Init(int *argc, char ***argv) { int ret; ret = DARSHAN_MPI_CALL(PMPI_Init)(argc, argv); if(ret != MPI_SUCCESS) { return(ret); } darshan_core_initialize(argc, argv); return(ret); } int MPI_Init_thread(int *argc, char ***argv, int required, int *provided) { int ret; ret = DARSHAN_MPI_CALL(PMPI_Init_thread)(argc, argv, required, provided); if(ret != MPI_SUCCESS) { return(ret); } darshan_core_initialize(argc, argv); return(ret); } int MPI_Finalize(void) { int ret; darshan_core_shutdown(); ret = DARSHAN_MPI_CALL(PMPI_Finalize)(); return(ret); } /* *********************************** */ static void darshan_core_initialize(int *argc, char ***argv) { int i; int internal_timing_flag = 0; double init_start, init_time, init_max; char* truncate_string = ""; int truncate_offset; int chars_left = 0; DARSHAN_MPI_CALL(PMPI_Comm_size)(MPI_COMM_WORLD, &nprocs); DARSHAN_MPI_CALL(PMPI_Comm_rank)(MPI_COMM_WORLD, &my_rank); if(getenv("DARSHAN_INTERNAL_TIMING")) internal_timing_flag = 1; if(internal_timing_flag) init_start = DARSHAN_MPI_CALL(PMPI_Wtime)(); /* setup darshan runtime if darshan is enabled and hasn't been initialized already */ if(!getenv("DARSHAN_DISABLE") && !darshan_core_job) { /* allocate structure to track darshan_core_job information */ darshan_core_job = malloc(sizeof(*darshan_core_job)); if(darshan_core_job) { memset(darshan_core_job, 0, sizeof(*darshan_core_job)); darshan_core_job->log_job.uid = getuid(); darshan_core_job->log_job.start_time = time(NULL); darshan_core_job->log_job.nprocs = nprocs; darshan_core_job->wtime_offset = DARSHAN_MPI_CALL(PMPI_Wtime)(); /* record exe and arguments */ for(i=0; i<(*argc); i++) { chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe); strncat(darshan_core_job->exe, *(argv[i]), chars_left); if(i < ((*argc)-1)) { chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe); strncat(darshan_core_job->exe, " ", chars_left); } } /* if we don't see any arguments, then use glibc symbol to get * program name at least (this happens in fortran) */ if(argc == 0) { chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe); strncat(darshan_core_job->exe, __progname, chars_left); chars_left = CP_EXE_LEN-strlen(darshan_core_job->exe); strncat(darshan_core_job->exe, " ", chars_left); } if(chars_left == 0) { /* we ran out of room; mark that string was truncated */ truncate_offset = CP_EXE_LEN - strlen(truncate_string); sprintf(&darshan_core_job->exe[truncate_offset], "%s", truncate_string); } } } if(internal_timing_flag) { init_time = DARSHAN_MPI_CALL(PMPI_Wtime)() - init_start; DARSHAN_MPI_CALL(PMPI_Reduce)(&init_time, &init_max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); if(my_rank == 0) { printf("#darshan:\t\t