Коммит
4477b87e1d
1
.gitignore
поставляемый
1
.gitignore
поставляемый
@ -244,6 +244,7 @@ ompi/mpiext/cuda/c/mpiext_cuda_c.h
|
|||||||
ompi/tools/mpisync/mpisync
|
ompi/tools/mpisync/mpisync
|
||||||
ompi/tools/mpisync/mpirun_prof
|
ompi/tools/mpisync/mpirun_prof
|
||||||
ompi/tools/mpisync/ompi_timing_post
|
ompi/tools/mpisync/ompi_timing_post
|
||||||
|
ompi/tools/mpisync/mpisync.1
|
||||||
|
|
||||||
ompi/tools/ompi_info/ompi_info
|
ompi/tools/ompi_info/ompi_info
|
||||||
ompi/tools/ompi_info/ompi_info.1
|
ompi/tools/ompi_info/ompi_info.1
|
||||||
|
@ -192,6 +192,7 @@ include mpiext/Makefile.am
|
|||||||
include patterns/net/Makefile.am
|
include patterns/net/Makefile.am
|
||||||
include patterns/comm/Makefile.am
|
include patterns/comm/Makefile.am
|
||||||
include mca/Makefile.am
|
include mca/Makefile.am
|
||||||
|
include util/Makefile.am
|
||||||
|
|
||||||
# Ensure that the man page directory exists before we try to make man
|
# Ensure that the man page directory exists before we try to make man
|
||||||
# page files (because ompi/mpi/man/man3 has no config.status-generated
|
# page files (because ompi/mpi/man/man3 has no config.status-generated
|
||||||
|
@ -91,7 +91,6 @@
|
|||||||
#include "ompi/runtime/ompi_cr.h"
|
#include "ompi/runtime/ompi_cr.h"
|
||||||
|
|
||||||
extern bool ompi_enable_timing;
|
extern bool ompi_enable_timing;
|
||||||
extern bool ompi_enable_timing_ext;
|
|
||||||
|
|
||||||
static void fence_cbfunc(int status, void *cbdata)
|
static void fence_cbfunc(int status, void *cbdata)
|
||||||
{
|
{
|
||||||
@ -108,8 +107,8 @@ int ompi_mpi_finalize(void)
|
|||||||
volatile bool active;
|
volatile bool active;
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
ompi_datatype_t * datatype;
|
ompi_datatype_t * datatype;
|
||||||
OPAL_TIMING_DECLARE(tm);
|
//OPAL_TIMING_DECLARE(tm);
|
||||||
OPAL_TIMING_INIT_EXT(&tm, OPAL_TIMING_GET_TIME_OF_DAY);
|
//OPAL_TIMING_INIT_EXT(&tm, OPAL_TIMING_GET_TIME_OF_DAY);
|
||||||
|
|
||||||
ompi_hook_base_mpi_finalize_top();
|
ompi_hook_base_mpi_finalize_top();
|
||||||
|
|
||||||
@ -176,7 +175,7 @@ int ompi_mpi_finalize(void)
|
|||||||
opal_progress_event_users_increment();
|
opal_progress_event_users_increment();
|
||||||
|
|
||||||
/* check to see if we want timing information */
|
/* check to see if we want timing information */
|
||||||
OPAL_TIMING_MSTART((&tm,"time to execute finalize barrier"));
|
//OPAL_TIMING_MSTART((&tm,"time to execute finalize barrier"));
|
||||||
|
|
||||||
/* NOTE: MPI-2.1 requires that MPI_FINALIZE is "collective" across
|
/* NOTE: MPI-2.1 requires that MPI_FINALIZE is "collective" across
|
||||||
*all* connected processes. This only means that all processes
|
*all* connected processes. This only means that all processes
|
||||||
@ -279,10 +278,7 @@ int ompi_mpi_finalize(void)
|
|||||||
|
|
||||||
/* check for timing request - get stop time and report elapsed
|
/* check for timing request - get stop time and report elapsed
|
||||||
time if so */
|
time if so */
|
||||||
OPAL_TIMING_MSTOP(&tm);
|
//OPAL_TIMING_DELTAS(ompi_enable_timing, &tm);
|
||||||
OPAL_TIMING_DELTAS(ompi_enable_timing, &tm);
|
|
||||||
OPAL_TIMING_REPORT(ompi_enable_timing_ext, &tm);
|
|
||||||
OPAL_TIMING_RELEASE(&tm);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shutdown the Checkpoint/Restart Mech.
|
* Shutdown the Checkpoint/Restart Mech.
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
#include "ompi/dpm/dpm.h"
|
#include "ompi/dpm/dpm.h"
|
||||||
#include "ompi/mpiext/mpiext.h"
|
#include "ompi/mpiext/mpiext.h"
|
||||||
#include "ompi/mca/hook/base/base.h"
|
#include "ompi/mca/hook/base/base.h"
|
||||||
|
#include "ompi/util/timings.h"
|
||||||
|
|
||||||
#if OPAL_ENABLE_FT_CR == 1
|
#if OPAL_ENABLE_FT_CR == 1
|
||||||
#include "ompi/mca/crcp/crcp.h"
|
#include "ompi/mca/crcp/crcp.h"
|
||||||
@ -279,7 +280,7 @@ opal_hash_table_t ompi_mpi_f90_complex_hashtable = {{0}};
|
|||||||
*/
|
*/
|
||||||
opal_list_t ompi_registered_datareps = {{0}};
|
opal_list_t ompi_registered_datareps = {{0}};
|
||||||
|
|
||||||
bool ompi_enable_timing = false, ompi_enable_timing_ext = false;
|
bool ompi_enable_timing = false;
|
||||||
extern bool ompi_mpi_yield_when_idle;
|
extern bool ompi_mpi_yield_when_idle;
|
||||||
extern int ompi_mpi_event_tick_rate;
|
extern int ompi_mpi_event_tick_rate;
|
||||||
|
|
||||||
@ -348,6 +349,9 @@ static int ompi_register_mca_variables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check to see if we want timing information */
|
/* check to see if we want timing information */
|
||||||
|
/* TODO: enable OMPI init and OMPI finalize timings if
|
||||||
|
* this variable was set to 1!
|
||||||
|
*/
|
||||||
ompi_enable_timing = false;
|
ompi_enable_timing = false;
|
||||||
(void) mca_base_var_register("ompi", "ompi", NULL, "timing",
|
(void) mca_base_var_register("ompi", "ompi", NULL, "timing",
|
||||||
"Request that critical timing loops be measured",
|
"Request that critical timing loops be measured",
|
||||||
@ -356,13 +360,6 @@ static int ompi_register_mca_variables(void)
|
|||||||
MCA_BASE_VAR_SCOPE_READONLY,
|
MCA_BASE_VAR_SCOPE_READONLY,
|
||||||
&ompi_enable_timing);
|
&ompi_enable_timing);
|
||||||
|
|
||||||
ompi_enable_timing_ext = false;
|
|
||||||
(void) mca_base_var_register("ompi", "ompi", NULL, "timing_ext",
|
|
||||||
"Request that critical timing loops be measured",
|
|
||||||
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0,
|
|
||||||
OPAL_INFO_LVL_9,
|
|
||||||
MCA_BASE_VAR_SCOPE_READONLY,
|
|
||||||
&ompi_enable_timing_ext);
|
|
||||||
return OMPI_SUCCESS;
|
return OMPI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,8 +379,8 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
volatile bool active;
|
volatile bool active;
|
||||||
opal_list_t info;
|
opal_list_t info;
|
||||||
opal_value_t *kv;
|
opal_value_t *kv;
|
||||||
OPAL_TIMING_DECLARE(tm);
|
|
||||||
OPAL_TIMING_INIT_EXT(&tm, OPAL_TIMING_GET_TIME_OF_DAY);
|
OMPI_TIMING_INIT(32);
|
||||||
|
|
||||||
/* bitflag of the thread level support provided. To be used
|
/* bitflag of the thread level support provided. To be used
|
||||||
* for the modex in order to work in heterogeneous environments. */
|
* for the modex in order to work in heterogeneous environments. */
|
||||||
@ -486,7 +483,7 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
ompi_hook_base_mpi_init_top_post_opal(argc, argv, requested, provided);
|
ompi_hook_base_mpi_init_top_post_opal(argc, argv, requested, provided);
|
||||||
|
|
||||||
|
|
||||||
OPAL_TIMING_MSTART((&tm,"time from start to completion of rte_init"));
|
OMPI_TIMING_NEXT("initialization");
|
||||||
|
|
||||||
/* if we were not externally started, then we need to setup
|
/* if we were not externally started, then we need to setup
|
||||||
* some envars so the MPI_INFO_ENV can get the cmd name
|
* some envars so the MPI_INFO_ENV can get the cmd name
|
||||||
@ -515,10 +512,10 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
error = "ompi_mpi_init: ompi_rte_init failed";
|
error = "ompi_mpi_init: ompi_rte_init failed";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
ompi_rte_initialized = true;
|
|
||||||
|
|
||||||
/* check for timing request - get stop time and report elapsed time if so */
|
OMPI_TIMING_NEXT("rte_init");
|
||||||
OPAL_TIMING_MNEXT((&tm,"time from completion of rte_init to modex"));
|
|
||||||
|
ompi_rte_initialized = true;
|
||||||
|
|
||||||
/* Register the default errhandler callback */
|
/* Register the default errhandler callback */
|
||||||
errtrk.status = OPAL_ERROR;
|
errtrk.status = OPAL_ERROR;
|
||||||
@ -645,8 +642,9 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for timing request - get stop time and report elapsed time if so */
|
OMPI_TIMING_IMPORT_OPAL("orte_init");
|
||||||
OPAL_TIMING_MNEXT((&tm,"time to execute modex"));
|
OMPI_TIMING_NEXT("rte_init-modex");
|
||||||
|
|
||||||
|
|
||||||
/* exchange connection info - this function may also act as a barrier
|
/* exchange connection info - this function may also act as a barrier
|
||||||
* if data exchange is required. The modex occurs solely across procs
|
* if data exchange is required. The modex occurs solely across procs
|
||||||
@ -664,7 +662,7 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OPAL_TIMING_MNEXT((&tm,"time from modex to first barrier"));
|
OMPI_TIMING_NEXT("modex");
|
||||||
|
|
||||||
/* select buffered send allocator component to be used */
|
/* select buffered send allocator component to be used */
|
||||||
if( OMPI_SUCCESS !=
|
if( OMPI_SUCCESS !=
|
||||||
@ -825,7 +823,7 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
ompi_rte_wait_for_debugger();
|
ompi_rte_wait_for_debugger();
|
||||||
|
|
||||||
/* Next timing measurement */
|
/* Next timing measurement */
|
||||||
OPAL_TIMING_MNEXT((&tm,"time to execute barrier"));
|
OMPI_TIMING_NEXT("modex-barrier");
|
||||||
|
|
||||||
/* wait for everyone to reach this point - this is a hard
|
/* wait for everyone to reach this point - this is a hard
|
||||||
* barrier requirement at this time, though we hope to relax
|
* barrier requirement at this time, though we hope to relax
|
||||||
@ -843,7 +841,7 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
|
|
||||||
/* check for timing request - get stop time and report elapsed
|
/* check for timing request - get stop time and report elapsed
|
||||||
time if so, then start the clock again */
|
time if so, then start the clock again */
|
||||||
OPAL_TIMING_MNEXT((&tm,"time from barrier to complete mpi_init"));
|
OMPI_TIMING_NEXT("barrier");
|
||||||
|
|
||||||
#if OPAL_ENABLE_PROGRESS_THREADS == 0
|
#if OPAL_ENABLE_PROGRESS_THREADS == 0
|
||||||
/* Start setting up the event engine for MPI operations. Don't
|
/* Start setting up the event engine for MPI operations. Don't
|
||||||
@ -952,6 +950,7 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
}
|
}
|
||||||
opal_mutex_unlock(&ompi_mpi_bootstrap_mutex);
|
opal_mutex_unlock(&ompi_mpi_bootstrap_mutex);
|
||||||
ompi_hook_base_mpi_init_error(argc, argv, requested, provided);
|
ompi_hook_base_mpi_init_error(argc, argv, requested, provided);
|
||||||
|
OMPI_TIMING_FINALIZE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -976,10 +975,9 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
|||||||
|
|
||||||
/* Finish last measurement, output results
|
/* Finish last measurement, output results
|
||||||
* and clear timing structure */
|
* and clear timing structure */
|
||||||
OPAL_TIMING_MSTOP(&tm);
|
OMPI_TIMING_NEXT("barrier-finish");
|
||||||
OPAL_TIMING_DELTAS(ompi_enable_timing, &tm);
|
OMPI_TIMING_OUT;
|
||||||
OPAL_TIMING_REPORT(ompi_enable_timing_ext, &tm);
|
OMPI_TIMING_FINALIZE;
|
||||||
OPAL_TIMING_RELEASE(&tm);
|
|
||||||
|
|
||||||
opal_mutex_unlock(&ompi_mpi_bootstrap_mutex);
|
opal_mutex_unlock(&ompi_mpi_bootstrap_mutex);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Artem Polyakov <artpol84@gmail.com>
|
* Copyright (C) 2014 Artem Polyakov <artpol84@gmail.com>
|
||||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
* Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -139,7 +139,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
MPI_Gather(hname,sizeof(hname),MPI_CHAR,hnames,sizeof(hname),MPI_CHAR, 0, MPI_COMM_WORLD);
|
MPI_Gather(hname,sizeof(hname),MPI_CHAR,hnames,sizeof(hname),MPI_CHAR, 0, MPI_COMM_WORLD);
|
||||||
MPI_Gather(send,2,MPI_DOUBLE,measure,2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
MPI_Gather(send,2,MPI_DOUBLE,measure,2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
||||||
char tmpname[128];
|
|
||||||
FILE *fp = fopen(filename,"w");
|
FILE *fp = fopen(filename,"w");
|
||||||
if( fp == NULL ){
|
if( fp == NULL ){
|
||||||
fprintf(stderr, "Fail to open the file %s. Abort\n", filename);
|
fprintf(stderr, "Fail to open the file %s. Abort\n", filename);
|
||||||
|
13
ompi/util/Makefile.am
Обычный файл
13
ompi/util/Makefile.am
Обычный файл
@ -0,0 +1,13 @@
|
|||||||
|
# -*- makefile -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017 Mellanox Technologies Ltd. All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
# Source code files
|
||||||
|
headers += \
|
||||||
|
util/timings.h
|
238
ompi/util/timings.h
Обычный файл
238
ompi/util/timings.h
Обычный файл
@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Mellanox Technologies Ltd. All rights reserved.
|
||||||
|
* Copyright (c) 2017 Intel, Inc. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OMPI_UTIL_TIMING_H
|
||||||
|
#define OMPI_UTIL_TIMING_H
|
||||||
|
|
||||||
|
#include "opal/util/timings.h"
|
||||||
|
/* TODO: we need access to MPI_* functions */
|
||||||
|
|
||||||
|
#if (OPAL_ENABLE_TIMING)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char desc[OPAL_TIMING_STR_LEN];
|
||||||
|
double ts;
|
||||||
|
char *file;
|
||||||
|
char *prefix;
|
||||||
|
} ompi_timing_val_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ompi_timing_val_t *val;
|
||||||
|
int use;
|
||||||
|
struct ompi_timing_list_t *next;
|
||||||
|
} ompi_timing_list_t;
|
||||||
|
|
||||||
|
typedef struct ompi_timing_t {
|
||||||
|
double ts;
|
||||||
|
const char *prefix;
|
||||||
|
int size;
|
||||||
|
int cnt;
|
||||||
|
int error;
|
||||||
|
int enabled;
|
||||||
|
opal_timing_ts_func_t get_ts;
|
||||||
|
ompi_timing_list_t *timing;
|
||||||
|
ompi_timing_list_t *cur_timing;
|
||||||
|
} ompi_timing_t;
|
||||||
|
|
||||||
|
#define OMPI_TIMING_INIT(_size) \
|
||||||
|
ompi_timing_t OMPI_TIMING; \
|
||||||
|
OMPI_TIMING.prefix = __func__; \
|
||||||
|
OMPI_TIMING.size = _size; \
|
||||||
|
OMPI_TIMING.get_ts = opal_timing_ts_func(OPAL_TIMING_AUTOMATIC_TIMER); \
|
||||||
|
OMPI_TIMING.cnt = 0; \
|
||||||
|
OMPI_TIMING.error = 0; \
|
||||||
|
OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \
|
||||||
|
OMPI_TIMING.enabled = 0; \
|
||||||
|
{ \
|
||||||
|
char *ptr; \
|
||||||
|
ptr = getenv("OMPI_TIMING_ENABLE"); \
|
||||||
|
if (NULL != ptr) { \
|
||||||
|
OMPI_TIMING.enabled = atoi(ptr); \
|
||||||
|
} \
|
||||||
|
if (OMPI_TIMING.enabled) { \
|
||||||
|
setenv("OPAL_TIMING_ENABLE", "1", 1); \
|
||||||
|
OMPI_TIMING.timing = (ompi_timing_list_t*)malloc(sizeof(ompi_timing_list_t)); \
|
||||||
|
memset(OMPI_TIMING.timing, 0, sizeof(ompi_timing_list_t)); \
|
||||||
|
OMPI_TIMING.timing->val = (ompi_timing_val_t*)malloc(sizeof(ompi_timing_val_t) * _size); \
|
||||||
|
OMPI_TIMING.cur_timing = OMPI_TIMING.timing; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OMPI_TIMING_ITEM_EXTEND \
|
||||||
|
do { \
|
||||||
|
if (OMPI_TIMING.enabled) { \
|
||||||
|
OMPI_TIMING.cur_timing->next = (struct ompi_timing_list_t*)malloc(sizeof(ompi_timing_list_t)); \
|
||||||
|
OMPI_TIMING.cur_timing = (ompi_timing_list_t*)OMPI_TIMING.cur_timing->next; \
|
||||||
|
memset(OMPI_TIMING.cur_timing, 0, sizeof(ompi_timing_list_t)); \
|
||||||
|
OMPI_TIMING.cur_timing->val = malloc(sizeof(ompi_timing_val_t) * OMPI_TIMING.size); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_FINALIZE \
|
||||||
|
do { \
|
||||||
|
if (OMPI_TIMING.enabled) { \
|
||||||
|
ompi_timing_list_t *t = OMPI_TIMING.timing, *tmp; \
|
||||||
|
while ( NULL != t) { \
|
||||||
|
tmp = t; \
|
||||||
|
t = (ompi_timing_list_t*)t->next; \
|
||||||
|
free(tmp->val); \
|
||||||
|
free(tmp); \
|
||||||
|
} \
|
||||||
|
OMPI_TIMING.timing = NULL; \
|
||||||
|
OMPI_TIMING.cur_timing = NULL; \
|
||||||
|
OMPI_TIMING.cnt = 0; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_NEXT(...) \
|
||||||
|
do { \
|
||||||
|
if (!OMPI_TIMING.error && OMPI_TIMING.enabled) { \
|
||||||
|
char *f = strrchr(__FILE__, '/') + 1; \
|
||||||
|
int len = 0; \
|
||||||
|
if (OMPI_TIMING.cur_timing->use >= OMPI_TIMING.size){ \
|
||||||
|
OMPI_TIMING_ITEM_EXTEND; \
|
||||||
|
} \
|
||||||
|
len = snprintf(OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].desc, \
|
||||||
|
OPAL_TIMING_STR_LEN, ##__VA_ARGS__); \
|
||||||
|
if (len >= OPAL_TIMING_STR_LEN) { \
|
||||||
|
OMPI_TIMING.error = 1; \
|
||||||
|
} \
|
||||||
|
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].file = strdup(f); \
|
||||||
|
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].prefix = strdup(__func__); \
|
||||||
|
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use++].ts = \
|
||||||
|
OMPI_TIMING.get_ts() - OMPI_TIMING.ts; \
|
||||||
|
OMPI_TIMING.cnt++; \
|
||||||
|
OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_APPEND(filename,func,desc,ts) \
|
||||||
|
do { \
|
||||||
|
if (OMPI_TIMING.cur_timing->use >= OMPI_TIMING.size){ \
|
||||||
|
OMPI_TIMING_ITEM_EXTEND; \
|
||||||
|
} \
|
||||||
|
int len = snprintf(OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].desc, \
|
||||||
|
OPAL_TIMING_STR_LEN, "%s", desc); \
|
||||||
|
if (len >= OPAL_TIMING_STR_LEN) { \
|
||||||
|
OMPI_TIMING.error = 1; \
|
||||||
|
} \
|
||||||
|
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].prefix = func; \
|
||||||
|
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].file = filename; \
|
||||||
|
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use++].ts = ts; \
|
||||||
|
OMPI_TIMING.cnt++; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_IMPORT_OPAL_PREFIX(_prefix, func) \
|
||||||
|
do { \
|
||||||
|
if (!OMPI_TIMING.error && OMPI_TIMING.enabled) { \
|
||||||
|
int cnt; \
|
||||||
|
int i; \
|
||||||
|
double ts; \
|
||||||
|
OPAL_TIMING_ENV_CNT(func, cnt); \
|
||||||
|
OPAL_TIMING_ENV_ERROR_PREFIX(_prefix, func, OMPI_TIMING.error); \
|
||||||
|
for(i = 0; i < cnt; i++){ \
|
||||||
|
char *desc, *filename; \
|
||||||
|
OPAL_TIMING_ENV_GETDESC_PREFIX(_prefix, &filename, func, i, &desc, ts); \
|
||||||
|
OMPI_TIMING_APPEND(filename, func, desc, ts); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_IMPORT_OPAL(func) \
|
||||||
|
OMPI_TIMING_IMPORT_OPAL_PREFIX("", func);
|
||||||
|
|
||||||
|
#define OMPI_TIMING_OUT \
|
||||||
|
do { \
|
||||||
|
if (OMPI_TIMING.enabled) { \
|
||||||
|
int i, size, rank; \
|
||||||
|
MPI_Comm_size(MPI_COMM_WORLD, &size); \
|
||||||
|
MPI_Comm_rank(MPI_COMM_WORLD, &rank); \
|
||||||
|
int error = 0; \
|
||||||
|
\
|
||||||
|
MPI_Reduce(&OMPI_TIMING.error, &error, 1, \
|
||||||
|
MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); \
|
||||||
|
\
|
||||||
|
if (error) { \
|
||||||
|
if (0 == rank) { \
|
||||||
|
printf("==OMPI_TIMING== error: something went wrong, timings doesn't work\n"); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
double *avg = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \
|
||||||
|
double *min = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \
|
||||||
|
double *max = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \
|
||||||
|
char **desc = (char**)malloc(sizeof(char*) * OMPI_TIMING.cnt); \
|
||||||
|
char **prefix = (char**)malloc(sizeof(char*) * OMPI_TIMING.cnt); \
|
||||||
|
char **file = (char**)malloc(sizeof(char*) * OMPI_TIMING.cnt); \
|
||||||
|
\
|
||||||
|
if( OMPI_TIMING.cnt > 0 ) { \
|
||||||
|
OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \
|
||||||
|
ompi_timing_list_t *timing = OMPI_TIMING.timing; \
|
||||||
|
i = 0; \
|
||||||
|
do { \
|
||||||
|
int use; \
|
||||||
|
for (use = 0; use < timing->use; use++) { \
|
||||||
|
MPI_Reduce(&timing->val[use].ts, avg + i, 1, \
|
||||||
|
MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); \
|
||||||
|
MPI_Reduce(&timing->val[use].ts, min + i, 1, \
|
||||||
|
MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD); \
|
||||||
|
MPI_Reduce(&timing->val[use].ts, max + i, 1, \
|
||||||
|
MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); \
|
||||||
|
desc[i] = timing->val[use].desc; \
|
||||||
|
prefix[i] = timing->val[use].prefix; \
|
||||||
|
file[i] = timing->val[use].file; \
|
||||||
|
i++; \
|
||||||
|
} \
|
||||||
|
timing = (ompi_timing_list_t*)timing->next; \
|
||||||
|
} while (timing != NULL); \
|
||||||
|
\
|
||||||
|
if( 0 == rank ){ \
|
||||||
|
if (OMPI_TIMING.timing->next) { \
|
||||||
|
printf("==OMPI_TIMING== warning: added the extra timings allocation that might misrepresent the results.\n" \
|
||||||
|
"==OMPI_TIMING== Increase the inited size of timings to avoid extra allocation during runtime.\n"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
printf("------------------ %s ------------------\n", \
|
||||||
|
OMPI_TIMING.prefix); \
|
||||||
|
for(i=0; i< OMPI_TIMING.cnt; i++){ \
|
||||||
|
avg[i] /= size; \
|
||||||
|
printf("[%s:%s:%s]: %lf / %lf / %lf\n", \
|
||||||
|
file[i], prefix[i], desc[i], avg[i], min[i], max[i]); \
|
||||||
|
} \
|
||||||
|
printf("[%s:overhead]: %lf \n", OMPI_TIMING.prefix, \
|
||||||
|
OMPI_TIMING.get_ts() - OMPI_TIMING.ts); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
free(avg); \
|
||||||
|
free(min); \
|
||||||
|
free(max); \
|
||||||
|
free(desc); \
|
||||||
|
free(prefix); \
|
||||||
|
free(file); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define OMPI_TIMING_INIT(size)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_NEXT(fmt, ...)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_APPEND(desc,ts)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_OUT
|
||||||
|
|
||||||
|
#define OMPI_TIMING_IMPORT_OPAL(func)
|
||||||
|
|
||||||
|
#define OMPI_TIMING_FINALIZE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -49,7 +49,19 @@ AC_DEFUN([MCA_opal_pmix_pmix2x_CONFIG],[
|
|||||||
opal_pmix_pmix2x_sm_flag=--disable-dstore
|
opal_pmix_pmix2x_sm_flag=--disable-dstore
|
||||||
fi
|
fi
|
||||||
|
|
||||||
opal_pmix_pmix2x_args="--with-pmix-symbol-rename=OPAL_MCA_PMIX2X_ $opal_pmix_pmix2x_sm_flag --without-tests-examples --disable-visibility --enable-embedded-libevent --with-libevent-header=\\\"opal/mca/event/$opal_event_base_include\\\""
|
AC_ARG_ENABLE([pmix-timing],
|
||||||
|
[AC_HELP_STRING([--enable-pmix-timing],
|
||||||
|
[Enable PMIx timing measurements (default: disabled)])])
|
||||||
|
AC_MSG_CHECKING([if PMIx timing is enabled])
|
||||||
|
if test "$enable_pmix_timing" == "yes"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
opal_pmix_pmix2x_timing_flag=--enable-pmix-timing
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no (disabled)])
|
||||||
|
opal_pmix_pmix2x_timing_flag=--disable-pmix-timing
|
||||||
|
fi
|
||||||
|
|
||||||
|
opal_pmix_pmix2x_args="--with-pmix-symbol-rename=OPAL_MCA_PMIX2X_ $opal_pmix_pmix2x_sm_flag $opal_pmix_pmix2x_timing_flag --without-tests-examples --disable-visibility --enable-embedded-libevent --with-libevent-header=\\\"opal/mca/event/$opal_event_base_include\\\""
|
||||||
AS_IF([test "$enable_debug" = "yes"],
|
AS_IF([test "$enable_debug" = "yes"],
|
||||||
[opal_pmix_pmix2x_args="--enable-debug $opal_pmix_pmix2x_args"
|
[opal_pmix_pmix2x_args="--enable-debug $opal_pmix_pmix2x_args"
|
||||||
CFLAGS="$OPAL_CFLAGS_BEFORE_PICKY $OPAL_VISIBILITY_CFLAGS -g"],
|
CFLAGS="$OPAL_CFLAGS_BEFORE_PICKY $OPAL_VISIBILITY_CFLAGS -g"],
|
||||||
|
@ -950,18 +950,18 @@ AC_MSG_RESULT([$with_ident_string])
|
|||||||
# Timing support
|
# Timing support
|
||||||
#
|
#
|
||||||
AC_MSG_CHECKING([if want developer-level timing support])
|
AC_MSG_CHECKING([if want developer-level timing support])
|
||||||
AC_ARG_ENABLE(timing,
|
AC_ARG_ENABLE(pmix-timing,
|
||||||
AC_HELP_STRING([--enable-timing],
|
AC_HELP_STRING([--enable-pmix-timing],
|
||||||
[enable developer-level timing code (default: disabled)]))
|
[enable developer-level timing code (default: disabled)]))
|
||||||
if test "$enable_timing" = "yes"; then
|
if test "$enable_pmix_timing" = "yes"; then
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
WANT_TIMING=1
|
WANT_PMIX_TIMING=1
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
WANT_TIMING=0
|
WANT_PMIX_TIMING=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_DEFINE_UNQUOTED([PMIX_ENABLE_TIMING], [$WANT_TIMING],
|
AC_DEFINE_UNQUOTED([PMIX_ENABLE_TIMING], [$WANT_PMIX_TIMING],
|
||||||
[Whether we want developer-level timing support or not])
|
[Whether we want developer-level timing support or not])
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* Copyright (c) 2015 Mellanox Technologies, Inc.
|
* Copyright (c) 2015 Mellanox Technologies, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2016 Intel, Inc. All rights reserved.
|
* Copyright (c) 2016-2017 Intel, Inc. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -37,7 +37,6 @@
|
|||||||
#include "src/util/timings.h"
|
#include "src/util/timings.h"
|
||||||
|
|
||||||
#if PMIX_ENABLE_TIMING
|
#if PMIX_ENABLE_TIMING
|
||||||
char *pmix_timing_sync_file = NULL;
|
|
||||||
char *pmix_timing_output = NULL;
|
char *pmix_timing_output = NULL;
|
||||||
bool pmix_timing_overhead = true;
|
bool pmix_timing_overhead = true;
|
||||||
#endif
|
#endif
|
||||||
@ -56,16 +55,6 @@ pmix_status_t pmix_register_params(void)
|
|||||||
pmix_register_done = true;
|
pmix_register_done = true;
|
||||||
|
|
||||||
#if PMIX_ENABLE_TIMING
|
#if PMIX_ENABLE_TIMING
|
||||||
pmix_timing_sync_file = NULL;
|
|
||||||
(void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "timing_sync_file",
|
|
||||||
"Clock synchronisation information generated by mpisync tool. You don't need to touch this if you use mpirun_prof tool.",
|
|
||||||
PMIX_MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
|
|
||||||
PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_ALL,
|
|
||||||
&pmix_timing_sync_file);
|
|
||||||
if( pmix_timing_clocksync_read(pmix_timing_sync_file) ){
|
|
||||||
pmix_output(0, "Cannot read file %s containing clock synchronisation information\n", pmix_timing_sync_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
pmix_timing_output = NULL;
|
pmix_timing_output = NULL;
|
||||||
(void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "timing_output",
|
(void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "timing_output",
|
||||||
"The name of output file for timing information. If this parameter is not set then output will be directed into PMIX debug channel.",
|
"The name of output file for timing information. If this parameter is not set then output will be directed into PMIX debug channel.",
|
||||||
|
@ -272,34 +272,6 @@ int opal_register_params(void)
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPAL_ENABLE_TIMING
|
|
||||||
opal_timing_sync_file = NULL;
|
|
||||||
(void) mca_base_var_register ("opal", "opal", NULL, "timing_sync_file",
|
|
||||||
"Clock synchronisation information generated by mpisync tool. You don't need to touch this if you use mpirun_prof tool.",
|
|
||||||
MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
|
|
||||||
OPAL_INFO_LVL_9, MCA_BASE_VAR_SCOPE_ALL,
|
|
||||||
&opal_timing_sync_file);
|
|
||||||
if( opal_timing_clocksync_read(opal_timing_sync_file) ){
|
|
||||||
opal_output(0, "Cannot read file %s containing clock synchronisation information\n", opal_timing_sync_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
opal_timing_output = NULL;
|
|
||||||
(void) mca_base_var_register ("opal", "opal", NULL, "timing_output",
|
|
||||||
"The name of output file for timing information. If this parameter is not set then output will be directed into OPAL debug channel.",
|
|
||||||
MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
|
|
||||||
OPAL_INFO_LVL_9, MCA_BASE_VAR_SCOPE_ALL,
|
|
||||||
&opal_timing_output);
|
|
||||||
|
|
||||||
opal_timing_overhead = true;
|
|
||||||
(void) mca_base_var_register ("opal", "opal", NULL, "timing_overhead",
|
|
||||||
"Timing framework introduce additional overhead (malloc's mostly)."
|
|
||||||
" The time spend in such costly routines is measured and may be accounted"
|
|
||||||
" (subtracted from timestamps). 'true' means consider overhead, 'false' - ignore (default: true).",
|
|
||||||
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0,
|
|
||||||
OPAL_INFO_LVL_9, MCA_BASE_VAR_SCOPE_ALL,
|
|
||||||
&opal_timing_overhead);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
opal_warn_on_fork = true;
|
opal_warn_on_fork = true;
|
||||||
(void) mca_base_var_register("ompi", "mpi", NULL, "warn_on_fork",
|
(void) mca_base_var_register("ompi", "mpi", NULL, "warn_on_fork",
|
||||||
"If nonzero, issue a warning if program forks under conditions that could cause system errors",
|
"If nonzero, issue a warning if program forks under conditions that could cause system errors",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Artem Polyakov <artpol84@gmail.com>
|
* Copyright (C) 2014 Artem Polyakov <artpol84@gmail.com>
|
||||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2017 Mellanox Technologies Ltd. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -41,108 +42,6 @@
|
|||||||
|
|
||||||
#include MCA_timer_IMPLEMENTATION_HEADER
|
#include MCA_timer_IMPLEMENTATION_HEADER
|
||||||
|
|
||||||
#define DELTAS_SANE_LIMIT (10*1024*1024)
|
|
||||||
|
|
||||||
/*
|
|
||||||
static void debug_hang(int i)
|
|
||||||
{
|
|
||||||
while( i ){
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct interval_descr{
|
|
||||||
opal_timing_event_t *descr_ev, *begin_ev;
|
|
||||||
double interval, overhead;
|
|
||||||
};
|
|
||||||
|
|
||||||
static OBJ_CLASS_INSTANCE(opal_timing_event_t, opal_list_item_t, NULL, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
opal_mutex_t tm_lock;
|
|
||||||
static char *nodename = NULL;
|
|
||||||
static char *jobid = "";
|
|
||||||
static double hnp_offs = 0;
|
|
||||||
static double hnp_rtt = 0;
|
|
||||||
|
|
||||||
int opal_timing_clocksync_read(char *fname)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
char *line = NULL;
|
|
||||||
size_t n;
|
|
||||||
bool found = false;
|
|
||||||
char *ptr = NULL;
|
|
||||||
|
|
||||||
char hname[OPAL_MAXHOSTNAMELEN] = "NA";
|
|
||||||
if( gethostname(hname, sizeof(hname)) ){
|
|
||||||
opal_output(0, "opal_timing_clocksync_read(%s): Cannot gethostname",
|
|
||||||
fname);
|
|
||||||
}
|
|
||||||
nodename = strdup(hname);
|
|
||||||
// Strip domain name
|
|
||||||
ptr = strchr(nodename,'.');
|
|
||||||
if( ptr != NULL ){
|
|
||||||
*ptr = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fname == NULL ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp = fopen(fname,"r");
|
|
||||||
if( fp == NULL ){
|
|
||||||
opal_output(0, "opal_timing_clocksync_read(%s): Cannot open the file",fname);
|
|
||||||
return OPAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( getline(&line,&n,fp) > 0 ){
|
|
||||||
ptr = strchr(line,' ');
|
|
||||||
if( ptr == NULL ){
|
|
||||||
rc = -1;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
*ptr = '\0';
|
|
||||||
ptr++;
|
|
||||||
if( strcmp(line, hname) == 0 ){
|
|
||||||
if( sscanf(ptr,"%lf %lf", &hnp_rtt, &hnp_offs) != 2 ){
|
|
||||||
rc = -1;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !found ){
|
|
||||||
opal_output(0,"opal_timing_clocksync_read: Can't find my host %s in %s", hname, fname);
|
|
||||||
rc = OPAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_exit:
|
|
||||||
|
|
||||||
if( line != NULL ){
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fp != NULL ){
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int opal_timing_set_jobid(char *jid)
|
|
||||||
{
|
|
||||||
jobid = strdup(jid);
|
|
||||||
if( jobid == NULL ){
|
|
||||||
return OPAL_ERROR;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get current timestamp. Derived from MPI_Wtime */
|
|
||||||
|
|
||||||
static double get_ts_gettimeofday(void)
|
static double get_ts_gettimeofday(void)
|
||||||
{
|
{
|
||||||
double ret;
|
double ret;
|
||||||
@ -168,7 +67,7 @@ static double get_ts_usec(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static get_ts_t _init_timestamping(opal_timer_type_t type)
|
opal_timing_ts_func_t opal_timing_ts_func(opal_timer_type_t type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OPAL_TIMING_GET_TIME_OF_DAY:
|
case OPAL_TIMING_GET_TIME_OF_DAY:
|
||||||
@ -199,563 +98,3 @@ static get_ts_t _init_timestamping(opal_timer_type_t type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static opal_timing_event_t *opal_timing_event_alloc(opal_timing_t *t)
|
|
||||||
{
|
|
||||||
if( t->buffer_offset >= t->buffer_size ){
|
|
||||||
// notch timings overhead
|
|
||||||
double alloc_begin = t->get_ts();
|
|
||||||
|
|
||||||
t->buffer = malloc(sizeof(opal_timing_event_t)*t->buffer_size);
|
|
||||||
if( t->buffer == NULL ){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(t->buffer, 0, sizeof(opal_timing_event_t)*t->buffer_size);
|
|
||||||
|
|
||||||
double alloc_end = t->get_ts();
|
|
||||||
|
|
||||||
t->buffer_offset = 0;
|
|
||||||
t->buffer[0].fib = 1;
|
|
||||||
t->buffer[0].ts_ovh = alloc_end - alloc_begin;
|
|
||||||
}
|
|
||||||
int tmp = t->buffer_offset;
|
|
||||||
(t->buffer_offset)++;
|
|
||||||
return t->buffer + tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int opal_timing_init(opal_timing_t *t, opal_timer_type_t type)
|
|
||||||
{
|
|
||||||
memset(t,0,sizeof(*t));
|
|
||||||
|
|
||||||
t->next_id_cntr = 0;
|
|
||||||
t->current_id = -1;
|
|
||||||
/* initialize events list */
|
|
||||||
t->events = OBJ_NEW(opal_list_t);
|
|
||||||
/* Set buffer size */
|
|
||||||
t->buffer_size = OPAL_TIMING_BUFSIZE;
|
|
||||||
/* Set buffer_offset = buffer_size so new buffer
|
|
||||||
* will be allocated at first event report */
|
|
||||||
t->buffer_offset = t->buffer_size;
|
|
||||||
/* initialize gettime function */
|
|
||||||
t->get_ts = _init_timestamping(type);
|
|
||||||
if (NULL == t->get_ts) {
|
|
||||||
return OPAL_ERR_BAD_PARAM;
|
|
||||||
}
|
|
||||||
return OPAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
opal_timing_prep_t opal_timing_prep_ev(opal_timing_t *t, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
opal_timing_event_t *ev = opal_timing_event_alloc(t);
|
|
||||||
if( ev == NULL ){
|
|
||||||
opal_timing_prep_t p = { t, NULL, OPAL_ERR_OUT_OF_RESOURCE };
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
OBJ_CONSTRUCT(ev, opal_timing_event_t);
|
|
||||||
ev->ts = t->get_ts();
|
|
||||||
va_list args;
|
|
||||||
va_start( args, fmt );
|
|
||||||
vsnprintf(ev->descr, OPAL_TIMING_DESCR_MAX - 1, fmt, args);
|
|
||||||
ev->descr[OPAL_TIMING_DESCR_MAX-1] = '\0';
|
|
||||||
va_end( args );
|
|
||||||
opal_timing_prep_t p = { t, ev, 0 };
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
opal_timing_prep_t opal_timing_prep_ev_end(opal_timing_t *t, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
opal_timing_prep_t p = { t, NULL, 0 };
|
|
||||||
|
|
||||||
if( t->current_id >= 0 ){
|
|
||||||
opal_timing_event_t *ev = opal_timing_event_alloc(t);
|
|
||||||
if( ev == NULL ){
|
|
||||||
opal_timing_prep_t p = { t, NULL, OPAL_ERR_OUT_OF_RESOURCE };
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
OBJ_CONSTRUCT(ev, opal_timing_event_t);
|
|
||||||
ev->ts = t->get_ts();
|
|
||||||
p.ev = ev;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void opal_timing_add_step(opal_timing_prep_t p,
|
|
||||||
const char *func, const char *file, int line)
|
|
||||||
{
|
|
||||||
if( !p.errcode ) {
|
|
||||||
p.ev->func = func;
|
|
||||||
p.ev->file = file;
|
|
||||||
p.ev->line = line;
|
|
||||||
p.ev->type = OPAL_TIMING_TRACE;
|
|
||||||
opal_list_append(p.t->events, (opal_list_item_t*)p.ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add description of the interval */
|
|
||||||
int opal_timing_descr(opal_timing_prep_t p,
|
|
||||||
const char *func, const char *file, int line)
|
|
||||||
{
|
|
||||||
if( !p.errcode ){
|
|
||||||
p.ev->func = func;
|
|
||||||
p.ev->file = file;
|
|
||||||
p.ev->line = line;
|
|
||||||
p.ev->type = OPAL_TIMING_INTDESCR;
|
|
||||||
p.ev->id = p.t->next_id_cntr;
|
|
||||||
(p.t->next_id_cntr)++;
|
|
||||||
opal_list_append(p.t->events, (opal_list_item_t*)p.ev);
|
|
||||||
return p.ev->id;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void opal_timing_start_id(opal_timing_t *t, int id, const char *func, const char *file, int line)
|
|
||||||
{
|
|
||||||
/* No description is needed. If everything is OK
|
|
||||||
* it'll be included in opal_timing_start_init */
|
|
||||||
opal_timing_event_t *ev = opal_timing_event_alloc(t);
|
|
||||||
if( ev == NULL ){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OBJ_CONSTRUCT(ev, opal_timing_event_t);
|
|
||||||
|
|
||||||
t->current_id = id;
|
|
||||||
ev->ts = t->get_ts();
|
|
||||||
ev->func = func;
|
|
||||||
ev->file = file;
|
|
||||||
ev->line = line;
|
|
||||||
ev->type = OPAL_TIMING_INTBEGIN;
|
|
||||||
ev->id = id;
|
|
||||||
opal_list_append(t->events, (opal_list_item_t*)ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void opal_timing_end(opal_timing_t *t, int id, const char *func, const char *file, int line )
|
|
||||||
{
|
|
||||||
/* No description is needed. If everything is OK
|
|
||||||
* it'll be included in opal_timing_start_init */
|
|
||||||
opal_timing_event_t *ev = opal_timing_event_alloc(t);
|
|
||||||
if( ev == NULL ){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OBJ_CONSTRUCT(ev, opal_timing_event_t);
|
|
||||||
|
|
||||||
if( id < 0 ){
|
|
||||||
ev->id = t->current_id;
|
|
||||||
t->current_id = -1;
|
|
||||||
} else {
|
|
||||||
if( t->current_id == id ){
|
|
||||||
t->current_id = -1;
|
|
||||||
}
|
|
||||||
ev->id = id;
|
|
||||||
}
|
|
||||||
ev->ts = t->get_ts();
|
|
||||||
ev->func = func;
|
|
||||||
ev->file = file;
|
|
||||||
ev->line = line;
|
|
||||||
ev->type = OPAL_TIMING_INTEND;
|
|
||||||
opal_list_append(t->events, (opal_list_item_t*)ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void opal_timing_end_prep(opal_timing_prep_t p,
|
|
||||||
const char *func, const char *file, int line)
|
|
||||||
{
|
|
||||||
opal_timing_event_t *ev = p.ev;
|
|
||||||
|
|
||||||
if( !p.errcode && ( NULL != ev ) ){
|
|
||||||
assert( p.t->current_id >=0 );
|
|
||||||
ev->id = p.t->current_id;
|
|
||||||
p.t->current_id = -1;
|
|
||||||
ev->func = func;
|
|
||||||
ev->file = file;
|
|
||||||
ev->line = line;
|
|
||||||
ev->type = OPAL_TIMING_INTEND;
|
|
||||||
opal_list_append(p.t->events, (opal_list_item_t*)ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _prepare_descriptions(opal_timing_t *t, struct interval_descr **__descr)
|
|
||||||
{
|
|
||||||
struct interval_descr *descr;
|
|
||||||
opal_timing_event_t *ev, *next;
|
|
||||||
|
|
||||||
if( t->next_id_cntr == 0 ){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*__descr = malloc(sizeof(struct interval_descr) * t->next_id_cntr);
|
|
||||||
descr = *__descr;
|
|
||||||
memset(descr, 0, sizeof(struct interval_descr) * t->next_id_cntr);
|
|
||||||
|
|
||||||
OPAL_LIST_FOREACH_SAFE(ev, next, t->events, opal_timing_event_t){
|
|
||||||
|
|
||||||
/* opal_output(0,"EVENT: type = %d, id=%d, ts = %.12le, ovh = %.12le %s",
|
|
||||||
ev->type, ev->id, ev->ts, ev->ts_ovh,
|
|
||||||
ev->descr );
|
|
||||||
*/
|
|
||||||
switch(ev->type){
|
|
||||||
case OPAL_TIMING_INTDESCR:{
|
|
||||||
if( ev->id >= t->next_id_cntr){
|
|
||||||
char *file = opal_basename(ev->file);
|
|
||||||
opal_output(0,"opal_timing: bad event id at %s:%d:%s, ignore and remove",
|
|
||||||
file, ev->line, ev->func);
|
|
||||||
free(file);
|
|
||||||
opal_list_remove_item(t->events, (opal_list_item_t *)ev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if( NULL != descr[ev->id].descr_ev ){
|
|
||||||
opal_timing_event_t *prev = descr[ev->id].descr_ev;
|
|
||||||
char *file = opal_basename(ev->file);
|
|
||||||
char *file_prev = opal_basename(prev->file);
|
|
||||||
opal_output(0,"opal_timing: duplicated description at %s:%d:%s, "
|
|
||||||
"previous: %s:%d:%s, ignore and remove", file, ev->line, ev->func,
|
|
||||||
file_prev, prev->line, prev->func);
|
|
||||||
free(file);
|
|
||||||
free(file_prev);
|
|
||||||
opal_list_remove_item(t->events, (opal_list_item_t *)ev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
descr[ev->id].descr_ev = ev;
|
|
||||||
descr[ev->id].begin_ev = NULL;
|
|
||||||
descr[ev->id].interval = 0;
|
|
||||||
descr[ev->id].overhead = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OPAL_TIMING_INTBEGIN:
|
|
||||||
case OPAL_TIMING_INTEND:{
|
|
||||||
if( ev->id >= t->next_id_cntr || (NULL == descr[ev->id].descr_ev ) ){
|
|
||||||
char *file = opal_basename(ev->file);
|
|
||||||
opal_output(0,"opal_timing: bad event id at %s:%d:%s, ignore and remove",
|
|
||||||
file, ev->line, ev->func);
|
|
||||||
free(file);
|
|
||||||
opal_list_remove_item(t->events, (opal_list_item_t *)ev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OPAL_TIMING_TRACE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t->next_id_cntr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output lines in portions that doesn't
|
|
||||||
* exceed OPAL_TIMING_OUTBUF_SIZE for later automatic processing */
|
|
||||||
int opal_timing_report(opal_timing_t *t, char *fname)
|
|
||||||
{
|
|
||||||
opal_timing_event_t *ev;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
char *buf = NULL;
|
|
||||||
int buf_size = 0;
|
|
||||||
struct interval_descr *descr = NULL;
|
|
||||||
int rc = OPAL_SUCCESS;
|
|
||||||
|
|
||||||
if( fname != NULL ){
|
|
||||||
fp = fopen(fname,"a");
|
|
||||||
if( fp == NULL ){
|
|
||||||
opal_output(0, "opal_timing_report: Cannot open %s file"
|
|
||||||
" for writing timing information!",fname);
|
|
||||||
rc = OPAL_ERROR;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_prepare_descriptions(t, &descr);
|
|
||||||
|
|
||||||
buf = malloc(OPAL_TIMING_OUTBUF_SIZE+1);
|
|
||||||
if( buf == NULL ){
|
|
||||||
rc = OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
buf[0] = '\0';
|
|
||||||
|
|
||||||
double overhead = 0;
|
|
||||||
OPAL_LIST_FOREACH(ev, t->events, opal_timing_event_t){
|
|
||||||
char *line, *file;
|
|
||||||
if( ev->fib && opal_timing_overhead ){
|
|
||||||
overhead += ev->ts_ovh;
|
|
||||||
}
|
|
||||||
file = opal_basename(ev->file);
|
|
||||||
switch( ev->type ){
|
|
||||||
case OPAL_TIMING_INTDESCR:
|
|
||||||
// Service event, skip it.
|
|
||||||
continue;
|
|
||||||
case OPAL_TIMING_TRACE:
|
|
||||||
rc = asprintf(&line,"[%s:%d] %s \"%s\" [OPAL_TRACE] %s:%d %.10lf\n",
|
|
||||||
nodename, getpid(), jobid, ev->descr, file, ev->line,
|
|
||||||
ev->ts + hnp_offs + overhead);
|
|
||||||
break;
|
|
||||||
case OPAL_TIMING_INTBEGIN:
|
|
||||||
rc = asprintf(&line,"[%s:%d] %s \"%s [start]\" [OPAL_TRACE] %s:%d %.10lf\n",
|
|
||||||
nodename, getpid(), jobid, descr[ev->id].descr_ev->descr,
|
|
||||||
file, ev->line, ev->ts + hnp_offs + overhead);
|
|
||||||
break;
|
|
||||||
case OPAL_TIMING_INTEND:
|
|
||||||
rc = asprintf(&line,"[%s:%d] %s \"%s [stop]\" [OPAL_TRACE] %s:%d %.10lf\n",
|
|
||||||
nodename, getpid(), jobid, descr[ev->id].descr_ev->descr,
|
|
||||||
file, ev->line, ev->ts + hnp_offs + overhead);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(file);
|
|
||||||
|
|
||||||
if( rc < 0 ){
|
|
||||||
rc = OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
/* Sanity check: this shouldn't happen since description
|
|
||||||
* is event only 1KB long and other fields should never
|
|
||||||
* exceed 9KB */
|
|
||||||
assert( strlen(line) <= OPAL_TIMING_OUTBUF_SIZE );
|
|
||||||
|
|
||||||
|
|
||||||
if( buf_size + strlen(line) > OPAL_TIMING_OUTBUF_SIZE ){
|
|
||||||
// flush buffer to the file
|
|
||||||
if( fp != NULL ){
|
|
||||||
fprintf(fp,"%s", buf);
|
|
||||||
fprintf(fp,"\n");
|
|
||||||
} else {
|
|
||||||
opal_output(0,"\n%s", buf);
|
|
||||||
}
|
|
||||||
buf[0] = '\0';
|
|
||||||
buf_size = 0;
|
|
||||||
}
|
|
||||||
sprintf(buf,"%s%s", buf, line);
|
|
||||||
buf_size += strlen(line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( buf_size > 0 ){
|
|
||||||
// flush buffer to the file
|
|
||||||
if( fp != NULL ){
|
|
||||||
fprintf(fp,"%s", buf);
|
|
||||||
fprintf(fp,"\n");
|
|
||||||
} else {
|
|
||||||
opal_output(0,"\n%s", buf);
|
|
||||||
}
|
|
||||||
buf[0] = '\0';
|
|
||||||
buf_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_exit:
|
|
||||||
if( NULL != descr ){
|
|
||||||
free(descr);
|
|
||||||
}
|
|
||||||
if( buf != NULL ){
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
if( fp != NULL ){
|
|
||||||
fflush(fp);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output events as one buffer so the data won't be mixed
|
|
||||||
* with other output. This function is supposed to be human readable.
|
|
||||||
* The output goes only to stdout. */
|
|
||||||
int opal_timing_deltas(opal_timing_t *t, char *fname)
|
|
||||||
{
|
|
||||||
opal_timing_event_t *ev;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
char *buf = NULL;
|
|
||||||
struct interval_descr *descr = NULL;
|
|
||||||
int i, rc = OPAL_SUCCESS;
|
|
||||||
size_t buf_size = 0, buf_used = 0;
|
|
||||||
|
|
||||||
if( fname != NULL ){
|
|
||||||
fp = fopen(fname,"a");
|
|
||||||
if( fp == NULL ){
|
|
||||||
opal_output(0, "opal_timing_report: Cannot open %s file"
|
|
||||||
" for writing timing information!",fname);
|
|
||||||
rc = OPAL_ERROR;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_prepare_descriptions(t, &descr);
|
|
||||||
|
|
||||||
OPAL_LIST_FOREACH(ev, t->events, opal_timing_event_t){
|
|
||||||
int id;
|
|
||||||
if( ev->fib ){
|
|
||||||
/* this event caused buffered memory allocation
|
|
||||||
* for events. Account the overhead for all active
|
|
||||||
* intervals. */
|
|
||||||
int i;
|
|
||||||
for( i = 0; i < t->next_id_cntr; i++){
|
|
||||||
if( (NULL != descr[i].descr_ev) && (NULL != descr[i].begin_ev) ){
|
|
||||||
if( opal_timing_overhead ){
|
|
||||||
descr[i].overhead += ev->ts_ovh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we already process all OPAL_TIMING_DESCR events
|
|
||||||
* and we ignore OPAL_TIMING_EVENT */
|
|
||||||
if( ev->type == OPAL_TIMING_INTDESCR ||
|
|
||||||
ev->type == OPAL_TIMING_TRACE){
|
|
||||||
/* skip */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = ev->id;
|
|
||||||
if( id < 0 || id >= t->next_id_cntr ){
|
|
||||||
char *file = opal_basename(ev->file);
|
|
||||||
opal_output(0,"opal_timing_deltas: bad interval event id: %d at %s:%d:%s (maxid=%d)",
|
|
||||||
id, file, ev->line, ev->func, t->next_id_cntr - 1 );
|
|
||||||
free(file);
|
|
||||||
/* skip */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* id's assigned auomatically. Ther shouldn't be any gaps in descr[] */
|
|
||||||
assert( NULL != descr[id].descr_ev);
|
|
||||||
|
|
||||||
if( ev->type == OPAL_TIMING_INTBEGIN ){
|
|
||||||
if( NULL != descr[id].begin_ev ){
|
|
||||||
/* the measurement on this interval was already
|
|
||||||
* started! */
|
|
||||||
opal_timing_event_t *prev = descr[ev->id].begin_ev;
|
|
||||||
char *file = opal_basename(ev->file);
|
|
||||||
char *file_prev = opal_basename(prev->file);
|
|
||||||
opal_output(0,"opal_timing_deltas: duplicated start statement at %s:%d:%s, "
|
|
||||||
"previous: %s:%d:%s", file, ev->line, ev->func,
|
|
||||||
file_prev, prev->line, prev->func);
|
|
||||||
free(file);
|
|
||||||
free(file_prev);
|
|
||||||
} else {
|
|
||||||
/* save pointer to the start of measurement event */
|
|
||||||
descr[id].begin_ev = ev;
|
|
||||||
}
|
|
||||||
/* done, go to the next event */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ev->type == OPAL_TIMING_INTEND ){
|
|
||||||
if( NULL == descr[id].begin_ev ){
|
|
||||||
/* the measurement on this interval wasn't started! */
|
|
||||||
char *file = opal_basename(ev->file);
|
|
||||||
opal_output(0,"opal_timing_deltas: inteval end without start at %s:%d:%s",
|
|
||||||
file, ev->line, ev->func );
|
|
||||||
free(file);
|
|
||||||
} else {
|
|
||||||
descr[id].interval += ev->ts - descr[id].begin_ev->ts;
|
|
||||||
descr[id].begin_ev = NULL;
|
|
||||||
if( ev->fib ){
|
|
||||||
descr[id].overhead += ev->ts_ovh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shouldn't ever get here: bad ev->type */
|
|
||||||
opal_output(0, "opal_timing_deltas: bad event type %d", ev->type);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = malloc(OPAL_TIMING_OUTBUF_SIZE + 1);
|
|
||||||
if( buf == NULL ){
|
|
||||||
rc = OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
buf[0] = '\0';
|
|
||||||
buf_size = OPAL_TIMING_OUTBUF_SIZE + 1;
|
|
||||||
buf_used = 0;
|
|
||||||
for(i = 0; i < t->next_id_cntr; i++){
|
|
||||||
char *line = NULL;
|
|
||||||
size_t line_size;
|
|
||||||
rc = asprintf(&line,"[%s:%d] %s \"%s\" [OPAL_OVHD] %le\n",
|
|
||||||
nodename, getpid(), jobid, descr[i].descr_ev->descr,
|
|
||||||
descr[i].interval - descr[i].overhead);
|
|
||||||
if( rc < 0 ){
|
|
||||||
rc = OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
rc = 0;
|
|
||||||
line_size = strlen(line);
|
|
||||||
|
|
||||||
/* Sanity check: this shouldn't happen since description
|
|
||||||
* is event only 1KB long and other fields should never
|
|
||||||
* exceed 9KB */
|
|
||||||
assert( line_size <= OPAL_TIMING_OUTBUF_SIZE );
|
|
||||||
|
|
||||||
if( buf_used + strlen(line) > buf_size ){
|
|
||||||
// Increase output buffer
|
|
||||||
while( buf_used + line_size > buf_size && buf_size < DELTAS_SANE_LIMIT){
|
|
||||||
buf_size += OPAL_TIMING_OUTBUF_SIZE + 1;
|
|
||||||
}
|
|
||||||
if( buf_size > DELTAS_SANE_LIMIT ){
|
|
||||||
opal_output(0, "opal_timing_report: delta sane limit overflow (%u > %u)!\n",
|
|
||||||
(unsigned int)buf_size, DELTAS_SANE_LIMIT);
|
|
||||||
free(line);
|
|
||||||
rc = OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
buf = realloc(buf, buf_size);
|
|
||||||
if( buf == NULL ){
|
|
||||||
opal_output(0, "opal_timing_deltas: Out of memory!\n");
|
|
||||||
rc = OPAL_ERR_OUT_OF_RESOURCE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprintf(buf,"%s%s", buf, line);
|
|
||||||
buf_used += line_size;
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( buf_used > 0 ){
|
|
||||||
// flush buffer to the file
|
|
||||||
if( fp != NULL ){
|
|
||||||
fprintf(fp,"%s", buf);
|
|
||||||
fprintf(fp,"\n");
|
|
||||||
} else {
|
|
||||||
opal_output(0,"\n%s", buf);
|
|
||||||
}
|
|
||||||
buf[0] = '\0';
|
|
||||||
buf_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_exit:
|
|
||||||
if( NULL != descr ){
|
|
||||||
free(descr);
|
|
||||||
}
|
|
||||||
if( NULL != buf ){
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
if( fp != NULL ){
|
|
||||||
fflush(fp);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void opal_timing_release(opal_timing_t *t)
|
|
||||||
{
|
|
||||||
int cnt = opal_list_get_size(t->events);
|
|
||||||
|
|
||||||
if( cnt > 0 ){
|
|
||||||
opal_list_t *tmp = OBJ_NEW(opal_list_t);
|
|
||||||
int i;
|
|
||||||
for(i=0; i<cnt; i++){
|
|
||||||
opal_timing_event_t *ev = (opal_timing_event_t *)opal_list_remove_first(t->events);
|
|
||||||
if( ev->fib ){
|
|
||||||
opal_list_append(tmp,(opal_list_item_t*)ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt = opal_list_get_size(tmp);
|
|
||||||
for(i=0; i<cnt; i++){
|
|
||||||
opal_timing_event_t *ev = (opal_timing_event_t *)opal_list_remove_first(tmp);
|
|
||||||
free(ev);
|
|
||||||
}
|
|
||||||
OBJ_RELEASE(tmp);
|
|
||||||
} else {
|
|
||||||
// Error case. At list one event was inserted at initialization.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
OBJ_RELEASE(t->events);
|
|
||||||
t->events = NULL;
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Artem Polyakov <artpol84@gmail.com>
|
* Copyright (C) 2014 Artem Polyakov <artpol84@gmail.com>
|
||||||
* Copyright (c) 2014 Intel, Inc. All rights reserved.
|
* Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2017 Mellanox Technologies Ltd. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
@ -25,426 +26,200 @@ typedef enum {
|
|||||||
|
|
||||||
#if OPAL_ENABLE_TIMING
|
#if OPAL_ENABLE_TIMING
|
||||||
|
|
||||||
#define OPAL_TIMING_DESCR_MAX 1024
|
typedef double (*opal_timing_ts_func_t)(void);
|
||||||
#define OPAL_TIMING_BUFSIZE 32
|
|
||||||
#define OPAL_TIMING_OUTBUF_SIZE (10*1024)
|
|
||||||
|
|
||||||
typedef enum {
|
#define OPAL_TIMING_STR_LEN 256
|
||||||
OPAL_TIMING_TRACE,
|
|
||||||
OPAL_TIMING_INTDESCR,
|
|
||||||
OPAL_TIMING_INTBEGIN,
|
|
||||||
OPAL_TIMING_INTEND
|
|
||||||
} opal_event_type_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
opal_list_item_t super;
|
char id[OPAL_TIMING_STR_LEN], cntr_env[OPAL_TIMING_STR_LEN];
|
||||||
int fib;
|
int enabled, error;
|
||||||
opal_event_type_t type;
|
int cntr;
|
||||||
const char *func;
|
double ts;
|
||||||
const char *file;
|
opal_timing_ts_func_t get_ts;
|
||||||
int line;
|
} opal_timing_env_t;
|
||||||
double ts, ts_ovh;
|
|
||||||
char descr[OPAL_TIMING_DESCR_MAX];
|
|
||||||
int id;
|
|
||||||
} opal_timing_event_t;
|
|
||||||
|
|
||||||
typedef double (*get_ts_t)(void);
|
opal_timing_ts_func_t opal_timing_ts_func(opal_timer_type_t type);
|
||||||
|
|
||||||
typedef struct opal_timing_t
|
#define OPAL_TIMING_ENV_START_TYPE(func, _nm, type, prefix) \
|
||||||
{
|
do { \
|
||||||
int next_id_cntr;
|
char *ptr = NULL; \
|
||||||
// not thread safe!
|
char *_prefix = prefix; \
|
||||||
// The whole implementation is not thread safe now
|
int n; \
|
||||||
// since it is supposed to be used in orte service
|
if( NULL == prefix ){ \
|
||||||
// thread only. Fix in the future or now?
|
_prefix = ""; \
|
||||||
int current_id;
|
} \
|
||||||
opal_list_t *events;
|
(_nm)->error = 0; \
|
||||||
opal_timing_event_t *buffer;
|
n = snprintf((_nm)->id, OPAL_TIMING_STR_LEN, "%s%s", _prefix, func); \
|
||||||
size_t buffer_offset, buffer_size;
|
if( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
get_ts_t get_ts;
|
(_nm)->error = 1; \
|
||||||
} opal_timing_t;
|
} \
|
||||||
|
n = sprintf((_nm)->cntr_env,"OMPI_TIMING_%s%s_CNT", prefix, (_nm)->id); \
|
||||||
|
if( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
(_nm)->error = 1; \
|
||||||
|
} \
|
||||||
|
ptr = getenv((_nm)->id); \
|
||||||
|
if( NULL == ptr || strcmp(ptr, "1")){ \
|
||||||
|
(_nm)->enabled = 0; \
|
||||||
|
} \
|
||||||
|
(_nm)->get_ts = opal_timing_ts_func(type); \
|
||||||
|
ptr = getenv("OPAL_TIMING_ENABLE"); \
|
||||||
|
if (NULL != ptr) { \
|
||||||
|
(_nm)->enabled = atoi(ptr); \
|
||||||
|
} \
|
||||||
|
(_nm)->cntr = 0; \
|
||||||
|
ptr = getenv((_nm)->id); \
|
||||||
|
if( NULL != ptr ){ \
|
||||||
|
(_nm)->cntr = atoi(ptr); \
|
||||||
|
} \
|
||||||
|
(_nm)->ts = (_nm)->get_ts(); \
|
||||||
|
if ( 0 != (_nm)->error ){ \
|
||||||
|
(_nm)->enabled = 0; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
typedef struct {
|
#define OPAL_TIMING_ENV_INIT(name) \
|
||||||
opal_timing_t *t;
|
opal_timing_env_t name ## _val, *name = &(name ## _val); \
|
||||||
opal_timing_event_t *ev;
|
OPAL_TIMING_ENV_START_TYPE(__func__, name, OPAL_TIMING_AUTOMATIC_TIMER, "");
|
||||||
int errcode;
|
|
||||||
} opal_timing_prep_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read synchronisation information from the file
|
/* We use function names for identification
|
||||||
* provided through the MCA parameter.
|
* however this might be a problem for the private
|
||||||
* Should not be directly used, for service purposes.
|
* functions declared as static as their names may
|
||||||
*
|
* conflict.
|
||||||
* @param sync_file Name of the file to read
|
* Use prefix to do a finer-grained identification if needed
|
||||||
*
|
|
||||||
* @retval OPAL_SUCCESS On success
|
|
||||||
* @retval OPAL_ERROR On failure
|
|
||||||
*/
|
*/
|
||||||
int opal_timing_clocksync_read(char *sync_file);
|
#define OPAL_TIMING_ENV_INIT_PREFIX(prefix, name) \
|
||||||
|
do { \
|
||||||
|
opal_timing_env_t name ## _val, *name = &(name ## _val); \
|
||||||
|
*name = OPAL_TIMING_ENV_START_TYPE(__func__, OPAL_TIMING_AUTOMATIC_TIMER, prefix); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/**
|
#define OPAL_TIMING_ENV_NEXT(h, ...) \
|
||||||
* Pass string representation of ORTE job ID down to the OPAL.
|
do { \
|
||||||
* Should not be directly used, for service purposes.
|
int n; \
|
||||||
*
|
char buf1[OPAL_TIMING_STR_LEN], buf2[OPAL_TIMING_STR_LEN]; \
|
||||||
* @param jid job id
|
double time; \
|
||||||
*
|
char *filename; \
|
||||||
* @retval OPAL_SUCCESS On success
|
if( h->enabled ){ \
|
||||||
* @retval OPAL_ERROR On failure
|
/* enabled codepath */ \
|
||||||
|
time = h->get_ts() - h->ts; \
|
||||||
|
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_DESC_%d", h->id, h->cntr); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
n = snprintf(buf2, OPAL_TIMING_STR_LEN, __VA_ARGS__ ); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
setenv(buf1, buf2, 1); \
|
||||||
|
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_VAL_%d", h->id, h->cntr); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%lf", time); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
setenv(buf1, buf2, 1); \
|
||||||
|
filename = strrchr(__FILE__, '/') + 1; \
|
||||||
|
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_FILE_%d", h->id, h->cntr); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%s", filename); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
setenv(buf1, buf2, 1); \
|
||||||
|
h->cntr++; \
|
||||||
|
sprintf(buf1, "%d", h->cntr); \
|
||||||
|
setenv(h->cntr_env, buf1, 1); \
|
||||||
|
/* We don't include env operations into the consideration.
|
||||||
|
* Hopefully this will help to make measurements more accurate.
|
||||||
|
*/ \
|
||||||
|
h->ts = h->get_ts(); \
|
||||||
|
} \
|
||||||
|
if (h->error) { \
|
||||||
|
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_ERROR", h->id);\
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%d", h->error); \
|
||||||
|
if ( n > OPAL_TIMING_STR_LEN ){ \
|
||||||
|
h->error = 1; \
|
||||||
|
} \
|
||||||
|
setenv(buf1, buf2, 1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* This function supposed to be called from the code that will
|
||||||
|
* do the postprocessing, i.e. OMPI timing portion that will
|
||||||
|
* do the reduction of accumulated values
|
||||||
*/
|
*/
|
||||||
int opal_timing_set_jobid(char *jid);
|
#define OPAL_TIMING_ENV_CNT_PREFIX(prefix, func, _cnt) \
|
||||||
|
do { \
|
||||||
|
char ename[OPAL_TIMING_STR_LEN]; \
|
||||||
|
char *ptr = NULL; \
|
||||||
|
int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_CNT", prefix, func); \
|
||||||
|
(_cnt) = 0; \
|
||||||
|
if ( n <= OPAL_TIMING_STR_LEN ){ \
|
||||||
|
ptr = getenv(ename); \
|
||||||
|
if( NULL != ptr ){ (_cnt) = atoi(ptr); }; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/**
|
#define OPAL_TIMING_ENV_ERROR_PREFIX(prefix, func, _err) \
|
||||||
* Initialize timing structure.
|
do { \
|
||||||
*
|
char ename[OPAL_TIMING_STR_LEN]; \
|
||||||
* @param t pointer to the timing handler structure
|
(_err) = 0; \
|
||||||
*
|
char *ptr = NULL; \
|
||||||
* @retval OPAL_SUCCESS On success
|
int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_ERROR", prefix, func); \
|
||||||
* @retval OPAL_ERROR On failure
|
if ( n <= OPAL_TIMING_STR_LEN ){ \
|
||||||
*/
|
ptr = getenv(ename); \
|
||||||
int opal_timing_init(opal_timing_t *t, opal_timer_type_t type);
|
if( NULL != ptr ){ (_err) = atoi(ptr); }; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/**
|
#define OPAL_TIMING_ENV_CNT(func, _cnt) \
|
||||||
* Prepare timing event, do all printf-like processing.
|
OPAL_TIMING_ENV_CNT_PREFIX("", func, _cnt)
|
||||||
* Should not be directly used - for service purposes only.
|
|
||||||
*
|
|
||||||
* @param t pointer to the timing handler structure
|
|
||||||
* @param fmt printf-like format
|
|
||||||
* @param ... other parameters that should be converted to string representation
|
|
||||||
*
|
|
||||||
* @retval partly filled opal_timing_prep_t structure
|
|
||||||
*/
|
|
||||||
opal_timing_prep_t opal_timing_prep_ev(opal_timing_t *t, const char *fmt, ...);
|
|
||||||
|
|
||||||
/**
|
#define OPAL_TIMING_ENV_GETDESC_PREFIX(prefix, filename, func, i, desc, _t) \
|
||||||
* Prepare timing event, ignore printf-like processing.
|
do { \
|
||||||
* Should not be directly used - for service purposes only.
|
char vname[OPAL_TIMING_STR_LEN]; \
|
||||||
*
|
(_t) = 0.0; \
|
||||||
* @param t pointer to the timing handler structure
|
sprintf(vname, "OMPI_TIMING_%s%s_FILE_%d", prefix, func, i); \
|
||||||
* @param fmt printf-like format
|
*filename = getenv(vname); \
|
||||||
* @param ... other parameters that should be converted to string representation
|
sprintf(vname, "OMPI_TIMING_%s%s_DESC_%d", prefix, func, i); \
|
||||||
*
|
*desc = getenv(vname); \
|
||||||
* @retval partly filled opal_timing_prep_t structure
|
sprintf(vname, "OMPI_TIMING_%s%s_VAL_%d", prefix, func, i); \
|
||||||
*/
|
char *ptr = getenv(vname); \
|
||||||
opal_timing_prep_t opal_timing_prep_ev_end(opal_timing_t *t, const char *fmt, ...);
|
if ( NULL != ptr ) { \
|
||||||
|
sscanf(ptr,"%lf", &(_t)); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/**
|
#define OPAL_TIMING_ENV_GETDESC(file, func, index, desc) \
|
||||||
* Enqueue timing event into the list of events in handler 't'.
|
OPAL_TIMING_ENV_GETDESC_PREFIX("", file, func, index, desc)
|
||||||
*
|
|
||||||
* @param p result of opal_timing_prep_ev
|
|
||||||
* @param func function name where event occurs
|
|
||||||
* @param file file name where event occurs
|
|
||||||
* @param line line number in the file
|
|
||||||
*
|
|
||||||
* @retval
|
|
||||||
*/
|
|
||||||
void opal_timing_add_step(opal_timing_prep_t p, const char *func,
|
|
||||||
const char *file, int line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enqueue the description of the interval into a list of events
|
|
||||||
* in handler 't'.
|
|
||||||
*
|
|
||||||
* @param p result of opal_timing_prep_ev
|
|
||||||
* @param func function name where event occurs
|
|
||||||
* @param file file name where event occurs
|
|
||||||
* @param line line number in the file
|
|
||||||
*
|
|
||||||
* @retval id of event interval
|
|
||||||
*/
|
|
||||||
int opal_timing_descr(opal_timing_prep_t p, const char *func,
|
|
||||||
const char *file, int line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enqueue the beginning of timing interval that already has the
|
|
||||||
* description and assigned id into the list of events
|
|
||||||
* in handler 't'.
|
|
||||||
*
|
|
||||||
* @param p result of opal_timing_prep_ev
|
|
||||||
* @param func function name where event occurs
|
|
||||||
* @param file file name where event occurs
|
|
||||||
* @param line line number in the file
|
|
||||||
*
|
|
||||||
* @retval
|
|
||||||
*/
|
|
||||||
void opal_timing_start_id(opal_timing_t *t, int id, const char *func,
|
|
||||||
const char *file, int line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enqueue the end of timing interval that already has
|
|
||||||
* description and assigned id into the list of events
|
|
||||||
* in handler 't'.
|
|
||||||
*
|
|
||||||
* @param p result of opal_timing_prep_ev
|
|
||||||
* @param func function name where event occurs
|
|
||||||
* @param file file name where event occurs
|
|
||||||
* @param line line number in the file
|
|
||||||
*
|
|
||||||
* @retval
|
|
||||||
*/
|
|
||||||
void opal_timing_end(opal_timing_t *t, int id, const char *func,
|
|
||||||
const char *file, int line );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enqueue both description and start of timing interval
|
|
||||||
* into the list of events and assign its id.
|
|
||||||
*
|
|
||||||
* @param p result of opal_timing_prep_ev
|
|
||||||
* @param func function name where event occurs
|
|
||||||
* @param file file name where event occurs
|
|
||||||
* @param line line number in the file
|
|
||||||
*
|
|
||||||
* @retval interval id
|
|
||||||
*/
|
|
||||||
static inline int opal_timing_start_init(opal_timing_prep_t p,
|
|
||||||
const char *func, const char *file, int line)
|
|
||||||
{
|
|
||||||
int id = opal_timing_descr(p, func, file, line);
|
|
||||||
if( id < 0 )
|
|
||||||
return id;
|
|
||||||
opal_timing_start_id(p.t, id, func, file, line);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The wrapper that is used to stop last measurement in OPAL_TIMING_MNEXT.
|
|
||||||
*
|
|
||||||
* @param p result of opal_timing_prep_ev
|
|
||||||
* @param func function name where event occurs
|
|
||||||
* @param file file name where event occurs
|
|
||||||
* @param line line number in the file
|
|
||||||
*
|
|
||||||
* @retval interval id
|
|
||||||
*/
|
|
||||||
void opal_timing_end_prep(opal_timing_prep_t p,
|
|
||||||
const char *func, const char *file, int line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report all events that were enqueued in the timing handler 't'.
|
|
||||||
* - if fname == NULL the output will be done using opal_output and
|
|
||||||
* each line will be prefixed with "prefix" to ease grep'ing.
|
|
||||||
* - otherwise the corresponding file will be used for output in "append" mode
|
|
||||||
* WARRNING: not all filesystems provide enough support for that feature, some records may
|
|
||||||
* disappear.
|
|
||||||
*
|
|
||||||
* @param t timing handler
|
|
||||||
* @param account_overhead consider malloc overhead introduced by timing code
|
|
||||||
* @param prefix prefix to use when no fname was specifyed to ease grep'ing
|
|
||||||
* @param fname name of the output file (may be NULL)
|
|
||||||
*
|
|
||||||
* @retval OPAL_SUCCESS On success
|
|
||||||
* @retval OPAL_ERROR or OPAL_ERR_OUT_OF_RESOURCE On failure
|
|
||||||
*/
|
|
||||||
int opal_timing_report(opal_timing_t *t, char *fname);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report all intervals that were enqueued in the timing handler 't'.
|
|
||||||
* - if fname == NULL the output will be done using opal_output and
|
|
||||||
* each line will be prefixed with "prefix" to ease grep'ing.
|
|
||||||
* - otherwise the corresponding file will be used for output in "append" mode
|
|
||||||
* WARRNING: not all filesystems provide enough support for that feature, some records may
|
|
||||||
* disappear.
|
|
||||||
*
|
|
||||||
* @param t timing handler
|
|
||||||
* @param account_overhead consider malloc overhead introduced by timing code
|
|
||||||
* @param fname name of the output file (may be NULL)
|
|
||||||
*
|
|
||||||
* @retval OPAL_SUCCESS On success
|
|
||||||
* @retval OPAL_ERROR or OPAL_ERR_OUT_OF_RESOURCE On failure
|
|
||||||
*/
|
|
||||||
int opal_timing_deltas(opal_timing_t *t, char *fname);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Release all memory allocated for the timing handler 't'.
|
|
||||||
*
|
|
||||||
* @param t timing handler
|
|
||||||
*
|
|
||||||
* @retval
|
|
||||||
*/
|
|
||||||
void opal_timing_release(opal_timing_t *t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main macro for use in declaring opal timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_DECLARE(t) opal_timing_t t; /* need semicolon here to avoid warnings when not enabled */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main macro for use in declaring external opal timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_DECLARE_EXT(x, t) x extern opal_timing_t t; /* need semicolon here to avoid warnings when not enabled */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main macro for use in initializing opal timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_init()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_INIT(t) opal_timing_init(t, OPAL_TIMING_AUTOMATIC_TIMER)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main macro for use in initializing opal timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_init()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_INIT_EXT(t, type) opal_timing_init(t, type)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Macro that enqueues event with its description to the specified
|
|
||||||
* timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_add_step()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_EVENT(x) opal_timing_add_step( opal_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MDESCR: Measurement DESCRiption
|
|
||||||
* Introduce new timing measurement with string description for the specified
|
|
||||||
* timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_descr()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_MDESCR(x) opal_timing_descr( opal_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MSTART_ID: Measurement START by ID.
|
|
||||||
* Marks the beginning of the measurement with ID=id on the
|
|
||||||
* specified timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_start_id()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_MSTART_ID(t, id) opal_timing_start_id(t, id, __FUNCTION__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MSTART: Measurement START
|
|
||||||
* Introduce new timing measurement conjuncted with its start
|
|
||||||
* on the specifyed timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_start_init()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_MSTART(x) opal_timing_start_init( opal_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MSTOP: STOP Measurement
|
|
||||||
* Finishes the most recent measurement on the specifyed timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_end()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_MSTOP(t) opal_timing_end(t, -1, __FUNCTION__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MSTOP_ID: STOP Measurement with ID=id.
|
|
||||||
* Finishes the measurement with give ID on the specifyed timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_end()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_MSTOP_ID(t, id) opal_timing_end(t, id, __FUNCTION__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MNEXT: start NEXT Measurement
|
|
||||||
* Convinient macro, may be implemented with the sequence of three previously
|
|
||||||
* defined macroses:
|
|
||||||
* - finish current measurement (OPAL_TIMING_MSTOP);
|
|
||||||
* - introduce new timing measurement (OPAL_TIMING_MDESCR);
|
|
||||||
* - starts next measurement (OPAL_TIMING_MSTART_ID)
|
|
||||||
* on the specifyed timing handler;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_start_init()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_MNEXT(x) ( \
|
|
||||||
opal_timing_end_prep(opal_timing_prep_ev_end x, \
|
|
||||||
__FUNCTION__, __FILE__, __LINE__ ), \
|
|
||||||
opal_timing_start_init( opal_timing_prep_ev x, \
|
|
||||||
__FUNCTION__, __FILE__, __LINE__) \
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The macro for use in reporting collected events with absolute values;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @param enable flag that enables/disables reporting. Used for fine-grained timing.
|
|
||||||
* @see opal_timing_report()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_REPORT(enable, t) { \
|
|
||||||
if( enable ) { \
|
|
||||||
opal_timing_report(t, opal_timing_output); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The macro for use in reporting collected events with relative times;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @param enable flag that enables/disables reporting. Used for fine-grained timing.
|
|
||||||
* @see opal_timing_deltas()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_DELTAS(enable, t) { \
|
|
||||||
if( enable ) { \
|
|
||||||
opal_timing_deltas(t, opal_timing_output); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main macro for use in releasing allocated resources;
|
|
||||||
* will be "compiled out" when OPAL is configured without
|
|
||||||
* --enable-timing.
|
|
||||||
*
|
|
||||||
* @see opal_timing_release()
|
|
||||||
*/
|
|
||||||
#define OPAL_TIMING_RELEASE(t) opal_timing_release(t)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define OPAL_TIMING_DECLARE(t)
|
#define OPAL_TIMING_ENV_START_TYPE(func, type, prefix)
|
||||||
|
|
||||||
#define OPAL_TIMING_DECLARE_EXT(x, t)
|
#define OPAL_TIMING_ENV_INIT(name)
|
||||||
|
|
||||||
#define OPAL_TIMING_INIT(t)
|
#define OPAL_TIMING_ENV_INIT_PREFIX(prefix)
|
||||||
|
|
||||||
#define OPAL_TIMING_INIT_EXT(t, type)
|
#define OPAL_TIMING_ENV_NEXT(h, fmt, ... )
|
||||||
|
|
||||||
#define OPAL_TIMING_EVENT(x)
|
#define OPAL_TIMING_ENV_CNT_PREFIX(prefix, func)
|
||||||
|
|
||||||
#define OPAL_TIMING_MDESCR(x)
|
#define OPAL_TIMING_ENV_CNT(func)
|
||||||
|
|
||||||
#define OPAL_TIMING_MSTART_ID(t, id)
|
#define OPAL_TIMING_ENV_GETDESC_PREFIX(prefix, func, i, desc)
|
||||||
|
|
||||||
#define OPAL_TIMING_MSTART(x)
|
#define OPAL_TIMING_ENV_GETDESC(func, index, desc)
|
||||||
|
|
||||||
#define OPAL_TIMING_MSTOP(t)
|
#define OPAL_TIMING_ENV_ERROR_PREFIX(prefix, func)
|
||||||
|
|
||||||
#define OPAL_TIMING_MSTOP_ID(t, id)
|
|
||||||
|
|
||||||
#define OPAL_TIMING_MNEXT(x)
|
|
||||||
|
|
||||||
#define OPAL_TIMING_REPORT(enable, t)
|
|
||||||
|
|
||||||
#define OPAL_TIMING_DELTAS(enable, t)
|
|
||||||
|
|
||||||
#define OPAL_TIMING_RELEASE(t)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -49,8 +49,6 @@
|
|||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
|
|
||||||
OPAL_TIMING_DECLARE_EXT(ORTE_DECLSPEC, tm_oob)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience Typedef
|
* Convenience Typedef
|
||||||
*/
|
*/
|
||||||
|
@ -52,8 +52,6 @@
|
|||||||
* Global variables
|
* Global variables
|
||||||
*/
|
*/
|
||||||
orte_oob_base_t orte_oob_base = {0};
|
orte_oob_base_t orte_oob_base = {0};
|
||||||
OPAL_TIMING_DECLARE(tm_oob)
|
|
||||||
|
|
||||||
|
|
||||||
static int orte_oob_base_register(mca_base_register_flag_t flags)
|
static int orte_oob_base_register(mca_base_register_flag_t flags)
|
||||||
{
|
{
|
||||||
@ -109,9 +107,6 @@ static int orte_oob_base_close(void)
|
|||||||
|
|
||||||
OBJ_DESTRUCT(&orte_oob_base.peers);
|
OBJ_DESTRUCT(&orte_oob_base.peers);
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_oob, "Finish"));
|
|
||||||
OPAL_TIMING_REPORT(orte_oob_base.timing, &tm_oob);
|
|
||||||
|
|
||||||
return mca_base_framework_components_close(&orte_oob_base_framework, NULL);
|
return mca_base_framework_components_close(&orte_oob_base_framework, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +132,6 @@ static int orte_oob_base_open(mca_base_open_flag_t flags)
|
|||||||
orte_state.add_job_state(ORTE_JOB_STATE_FT_RESTART, orte_oob_base_ft_event, ORTE_ERROR_PRI);
|
orte_state.add_job_state(ORTE_JOB_STATE_FT_RESTART, orte_oob_base_ft_event, ORTE_ERROR_PRI);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OPAL_TIMING_INIT(&tm_oob);
|
|
||||||
|
|
||||||
/* Open up all available components */
|
/* Open up all available components */
|
||||||
return mca_base_framework_components_open(&orte_oob_base_framework, flags);
|
return mca_base_framework_components_open(&orte_oob_base_framework, flags);
|
||||||
}
|
}
|
||||||
|
@ -110,9 +110,6 @@ static int send_msg(mca_oob_tcp_peer_t* peer, mca_oob_tcp_send_t* msg)
|
|||||||
int iov_count, retries = 0;
|
int iov_count, retries = 0;
|
||||||
ssize_t remain = msg->sdbytes, rc;
|
ssize_t remain = msg->sdbytes, rc;
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_oob, "to %s %d bytes",
|
|
||||||
ORTE_NAME_PRINT(&(peer->name)), msg->sdbytes));
|
|
||||||
|
|
||||||
iov[0].iov_base = msg->sdptr;
|
iov[0].iov_base = msg->sdptr;
|
||||||
iov[0].iov_len = msg->sdbytes;
|
iov[0].iov_len = msg->sdbytes;
|
||||||
if (!msg->hdr_sent) {
|
if (!msg->hdr_sent) {
|
||||||
@ -346,9 +343,6 @@ void mca_oob_tcp_send_handler(int sd, short flags, void *cbdata)
|
|||||||
static int read_bytes(mca_oob_tcp_peer_t* peer)
|
static int read_bytes(mca_oob_tcp_peer_t* peer)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
#if OPAL_ENABLE_TIMING
|
|
||||||
int to_read = peer->recv_msg->rdbytes;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* read until all bytes recvd or error */
|
/* read until all bytes recvd or error */
|
||||||
while (0 < peer->recv_msg->rdbytes) {
|
while (0 < peer->recv_msg->rdbytes) {
|
||||||
@ -420,9 +414,6 @@ static int read_bytes(mca_oob_tcp_peer_t* peer)
|
|||||||
peer->recv_msg->rdptr += rc;
|
peer->recv_msg->rdptr += rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_oob, "from %s %d bytes",
|
|
||||||
ORTE_NAME_PRINT(&(peer->name)), to_read));
|
|
||||||
|
|
||||||
/* we read the full data block */
|
/* we read the full data block */
|
||||||
return ORTE_SUCCESS;
|
return ORTE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -437,9 +428,6 @@ void mca_oob_tcp_recv_handler(int sd, short flags, void *cbdata)
|
|||||||
mca_oob_tcp_peer_t* peer = (mca_oob_tcp_peer_t*)cbdata;
|
mca_oob_tcp_peer_t* peer = (mca_oob_tcp_peer_t*)cbdata;
|
||||||
int rc;
|
int rc;
|
||||||
orte_rml_send_t *snd;
|
orte_rml_send_t *snd;
|
||||||
#if OPAL_ENABLE_TIMING
|
|
||||||
bool timing_same_as_hdr = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
|
opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
|
||||||
"%s:tcp:recv:handler called for peer %s",
|
"%s:tcp:recv:handler called for peer %s",
|
||||||
@ -509,15 +497,7 @@ void mca_oob_tcp_recv_handler(int sd, short flags, void *cbdata)
|
|||||||
opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
|
opal_output_verbose(OOB_TCP_DEBUG_CONNECT, orte_oob_base_framework.framework_output,
|
||||||
"%s:tcp:recv:handler read hdr",
|
"%s:tcp:recv:handler read hdr",
|
||||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
|
||||||
#if OPAL_ENABLE_TIMING
|
|
||||||
int to_recv = peer->recv_msg->rdbytes;
|
|
||||||
#endif
|
|
||||||
if (ORTE_SUCCESS == (rc = read_bytes(peer))) {
|
if (ORTE_SUCCESS == (rc = read_bytes(peer))) {
|
||||||
#if OPAL_ENABLE_TIMING
|
|
||||||
timing_same_as_hdr = true;
|
|
||||||
#endif
|
|
||||||
OPAL_TIMING_EVENT((&tm_oob, "from %s %d bytes [header]",
|
|
||||||
ORTE_NAME_PRINT(&(peer->name)), to_recv));
|
|
||||||
/* completed reading the header */
|
/* completed reading the header */
|
||||||
peer->recv_msg->hdr_recvd = true;
|
peer->recv_msg->hdr_recvd = true;
|
||||||
/* convert the header */
|
/* convert the header */
|
||||||
@ -570,11 +550,6 @@ void mca_oob_tcp_recv_handler(int sd, short flags, void *cbdata)
|
|||||||
ORTE_NAME_PRINT(&peer->recv_msg->hdr.dst),
|
ORTE_NAME_PRINT(&peer->recv_msg->hdr.dst),
|
||||||
peer->recv_msg->hdr.tag);
|
peer->recv_msg->hdr.tag);
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_oob, "from %s %d bytes [body:%s]",
|
|
||||||
ORTE_NAME_PRINT(&(peer->name)),
|
|
||||||
(int)peer->recv_msg->hdr.nbytes,
|
|
||||||
(timing_same_as_hdr) ? "same" : "next"));
|
|
||||||
|
|
||||||
/* am I the intended recipient (header was already converted back to host order)? */
|
/* am I the intended recipient (header was already converted back to host order)? */
|
||||||
if (peer->recv_msg->hdr.dst.jobid == ORTE_PROC_MY_NAME->jobid &&
|
if (peer->recv_msg->hdr.dst.jobid == ORTE_PROC_MY_NAME->jobid &&
|
||||||
peer->recv_msg->hdr.dst.vpid == ORTE_PROC_MY_NAME->vpid) {
|
peer->recv_msg->hdr.dst.vpid == ORTE_PROC_MY_NAME->vpid) {
|
||||||
|
@ -55,8 +55,6 @@
|
|||||||
|
|
||||||
BEGIN_C_DECLS
|
BEGIN_C_DECLS
|
||||||
|
|
||||||
OPAL_TIMING_DECLARE_EXT(ORTE_DECLSPEC, tm_rml)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MCA Framework
|
* MCA Framework
|
||||||
*/
|
*/
|
||||||
|
@ -56,7 +56,6 @@ orte_rml_base_API_t orte_rml = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
orte_rml_base_t orte_rml_base = {{{0}}};
|
orte_rml_base_t orte_rml_base = {{{0}}};
|
||||||
OPAL_TIMING_DECLARE(tm_rml)
|
|
||||||
|
|
||||||
orte_rml_component_t *orte_rml_component = NULL;
|
orte_rml_component_t *orte_rml_component = NULL;
|
||||||
|
|
||||||
@ -136,8 +135,6 @@ static int orte_rml_base_close(void)
|
|||||||
cleanup(0, 0, NULL);
|
cleanup(0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
OPAL_TIMING_REPORT(orte_rml_base.timing, &tm_rml);
|
|
||||||
|
|
||||||
return mca_base_framework_components_close(&orte_rml_base_framework, NULL);
|
return mca_base_framework_components_close(&orte_rml_base_framework, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +148,6 @@ static int orte_rml_base_open(mca_base_open_flag_t flags)
|
|||||||
OBJ_CONSTRUCT(&orte_rml_base.conduits, opal_pointer_array_t);
|
OBJ_CONSTRUCT(&orte_rml_base.conduits, opal_pointer_array_t);
|
||||||
opal_pointer_array_init(&orte_rml_base.conduits,1,INT_MAX,1);
|
opal_pointer_array_init(&orte_rml_base.conduits,1,INT_MAX,1);
|
||||||
|
|
||||||
OPAL_TIMING_INIT(&tm_rml);
|
|
||||||
/* Open up all available components */
|
/* Open up all available components */
|
||||||
return mca_base_framework_components_open(&orte_rml_base_framework, flags);
|
return mca_base_framework_components_open(&orte_rml_base_framework, flags);
|
||||||
}
|
}
|
||||||
|
@ -165,9 +165,6 @@ void orte_rml_base_process_msg(int fd, short flags, void *cbdata)
|
|||||||
ORTE_NAME_PRINT(&msg->sender),
|
ORTE_NAME_PRINT(&msg->sender),
|
||||||
msg->tag));
|
msg->tag));
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_rml,"from %s %d bytes",
|
|
||||||
ORTE_NAME_PRINT(&msg->sender), msg->iov.iov_len));
|
|
||||||
|
|
||||||
/* if this message is just to warmup the connection, then drop it */
|
/* if this message is just to warmup the connection, then drop it */
|
||||||
if (ORTE_RML_TAG_WARMUP_CONNECTION == msg->tag) {
|
if (ORTE_RML_TAG_WARMUP_CONNECTION == msg->tag) {
|
||||||
OBJ_RELEASE(msg);
|
OBJ_RELEASE(msg);
|
||||||
|
@ -99,8 +99,6 @@ int orte_rml_oob_send_nb(struct orte_rml_base_module_t *mod,
|
|||||||
return ORTE_ERR_BAD_PARAM;
|
return ORTE_ERR_BAD_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_rml, "to %s", ORTE_NAME_PRINT(peer)));
|
|
||||||
|
|
||||||
/* if this is a message to myself, then just post the message
|
/* if this is a message to myself, then just post the message
|
||||||
* for receipt - no need to dive into the oob
|
* for receipt - no need to dive into the oob
|
||||||
*/
|
*/
|
||||||
@ -207,8 +205,6 @@ int orte_rml_oob_send_buffer_nb(struct orte_rml_base_module_t *mod,
|
|||||||
return ORTE_ERR_BAD_PARAM;
|
return ORTE_ERR_BAD_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
OPAL_TIMING_EVENT((&tm_rml, "to %s", ORTE_NAME_PRINT(peer)));
|
|
||||||
|
|
||||||
/* if this is a message to myself, then just post the message
|
/* if this is a message to myself, then just post the message
|
||||||
* for receipt - no need to dive into the oob
|
* for receipt - no need to dive into the oob
|
||||||
*/
|
*/
|
||||||
|
@ -134,6 +134,7 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
|
OPAL_TIMING_ENV_INIT(tmng);
|
||||||
|
|
||||||
if (0 < orte_initialized) {
|
if (0 < orte_initialized) {
|
||||||
/* track number of times we have been called */
|
/* track number of times we have been called */
|
||||||
@ -152,12 +153,16 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
opal_snprintf_jobid = orte_util_snprintf_jobid;
|
opal_snprintf_jobid = orte_util_snprintf_jobid;
|
||||||
opal_convert_string_to_jobid = _convert_string_to_jobid;
|
opal_convert_string_to_jobid = _convert_string_to_jobid;
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "initializations");
|
||||||
|
|
||||||
/* initialize the opal layer */
|
/* initialize the opal layer */
|
||||||
if (ORTE_SUCCESS != (ret = opal_init(pargc, pargv))) {
|
if (ORTE_SUCCESS != (ret = opal_init(pargc, pargv))) {
|
||||||
error = "opal_init";
|
error = "opal_init";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "opal_init");
|
||||||
|
|
||||||
/* ensure we know the type of proc for when we finalize */
|
/* ensure we know the type of proc for when we finalize */
|
||||||
orte_process_info.proc_type = flags;
|
orte_process_info.proc_type = flags;
|
||||||
|
|
||||||
@ -167,27 +172,37 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_locks_init");
|
||||||
|
|
||||||
/* Register all MCA Params */
|
/* Register all MCA Params */
|
||||||
if (ORTE_SUCCESS != (ret = orte_register_params())) {
|
if (ORTE_SUCCESS != (ret = orte_register_params())) {
|
||||||
error = "orte_register_params";
|
error = "orte_register_params";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_register_params");
|
||||||
|
|
||||||
/* setup the orte_show_help system */
|
/* setup the orte_show_help system */
|
||||||
if (ORTE_SUCCESS != (ret = orte_show_help_init())) {
|
if (ORTE_SUCCESS != (ret = orte_show_help_init())) {
|
||||||
error = "opal_output_init";
|
error = "opal_output_init";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_show_help_init");
|
||||||
|
|
||||||
/* register handler for errnum -> string conversion */
|
/* register handler for errnum -> string conversion */
|
||||||
opal_error_register("ORTE", ORTE_ERR_BASE, ORTE_ERR_MAX, orte_err2str);
|
opal_error_register("ORTE", ORTE_ERR_BASE, ORTE_ERR_MAX, orte_err2str);
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "opal_error_register");
|
||||||
|
|
||||||
/* Ensure the rest of the process info structure is initialized */
|
/* Ensure the rest of the process info structure is initialized */
|
||||||
if (ORTE_SUCCESS != (ret = orte_proc_info())) {
|
if (ORTE_SUCCESS != (ret = orte_proc_info())) {
|
||||||
error = "orte_proc_info";
|
error = "orte_proc_info";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_proc_info");
|
||||||
|
|
||||||
/* we may have modified the local nodename according to
|
/* we may have modified the local nodename according to
|
||||||
* request to retain/strip the FQDN and prefix, so update
|
* request to retain/strip the FQDN and prefix, so update
|
||||||
* it here. The OPAL layer will strdup the hostname, so
|
* it here. The OPAL layer will strdup the hostname, so
|
||||||
@ -201,6 +216,7 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
if (ORTE_PROC_IS_DAEMON || ORTE_PROC_IS_HNP) {
|
if (ORTE_PROC_IS_DAEMON || ORTE_PROC_IS_HNP) {
|
||||||
/* let the pmix server register params */
|
/* let the pmix server register params */
|
||||||
pmix_server_register_params();
|
pmix_server_register_params();
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "pmix_server_register_params");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the SCHIZO framework as everyone needs it, and the
|
/* open the SCHIZO framework as everyone needs it, and the
|
||||||
@ -210,13 +226,20 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
error = "orte_schizo_base_open";
|
error = "orte_schizo_base_open";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "framework_open(schizo)");
|
||||||
|
|
||||||
if (ORTE_SUCCESS != (ret = orte_schizo_base_select())) {
|
if (ORTE_SUCCESS != (ret = orte_schizo_base_select())) {
|
||||||
error = "orte_schizo_base_select";
|
error = "orte_schizo_base_select";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_schizo_base_select");
|
||||||
|
|
||||||
/* if we are an app, let SCHIZO help us determine our environment */
|
/* if we are an app, let SCHIZO help us determine our environment */
|
||||||
if (ORTE_PROC_IS_APP) {
|
if (ORTE_PROC_IS_APP) {
|
||||||
(void)orte_schizo.check_launch_environment();
|
(void)orte_schizo.check_launch_environment();
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_schizo.check_launch_environment");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the ESS and select the correct module for this environment */
|
/* open the ESS and select the correct module for this environment */
|
||||||
@ -225,11 +248,16 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
error = "orte_ess_base_open";
|
error = "orte_ess_base_open";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "framework_open(ess)");
|
||||||
|
|
||||||
if (ORTE_SUCCESS != (ret = orte_ess_base_select())) {
|
if (ORTE_SUCCESS != (ret = orte_ess_base_select())) {
|
||||||
error = "orte_ess_base_select";
|
error = "orte_ess_base_select";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_ess_base_select");
|
||||||
|
|
||||||
if (!ORTE_PROC_IS_APP) {
|
if (!ORTE_PROC_IS_APP) {
|
||||||
/* ORTE tools "block" in their own loop over the event
|
/* ORTE tools "block" in their own loop over the event
|
||||||
* base, so no progress thread is required - apps will
|
* base, so no progress thread is required - apps will
|
||||||
@ -245,6 +273,8 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "orte_ess.init");
|
||||||
|
|
||||||
/* set the remaining opal_process_info fields. Note that
|
/* set the remaining opal_process_info fields. Note that
|
||||||
* the OPAL layer will have initialized these to NULL, and
|
* the OPAL layer will have initialized these to NULL, and
|
||||||
* anyone between us would not have strdup'd the string, so
|
* anyone between us would not have strdup'd the string, so
|
||||||
@ -255,10 +285,6 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
opal_process_info.my_local_rank = (int32_t)orte_process_info.my_local_rank;
|
opal_process_info.my_local_rank = (int32_t)orte_process_info.my_local_rank;
|
||||||
opal_process_info.cpuset = orte_process_info.cpuset;
|
opal_process_info.cpuset = orte_process_info.cpuset;
|
||||||
|
|
||||||
#if OPAL_ENABLE_TIMING
|
|
||||||
opal_timing_set_jobid(ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ORTE_PROC_IS_HNP || ORTE_PROC_IS_DAEMON) {
|
if (ORTE_PROC_IS_HNP || ORTE_PROC_IS_DAEMON) {
|
||||||
/* start listening - will be ignored if no listeners
|
/* start listening - will be ignored if no listeners
|
||||||
* were registered */
|
* were registered */
|
||||||
@ -269,6 +295,7 @@ int orte_init(int* pargc, char*** pargv, orte_proc_type_t flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPAL_TIMING_ENV_NEXT(tmng, "finalize");
|
||||||
/* All done */
|
/* All done */
|
||||||
return ORTE_SUCCESS;
|
return ORTE_SUCCESS;
|
||||||
|
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user