/* * (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 "darshan-core.h" #include "utlist.h" /* TODO is __progname_full needed here */ extern char* __progname; /* internal variables */ static struct darshan_core_job_runtime *darshan_core_job = NULL; static pthread_mutex_t darshan_mutex = PTHREAD_MUTEX_INITIALIZER; static int my_rank = -1; static void darshan_core_initialize(int *argc, char ***argv); static void darshan_core_shutdown(void); static void darshan_core_cleanup(struct darshan_core_job_runtime* job); #define DARSHAN_LOCK() pthread_mutex_lock(&darshan_mutex) #define DARSHAN_UNLOCK() pthread_mutex_unlock(&darshan_mutex) #define DARSHAN_MOD_REGISTER(__mod, __job) \ LL_PREPEND(__job->mod_list_head, __mod) #define DARSHAN_MOD_SEARCH(__mod, __tmp, __job) \ LL_SEARCH(__job->mod_list_head, __mod, __tmp, mod_cmp) #define DARSHAN_MOD_ITER(__mod, __tmp, __job) \ LL_FOREACH_SAFE(__job->mod_list_head, __mod, __tmp) #define DARSHAN_MOD_DELETE(__mod, __job) \ LL_DELETE(__job->mod_list_head, __mod) /* 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 nprocs; 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)); if(getenv("DARSHAN_DISABLE_TIMING")) { darshan_core_job->flags |= CP_FLAG_NOTIMING; } strcpy(darshan_core_job->log_job.version_string, CP_VERSION); darshan_core_job->log_job.magic_nr = CP_MAGIC_NR; 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