1
1

Cleanup timing macros for portability across compilers. Rename the --enable-timing configure option to be --enable-pmix-timing so it doesn't pickup external timing requests. Remove a stale function reference in PMIx so it can compile with timing enabled.

Signed-off-by: Ralph Castain <rhc@open-mpi.org>
Этот коммит содержится в:
Ralph Castain 2017-04-07 12:15:46 -07:00 коммит произвёл Boris Karasev
родитель 36a0e71f2d
Коммит 95ae0d1df3
8 изменённых файлов: 325 добавлений и 326 удалений

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

Просмотреть файл

@ -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,27 +13,27 @@ typedef struct {
char *prefix; char *prefix;
} ompi_timing_val_t; } ompi_timing_val_t;
typedef struct { typedef struct {
ompi_timing_val_t *val; ompi_timing_val_t *val;
int use; int use;
struct ompi_timing_list_t *next; struct ompi_timing_list_t *next;
} ompi_timing_list_t; } ompi_timing_list_t;
typedef struct ompi_timing_t { typedef struct ompi_timing_t {
double ts; double ts;
const char *prefix; const char *prefix;
int size; int size;
int cnt; int cnt;
int error; int error;
int enabled; int enabled;
opal_timing_ts_func_t get_ts; opal_timing_ts_func_t get_ts;
ompi_timing_list_t *timing; ompi_timing_list_t *timing;
ompi_timing_list_t *cur_timing; ompi_timing_list_t *cur_timing;
} ompi_timing_t; } ompi_timing_t;
#define OMPI_TIMING_INIT(_size) \ #define OMPI_TIMING_INIT(_size) \
ompi_timing_t OMPI_TIMING; \ ompi_timing_t OMPI_TIMING; \
OMPI_TIMING.prefix = __FUNCTION__; \ OMPI_TIMING.prefix = __func__; \
OMPI_TIMING.size = _size; \ OMPI_TIMING.size = _size; \
OMPI_TIMING.get_ts = opal_timing_ts_func(OPAL_TIMING_AUTOMATIC_TIMER); \ OMPI_TIMING.get_ts = opal_timing_ts_func(OPAL_TIMING_AUTOMATIC_TIMER); \
OMPI_TIMING.cnt = 0; \ OMPI_TIMING.cnt = 0; \
@ -55,156 +55,164 @@ typedef struct {
} \ } \
} }
#define OMPI_TIMING_ITEM_EXTEND ({ \ #define OMPI_TIMING_ITEM_EXTEND \
if (OMPI_TIMING.enabled) { \ do { \
OMPI_TIMING.cur_timing->next = (struct ompi_timing_list_t*)malloc(sizeof(ompi_timing_list_t)); \ if (OMPI_TIMING.enabled) { \
OMPI_TIMING.cur_timing = (ompi_timing_list_t*)OMPI_TIMING.cur_timing->next; \ OMPI_TIMING.cur_timing->next = (struct ompi_timing_list_t*)malloc(sizeof(ompi_timing_list_t)); \
memset(OMPI_TIMING.cur_timing, 0, sizeof(ompi_timing_list_t)); \ OMPI_TIMING.cur_timing = (ompi_timing_list_t*)OMPI_TIMING.cur_timing->next; \
OMPI_TIMING.cur_timing->val = malloc(sizeof(ompi_timing_val_t) * OMPI_TIMING.size); \ 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 ({ \ #define OMPI_TIMING_FINALIZE \
if (OMPI_TIMING.enabled) { \ do { \
ompi_timing_list_t *t = OMPI_TIMING.timing, *tmp; \ if (OMPI_TIMING.enabled) { \
while ( NULL != t) { \ ompi_timing_list_t *t = OMPI_TIMING.timing, *tmp; \
tmp = t; \ while ( NULL != t) { \
t = t->next; \ tmp = t; \
free(tmp->val); \ t = (ompi_timing_list_t*)t->next; \
free(tmp); \ free(tmp->val); \
} \ free(tmp); \
OMPI_TIMING.timing = NULL; \ } \
OMPI_TIMING.cur_timing = NULL; \ OMPI_TIMING.timing = NULL; \
OMPI_TIMING.cnt = 0; \ OMPI_TIMING.cur_timing = NULL; \
} \ OMPI_TIMING.cnt = 0; \
}) } \
} while(0)
#define OMPI_TIMING_NEXT(fmt, ...) ({ \ #define OMPI_TIMING_NEXT(...) \
if (!OMPI_TIMING.error && OMPI_TIMING.enabled) { \ do { \
char *f = strrchr(__FILE__, '/') + 1; \ if (!OMPI_TIMING.error && OMPI_TIMING.enabled) { \
int len = 0; \ char *f = strrchr(__FILE__, '/') + 1; \
if (OMPI_TIMING.cur_timing->use >= OMPI_TIMING.size){ \ int len = 0; \
OMPI_TIMING_ITEM_EXTEND; \ 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, fmt, ##__VA_ARGS__); \ len = snprintf(OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].desc, \
if (len >= OPAL_TIMING_STR_LEN) { \ OPAL_TIMING_STR_LEN, ##__VA_ARGS__); \
OMPI_TIMING.error = 1; \ if (len >= OPAL_TIMING_STR_LEN) { \
} \ OMPI_TIMING.error = 1; \
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].file = f; \ } \
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].prefix = __FUNCTION__; \ OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].file = strdup(f); \
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use++].ts = \ OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].prefix = strdup(__func__); \
OMPI_TIMING.get_ts() - OMPI_TIMING.ts; \ OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use++].ts = \
OMPI_TIMING.cnt++; \ OMPI_TIMING.get_ts() - OMPI_TIMING.ts; \
OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \ OMPI_TIMING.cnt++; \
} \ OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \
}) } \
} while(0)
#define OMPI_TIMING_APPEND(filename,func,desc,ts) { \ #define OMPI_TIMING_APPEND(filename,func,desc,ts) \
if (OMPI_TIMING.cur_timing->use >= OMPI_TIMING.size){ \ do { \
OMPI_TIMING_ITEM_EXTEND; \ 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); \ int len = snprintf(OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].desc, \
if (len >= OPAL_TIMING_STR_LEN) { \ OPAL_TIMING_STR_LEN, "%s", desc); \
OMPI_TIMING.error = 1; \ 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].prefix = func; \
OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use++].ts = \ OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use].file = filename; \
OMPI_TIMING.get_ts() - OMPI_TIMING.ts; \ OMPI_TIMING.cur_timing->val[OMPI_TIMING.cur_timing->use++].ts = \
OMPI_TIMING.cnt++; \ OMPI_TIMING.get_ts() - OMPI_TIMING.ts; \
OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \ OMPI_TIMING.cnt++; \
} OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \
} while(0)
#define OMPI_TIMING_IMPORT_OPAL_PREFIX(_prefix, func) { \ #define OMPI_TIMING_IMPORT_OPAL_PREFIX(_prefix, func) \
if (!OMPI_TIMING.error && OMPI_TIMING.enabled) { \ do { \
int cnt = OPAL_TIMING_ENV_CNT(func); \ if (!OMPI_TIMING.error && OMPI_TIMING.enabled) { \
int i; \ int cnt; \
OMPI_TIMING.error = OPAL_TIMING_ENV_ERROR_PREFIX(_prefix, func); \ int i; \
for(i = 0; i < cnt; i++){ \ double ts; \
char *desc, *filename; \ OPAL_TIMING_ENV_CNT(func, cnt); \
double ts = OPAL_TIMING_ENV_GETDESC_PREFIX(_prefix, &filename, func, i, &desc); \ OPAL_TIMING_ENV_ERROR_PREFIX(_prefix, func, OMPI_TIMING.error); \
OMPI_TIMING_APPEND(filename, func, desc, ts); \ 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) \ #define OMPI_TIMING_IMPORT_OPAL(func) \
OMPI_TIMING_IMPORT_OPAL_PREFIX("", func) OMPI_TIMING_IMPORT_OPAL_PREFIX("", func)
#define OMPI_TIMING_OUT ({ \ #define OMPI_TIMING_OUT \
if (OMPI_TIMING.enabled) { \ do { \
int i, size, rank; \ if (OMPI_TIMING.enabled) { \
MPI_Comm_size(MPI_COMM_WORLD, &size); \ int i, size, rank; \
MPI_Comm_rank(MPI_COMM_WORLD, &rank); \ MPI_Comm_size(MPI_COMM_WORLD, &size); \
int error = 0; \ 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); \ MPI_Reduce(&OMPI_TIMING.error, &error, 1, \
\ MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); \
if (error) { \ \
if (0 == rank) { \ if (error) { \
printf("==OMPI_TIMING== error: something went wrong, timings doesn't work\n"); \ 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); \ else { \
double *min = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \ double *avg = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \
double *max = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \ double *min = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \
char **desc = (char**)malloc(sizeof(char*) * OMPI_TIMING.cnt); \ double *max = (double*)malloc(sizeof(double) * OMPI_TIMING.cnt); \
char **prefix = (char**)malloc(sizeof(char*) * OMPI_TIMING.cnt); \ char **desc = (char**)malloc(sizeof(char*) * OMPI_TIMING.cnt); \
char **file = (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(); \ if( OMPI_TIMING.cnt > 0 ) { \
ompi_timing_list_t *timing = OMPI_TIMING.timing; \ OMPI_TIMING.ts = OMPI_TIMING.get_ts(); \
i = 0; \ ompi_timing_list_t *timing = OMPI_TIMING.timing; \
do { \ i = 0; \
int use; \ do { \
for (use = 0; use < timing->use; use++) { \ int use; \
MPI_Reduce(&timing->val[use].ts, avg + i, 1, \ for (use = 0; use < timing->use; use++) { \
MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); \ MPI_Reduce(&timing->val[use].ts, avg + i, 1, \
MPI_Reduce(&timing->val[use].ts, min + i, 1, \ MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); \
MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD); \ MPI_Reduce(&timing->val[use].ts, min + i, 1, \
MPI_Reduce(&timing->val[use].ts, max + i, 1, \ MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD); \
MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); \ MPI_Reduce(&timing->val[use].ts, max + i, 1, \
desc[i] = timing->val[use].desc; \ MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); \
prefix[i] = timing->val[use].prefix; \ desc[i] = timing->val[use].desc; \
file[i] = timing->val[use].file; \ prefix[i] = timing->val[use].prefix; \
i++; \ file[i] = timing->val[use].file; \
} \ i++; \
timing = (ompi_timing_list_t*)timing->next; \ } \
} while (timing != NULL); \ timing = (ompi_timing_list_t*)timing->next; \
\ } while (timing != NULL); \
if( 0 == rank ){ \ \
if (OMPI_TIMING.timing->next) { \ if( 0 == rank ){ \
printf("==OMPI_TIMING== warning: added the extra timings allocation that might misrepresent the results.\n" \ if (OMPI_TIMING.timing->next) { \
"==OMPI_TIMING== Increase the inited size of timings to avoid extra allocation during runtime.\n"); \ 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); \ printf("------------------ %s ------------------\n", \
for(i=0; i< OMPI_TIMING.cnt; i++){ \ OMPI_TIMING.prefix); \
avg[i] /= size; \ for(i=0; i< OMPI_TIMING.cnt; i++){ \
printf("[%s:%s:%s]: %lf / %lf / %lf\n", \ avg[i] /= size; \
file[i], prefix[i], desc[i], avg[i], min[i], max[i]); \ 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); \ printf("[%s:overhead]: %lf \n", OMPI_TIMING.prefix, \
} \ OMPI_TIMING.get_ts() - OMPI_TIMING.ts); \
} \ } \
free(avg); \ } \
free(min); \ free(avg); \
free(max); \ free(min); \
free(desc); \ free(max); \
free(prefix); \ free(desc); \
free(file); \ free(prefix); \
} \ free(file); \
} \ } \
}) } \
} while(0)
#else #else
#define OMPI_TIMING_INIT(size) #define OMPI_TIMING_INIT(size)

Просмотреть файл

@ -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.",

Просмотреть файл

@ -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
@ -39,47 +39,46 @@ typedef struct {
opal_timing_ts_func_t opal_timing_ts_func(opal_timer_type_t type); opal_timing_ts_func_t opal_timing_ts_func(opal_timer_type_t type);
#define OPAL_TIMING_ENV_START_TYPE(func, type, prefix) ({ \ #define OPAL_TIMING_ENV_START_TYPE(func, _nm, type, prefix) \
opal_timing_env_t h; \ do { \
char *ptr = NULL; \ char *ptr = NULL; \
char *_prefix = prefix; \ char *_prefix = prefix; \
int n; \ int n; \
if( NULL == prefix ){ \ if( NULL == prefix ){ \
_prefix = ""; \ _prefix = ""; \
} \ } \
h.error = 0; \ (_nm)->error = 0; \
n = snprintf(h.id, OPAL_TIMING_STR_LEN, "%s%s", _prefix, func); \ n = snprintf((_nm)->id, OPAL_TIMING_STR_LEN, "%s%s", _prefix, func); \
if( n > OPAL_TIMING_STR_LEN ){ \ if( n > OPAL_TIMING_STR_LEN ){ \
h.error = 1; \ (_nm)->error = 1; \
} \ } \
n = sprintf(h.cntr_env,"OMPI_TIMING_%s%s_CNT", prefix, h.id); \ n = sprintf((_nm)->cntr_env,"OMPI_TIMING_%s%s_CNT", prefix, (_nm)->id); \
if( n > OPAL_TIMING_STR_LEN ){ \ if( n > OPAL_TIMING_STR_LEN ){ \
h.error = 1; \ (_nm)->error = 1; \
} \ } \
ptr = getenv(h.id); \ ptr = getenv((_nm)->id); \
if( NULL == ptr || strcmp(ptr, "1")){ \ if( NULL == ptr || strcmp(ptr, "1")){ \
h.enabled = 0; \ (_nm)->enabled = 0; \
} \ } \
h.get_ts = opal_timing_ts_func(type); \ (_nm)->get_ts = opal_timing_ts_func(type); \
ptr = getenv("OPAL_TIMING_ENABLE"); \ ptr = getenv("OPAL_TIMING_ENABLE"); \
if (NULL != ptr) { \ if (NULL != ptr) { \
h.enabled = atoi(ptr); \ (_nm)->enabled = atoi(ptr); \
} \ } \
h.cntr = 0; \ (_nm)->cntr = 0; \
ptr = getenv(h.id); \ ptr = getenv((_nm)->id); \
if( NULL != ptr ){ \ if( NULL != ptr ){ \
h.cntr = atoi(ptr); \ (_nm)->cntr = atoi(ptr); \
} \ } \
h.ts = h.get_ts(); \ (_nm)->ts = (_nm)->get_ts(); \
if ( 0 != h.error ){ \ if ( 0 != (_nm)->error ){ \
h.enabled = 0; \ (_nm)->enabled = 0; \
} \ } \
h; \ } while(0)
})
#define OPAL_TIMING_ENV_INIT(name) \ #define OPAL_TIMING_ENV_INIT(name) \
opal_timing_env_t name ## _val, *name = &(name ## _val); \ opal_timing_env_t name ## _val, *name = &(name ## _val); \
*name = OPAL_TIMING_ENV_START_TYPE(__FUNCTION__, OPAL_TIMING_AUTOMATIC_TIMER, ""); OPAL_TIMING_ENV_START_TYPE(__func__, name, OPAL_TIMING_AUTOMATIC_TIMER, "");
/* We use function names for identification /* We use function names for identification
* however this might be a problem for the private * however this might be a problem for the private
@ -88,111 +87,114 @@ opal_timing_ts_func_t opal_timing_ts_func(opal_timer_type_t type);
* Use prefix to do a finer-grained identification if needed * Use prefix to do a finer-grained identification if needed
*/ */
#define OPAL_TIMING_ENV_INIT_PREFIX(prefix, name) \ #define OPAL_TIMING_ENV_INIT_PREFIX(prefix, name) \
opal_timing_env_t name ## _val, *name = &(name ## _val); \ do { \
*name = OPAL_TIMING_ENV_START_TYPE(__FUNCTION__, OPAL_TIMING_AUTOMATIC_TIMER, prefix); 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, fmt, ...) ({ \ #define OPAL_TIMING_ENV_NEXT(h, ...) \
int n; \ do { \
char buf1[OPAL_TIMING_STR_LEN], buf2[OPAL_TIMING_STR_LEN]; \ int n; \
double time; \ char buf1[OPAL_TIMING_STR_LEN], buf2[OPAL_TIMING_STR_LEN]; \
char *filename; \ double time; \
if( h->enabled ){ \ char *filename; \
/* enabled codepath */ \ if( h->enabled ){ \
time = h->get_ts() - h->ts; \ /* enabled codepath */ \
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_DESC_%d", h->id, h->cntr); \ time = h->get_ts() - h->ts; \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_DESC_%d", h->id, h->cntr); \
h->error = 1; \ if ( n > OPAL_TIMING_STR_LEN ){ \
} \ h->error = 1; \
n = snprintf(buf2, OPAL_TIMING_STR_LEN, fmt, ## __VA_ARGS__ ); \ } \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf2, OPAL_TIMING_STR_LEN, __VA_ARGS__ ); \
h->error = 1; \ 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); \ setenv(buf1, buf2, 1); \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_VAL_%d", h->id, h->cntr); \
h->error = 1; \ if ( n > OPAL_TIMING_STR_LEN ){ \
} \ h->error = 1; \
n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%lf", time); \ } \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%lf", time); \
h->error = 1; \ if ( n > OPAL_TIMING_STR_LEN ){ \
} \ h->error = 1; \
setenv(buf1, buf2, 1); \ } \
filename = strrchr(__FILE__, '/') + 1; \ setenv(buf1, buf2, 1); \
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_FILE_%d", h->id, h->cntr); \ filename = strrchr(__FILE__, '/') + 1; \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_FILE_%d", h->id, h->cntr); \
h->error = 1; \ if ( n > OPAL_TIMING_STR_LEN ){ \
} \ h->error = 1; \
n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%s", filename); \ } \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%s", filename); \
h->error = 1; \ if ( n > OPAL_TIMING_STR_LEN ){ \
} \ h->error = 1; \
setenv(buf1, buf2, 1); \ } \
h->cntr++; \ setenv(buf1, buf2, 1); \
sprintf(buf1, "%d", h->cntr); \ h->cntr++; \
setenv(h->cntr_env, buf1, 1); \ sprintf(buf1, "%d", h->cntr); \
/* We don't include env operations into the consideration. setenv(h->cntr_env, buf1, 1); \
* Hopefully this will help to make measurements more accurate. /* We don't include env operations into the consideration.
*/ \ * Hopefully this will help to make measurements more accurate.
h->ts = h->get_ts(); \ */ \
} \ h->ts = h->get_ts(); \
if (h->error) { \ } \
n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_ERROR", h->id);\ if (h->error) { \
if ( n > OPAL_TIMING_STR_LEN ){ \ n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_ERROR", h->id);\
h->error = 1; \ 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 ){ \ n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%d", h->error); \
h->error = 1; \ if ( n > OPAL_TIMING_STR_LEN ){ \
} \ h->error = 1; \
setenv(buf1, buf2, 1); \ } \
} \ setenv(buf1, buf2, 1); \
}) } \
} while(0)
/* This function supposed to be called from the code that will /* This function supposed to be called from the code that will
* do the postprocessing, i.e. OMPI timing portion that will * do the postprocessing, i.e. OMPI timing portion that will
* do the reduction of accumulated values * do the reduction of accumulated values
*/ */
#define OPAL_TIMING_ENV_CNT_PREFIX(prefix, func) ({ \ #define OPAL_TIMING_ENV_CNT_PREFIX(prefix, func, _cnt) \
char ename[OPAL_TIMING_STR_LEN]; \ do { \
int cnt = 0; \ char ename[OPAL_TIMING_STR_LEN]; \
char *ptr = NULL; \ char *ptr = NULL; \
int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_CNT", prefix, func); \ int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_CNT", prefix, func); \
if ( n <= OPAL_TIMING_STR_LEN ){ \ (_cnt) = 0; \
ptr = getenv(ename); \ if ( n <= OPAL_TIMING_STR_LEN ){ \
if( NULL != ptr ){ cnt = atoi(ptr); }; \ ptr = getenv(ename); \
} \ if( NULL != ptr ){ (_cnt) = atoi(ptr); }; \
cnt; \ } \
}) } while(0)
#define OPAL_TIMING_ENV_ERROR_PREFIX(prefix, func) ({ \ #define OPAL_TIMING_ENV_ERROR_PREFIX(prefix, func, _err) \
char ename[OPAL_TIMING_STR_LEN]; \ do { \
int error = 0; \ char ename[OPAL_TIMING_STR_LEN]; \
char *ptr = NULL; \ (_err) = 0; \
int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_ERROR", prefix, func); \ char *ptr = NULL; \
if ( n <= OPAL_TIMING_STR_LEN ){ \ int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_ERROR", prefix, func); \
ptr = getenv(ename); \ if ( n <= OPAL_TIMING_STR_LEN ){ \
if( NULL != ptr ){ error = atoi(ptr); }; \ ptr = getenv(ename); \
} \ if( NULL != ptr ){ (_err) = atoi(ptr); }; \
error; \ } \
}) } while(0)
#define OPAL_TIMING_ENV_CNT(func) \ #define OPAL_TIMING_ENV_CNT(func, _cnt) \
OPAL_TIMING_ENV_CNT_PREFIX("", func) OPAL_TIMING_ENV_CNT_PREFIX("", func, _cnt)
#define OPAL_TIMING_ENV_GETDESC_PREFIX(prefix, filename, func, i, desc) ({ \ #define OPAL_TIMING_ENV_GETDESC_PREFIX(prefix, filename, func, i, desc, _t) \
char vname[OPAL_TIMING_STR_LEN]; \ do { \
double ts = 0.0; \ char vname[OPAL_TIMING_STR_LEN]; \
sprintf(vname, "OMPI_TIMING_%s%s_FILE_%d", prefix, func, i); \ (_t) = 0.0; \
*filename = getenv(vname); \ sprintf(vname, "OMPI_TIMING_%s%s_FILE_%d", prefix, func, i); \
sprintf(vname, "OMPI_TIMING_%s%s_DESC_%d", prefix, func, i); \ *filename = getenv(vname); \
*desc = getenv(vname); \ sprintf(vname, "OMPI_TIMING_%s%s_DESC_%d", prefix, func, i); \
sprintf(vname, "OMPI_TIMING_%s%s_VAL_%d", prefix, func, i); \ *desc = getenv(vname); \
char *ptr = getenv(vname); \ sprintf(vname, "OMPI_TIMING_%s%s_VAL_%d", prefix, func, i); \
if ( NULL != ptr ) { \ char *ptr = getenv(vname); \
sscanf(ptr,"%lf", &ts); \ if ( NULL != ptr ) { \
} \ sscanf(ptr,"%lf", &(_t)); \
ts; \ } \
}) } while(0)
#define OPAL_TIMING_ENV_GETDESC(file, func, index, desc) \ #define OPAL_TIMING_ENV_GETDESC(file, func, index, desc) \
OPAL_TIMING_ENV_GETDESC_PREFIX("", file, func, index, desc) OPAL_TIMING_ENV_GETDESC_PREFIX("", file, func, index, desc)

Просмотреть файл

@ -343,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) {
@ -431,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",
@ -503,13 +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
/* 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 */