/* * (C) 2009 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ #include "darshan-runtime-config.h" #include #include #include #ifdef HAVE_MNTENT_H #include #endif #include #include #include #include #include #include "darshan-core.h" extern char* __progname_full; static void darshan_core_initialize(int *argc, char ***argv); static void darshan_core_shutdown(void); static char *darshan_get_exe_and_mounts(int rank); static void darshan_get_exe_and_mounts_root(char* trailing_data, int space_left); /* internal variables */ static struct darshan_core_job_runtime *darshan_global_job = NULL; static pthread_mutex_t darshan_mutex = PTHREAD_MUTEX_INITIALIZER; #define DARSHAN_LOCK() pthread_mutex_lock(&darshan_mutex) #define DARSHAN_UNLOCK() pthread_mutex_unlock(&darshan_mutex) #define DARSHAN_MAX_MNTS 64 #define DARSHAN_MAX_MNT_PATH 256 #define DARSHAN_MAX_MNT_TYPE 32 struct mnt_data { int64_t hash; int64_t block_size; char path[DARSHAN_MAX_MNT_PATH]; char type[DARSHAN_MAX_MNT_TYPE]; }; static struct mnt_data mnt_data_array[DARSHAN_MAX_MNTS]; static int mnt_data_count = 0; /* intercept MPI initialize and finalize to initialize darshan */ 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 rank; 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, &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_global_job) { /* allocate structure to track darshan_global_job information */ darshan_global_job = malloc(sizeof(*darshan_global_job)); if (darshan_global_job) { memset(darshan_global_job, 0, sizeof(*darshan_global_job)); if (getenv("DARSHAN_DISABLE_TIMING")) { darshan_global_job->flags |= CP_FLAG_NOTIMING; } strcpy(darshan_global_job->log_job.version_string, CP_VERSION); darshan_global_job->log_job.magic_nr = CP_MAGIC_NR; darshan_global_job->log_job.uid = getuid(); darshan_global_job->log_job.start_time = time(NULL); darshan_global_job->log_job.nprocs = nprocs; darshan_global_job->wtime_offset = DARSHAN_MPI_CALL(PMPI_Wtime)(); darshan_global_job->mod_list_head = NULL; /* record exe and arguments */ for(i=0; i<(*argc); i++) { chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); strncat(darshan_global_job->exe, *(argv[i]), chars_left); if(i < ((*argc)-1)) { chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); strncat(darshan_global_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_global_job->exe); strncat(darshan_global_job->exe, __progname_full, chars_left); chars_left = CP_EXE_LEN-strlen(darshan_global_job->exe); strncat(darshan_global_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_global_job->exe[truncate_offset], "%s", truncate_string); } /* collect information about command line and * mounted file systems */ darshan_global_job->trailing_data = darshan_get_exe_and_mounts(rank); } } 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(rank == 0) { printf("#darshan:\t\t