Skip to content

Instantly share code, notes, and snippets.

@bosilca
Created July 31, 2020 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bosilca/f3bd08167acfb76f0a7d558b17ed8931 to your computer and use it in GitHub Desktop.
Save bosilca/f3bd08167acfb76f0a7d558b17ed8931 to your computer and use it in GitHub Desktop.
A quick benchmark to evaluate the cost of converting a MPI collective communication name into the collective identifier. The benchmark does not check the cost for a particular permutation of the collectives, as they all have the same chance to be in the configuration file I look at the cost to search for all of them once.
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
extern int mca_coll_base_name_to_colltype(const char* name);
typedef enum COLLTYPE {
ALLGATHER = 0, /* 0 */
ALLGATHERV, /* 1 */
ALLREDUCE, /* 2 */
ALLTOALL, /* 3 */
ALLTOALLV, /* 4 */
ALLTOALLW, /* 5 */
BARRIER, /* 6 */
BCAST, /* 7 */
EXSCAN, /* 8 */
GATHER, /* 9 */
GATHERV, /* 10 */
REDUCE, /* 11 */
REDUCESCATTER, /* 12 */
REDUCESCATTERBLOCK, /* 13 */
SCAN, /* 14 */
SCATTER, /* 15 */
SCATTERV, /* 16 */
NEIGHBOR_ALLGATHER, /* 17 */
NEIGHBOR_ALLGATHERV, /* 18 */
NEIGHBOR_ALLTOALL, /* 19 */
NEIGHBOR_ALLTOALLV, /* 20 */
NEIGHBOR_ALLTOALLW, /* 21 */
COLLCOUNT /* 22 end counter keep it as last element */
} COLLTYPE_T;
static const char* colltype_translation_table[] = {
[ALLGATHER] = "allgather",
[ALLGATHERV] = "allgatherv",
[ALLREDUCE] = "allreduce",
[ALLTOALL] = "alltoall",
[ALLTOALLV] = "alltoallv",
[ALLTOALLW] = "alltoallw",
[BARRIER] = "barrier",
[BCAST] = "bcast",
[EXSCAN] = "exscan",
[GATHER] = "gather",
[GATHERV] = "gatherv",
[REDUCE] = "reduce",
[REDUCESCATTER] = "reduce_scatter",
[REDUCESCATTERBLOCK] = "reduce_scatter_block",
[SCAN] = "scan",
[SCATTER] = "scatter",
[SCATTERV] = "scatterv",
[NEIGHBOR_ALLGATHER] = "neighbor_allgather",
[NEIGHBOR_ALLGATHERV] = "neighbor_allgatherv",
[NEIGHBOR_ALLTOALL] = "neighbor_alltoall",
[NEIGHBOR_ALLTOALLV] = "neighbor_alltoallv",
[NEIGHBOR_ALLTOALLW] = "neighbor_alltoallw",
[COLLCOUNT] = NULL
};
int mca_coll_base_name_to_colltype_gb(const char* name)
{
if( 'n' == name[0] ) {
if( 0 == strncmp(name, "neighbor_all", 12) ) {
if( 't' != name[12] ) {
if( 0 == strncmp(name+12, "gather", 6) ) {
if('\0' == name[18]) return NEIGHBOR_ALLGATHER;
if( 'v' == name[18]) return NEIGHBOR_ALLGATHERV;
}
} else {
if( 0 == strncmp(name+12, "toall", 5) ) {
if( '\0' == name[17] ) return NEIGHBOR_ALLTOALL;
if( 'v' == name[17] ) return NEIGHBOR_ALLTOALLV;
if( 'w' == name[17] ) return NEIGHBOR_ALLTOALLW;
}
}
}
return -1;
}
if( 'a' == name[0] ) {
if( 0 != strncmp(name, "all", 3) ) {
return -1;
}
if( 't' != name[3] ) {
if( 'r' == name[3] ) {
if( 0 == strcmp(name+3, "reduce") )
return ALLREDUCE;
} else {
if( 0 == strncmp(name+3, "gather", 6) ) {
if( '\0' == name[9] ) return ALLGATHER;
if( 'v' == name[9] ) return ALLGATHERV;
}
}
} else {
if( 0 == strncmp(name+3, "toall", 5) ) {
if( '\0' == name[8] ) return ALLTOALL;
if( 'v' == name[8] ) return ALLTOALLV;
if( 'w' == name[8] ) return ALLTOALLW;
}
}
return -1;
}
if( 'r' > name[0] ) {
if( 'b' == name[0] ) {
if( 0 == strcmp(name, "barrier") )
return BARRIER;
if( 0 == strcmp(name, "bcast") )
return BCAST;
} else if( 'g'== name[0] ) {
if( 0 == strncmp(name, "gather", 6) ) {
if( '\0' == name[6] ) return GATHER;
if( 'v' == name[6] ) return GATHERV;
}
}
if( 0 == strcmp(name, "exscan") )
return EXSCAN;
return -1;
}
if( 's' > name[0] ) {
if( 0 == strncmp(name, "reduce", 6) ) {
if( '\0' == name[6] ) return REDUCE;
if( '_' == name[6] ) {
if( 0 == strncmp(name+7, "scatter", 7) ) {
if( '\0' == name[14] ) return REDUCESCATTER;
if( 0 == strcmp(name+14, "_block") ) return REDUCESCATTERBLOCK;
}
}
}
return -1;
}
if( 0 == strcmp(name, "scan") )
return SCAN;
if( 0 == strcmp(name, "scatterv") )
return SCATTERV;
if( 0 == strcmp(name, "scatter") )
return SCATTER;
return -1;
}
int mca_coll_base_name_to_colltype_ch(const char* name)
{
int i;
for (i = 0; i < COLLCOUNT; i++) {
if (0 == strcmp(name, colltype_translation_table[i])) {
return i;}
}
return -1;
}
uint64_t diff(struct timespec* start, struct timespec* end)
{
uint64_t temp = (end->tv_sec - start->tv_sec) * 1000000000;
temp += end->tv_nsec - start->tv_nsec;
return temp;
}
#define MAX_REPEAT 1000
int main(int argc, char* argv[])
{
int rc, i;
struct timespec start, end;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
for(int repeat = 0; repeat < 1000; repeat++ ) {
for( i = 0; NULL != colltype_translation_table[i]; i++ ) {
rc = mca_coll_base_name_to_colltype_gb(colltype_translation_table[i]);
if( rc != i ) {
printf("This is bad for index %d collective %s\n", i, colltype_translation_table[i]);
}
}
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
printf("gb: search all collectives for %ld secs\n", diff(&start, &end)/MAX_REPEAT);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
for(int repeat = 0; repeat < 1000; repeat++ ) {
for( i = 0; NULL != colltype_translation_table[i]; i++ ) {
rc = mca_coll_base_name_to_colltype_ch(colltype_translation_table[i]);
if( rc != i ) {
printf("This is bad for index %d collective %s\n", i, colltype_translation_table[i]);
}
}
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
printf("ch: search all collectives for %ld secs\n", diff(&start, &end)/MAX_REPEAT);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment