/*****************************************************************************/ /* */ /* Copyright (c) 2008, 2009, 2010 */ /* Computer Architecture Group (CAG) */ /* University of A Coruña, Spain */ /* (http://gac.des.udc.es) */ /* Galicia Supercomputing Center (CESGA) */ /* (http://www.cesga.es) */ /* Hewlett-Packard Spain (HP) */ /* (http://www.hp.es) */ /* */ /* This file is part of UPC Operations Microbenchmarking Suite (UOMS). */ /* */ /* UOMS is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU Lesser General Public License as published */ /* by the Free Software Foundation, either version 3 of the License, or */ /* (at your option) any later version. */ /* */ /* UOMS is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with UOMS. If not, see . */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* FUNDING: This development has been funded by Hewlett-Packard Spain */ /* */ /* Project Name: */ /* UPCHACO (2008-2011) */ /* Subproject: */ /* Improving UPC Usability and Performance in Constellation Systems: */ /* Implementation/Extensions of UPC Libraries. */ /* (UPCPU­Project -> UPC Performance and Usability Project) */ /* */ /*****************************************************************************/ /***************************************************************************** For further documentation, see [1] Files under doc/ ******************************************************************************/ #include #include #include #include #include #include #include "defines.h" #include "headers.h" #define roundtoint(x) ((x)>=0?(int)((x)+0.5):(int)((x)-0.5)) extern char * valid_bms[NUM_BMS]; extern upc_op_t reduce_op; long maxsize, minsize; /* Set benchmarks names */ void set_bms_names(){ valid_bms[BARRIER] = "upc_barrier"; valid_bms[BROADCAST] = "upc_all_broadcast"; valid_bms[SCATTER] = "upc_all_scatter"; valid_bms[GATHER] = "upc_all_gather"; valid_bms[GATHERALL] = "upc_all_gather_all"; valid_bms[EXCHANGE] = "upc_all_exchange"; valid_bms[PERMUTE] = "upc_all_permute"; valid_bms[MEMGET] = "upc_memget"; valid_bms[MEMPUT] = "upc_memput"; valid_bms[MEMCPY] = "upc_memcpy"; valid_bms[LMEMGET] = "local_upc_memget"; valid_bms[LMEMPUT] = "local_upc_memput"; valid_bms[LMEMCPY] = "local_upc_memcpy"; valid_bms[SMEMCPY] = "memcpy"; valid_bms[MEMMOVE] = "memmove"; valid_bms[ALLALLOC] = "upc_all_alloc"; valid_bms[FREE] = "upc_free"; valid_bms[REDUCE_C] = "upc_all_reduceC"; valid_bms[PREFIX_REDUCE_C] = "upc_all_prefix_reduceC"; valid_bms[REDUCE_UC] = "upc_all_reduceUC"; valid_bms[PREFIX_REDUCE_UC] = "upc_all_prefix_reduceUC"; valid_bms[REDUCE_S] = "upc_all_reduceS"; valid_bms[PREFIX_REDUCE_S] = "upc_all_prefix_reduceS"; valid_bms[REDUCE_US] = "upc_all_reduceUS"; valid_bms[PREFIX_REDUCE_US] = "upc_all_prefix_reduceUS"; valid_bms[REDUCE_I] = "upc_all_reduceI"; valid_bms[PREFIX_REDUCE_I] = "upc_all_prefix_reduceI"; valid_bms[REDUCE_UI] = "upc_all_reduceUI"; valid_bms[PREFIX_REDUCE_UI] = "upc_all_prefix_reduceUI"; valid_bms[REDUCE_L] = "upc_all_reduceL"; valid_bms[PREFIX_REDUCE_L] = "upc_all_prefix_reduceL"; valid_bms[REDUCE_UL] = "upc_all_reduceUL"; valid_bms[PREFIX_REDUCE_UL] = "upc_all_prefix_reduceUL"; valid_bms[REDUCE_F] = "upc_all_reduceF"; valid_bms[PREFIX_REDUCE_F] = "upc_all_prefix_reduceF"; valid_bms[REDUCE_D] = "upc_all_reduceD"; valid_bms[PREFIX_REDUCE_D] = "upc_all_prefix_reduceD"; valid_bms[REDUCE_LD] = "upc_all_reduceLD"; valid_bms[PREFIX_REDUCE_LD] = "upc_all_prefix_reduceLD"; #ifdef ASYNC_MEM_TEST valid_bms[AMEMGET] = "upc_memget_async"; valid_bms[AMEMPUT] = "upc_memput_async"; valid_bms[AMEMCPY] = "upc_memcpy_async"; valid_bms[ALMEMGET] = "local_upc_memget_async"; valid_bms[ALMEMPUT] = "local_upc_memput_async"; valid_bms[ALMEMCPY] = "local_upc_memcpy_async"; #endif #ifdef ASYNCI_MEM_TEST valid_bms[AIMEMGET] = "upc_memget_asynci"; valid_bms[AIMEMPUT] = "upc_memput_asynci"; valid_bms[AIMEMCPY] = "upc_memcpy_asynci"; valid_bms[AILMEMGET] = "local_upc_memget_asynci"; valid_bms[AILMEMPUT] = "local_upc_memput_asynci"; valid_bms[AILMEMCPY] = "local_upc_memcpy_asynci"; #endif } /* Set min size */ int set_min_size(char *size){ if(size[0] >= '0' && size[0] <= '9'){ errno = 0; minsize = strtol(size,NULL,10); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** minsize (%s) not valid: ",size); perror(NULL); } return -1; } } else{ if(MYTHREAD == 0){ fprintf(stderr,"*** minsize (%s) not valid",size); } return -1; } return 0; } /* Set max size */ int set_max_size(char *size){ if(size[0] >= '0' && size[0] <= '9'){ errno = 0; maxsize = strtol(size,NULL,10); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** maxsize (%s) not valid: ",size); perror(NULL); } return -1; } } else{ if(MYTHREAD == 0){ fprintf(stderr,"*** maxsize (%s) not valid",size); } return -1; } return 0; } /* Set reduce operation */ int set_reduce_op(char *operation){ extern char *char_reduce_op; if(strcmp(operation,"UPC_ADD") == 0){ reduce_op = UPC_ADD; char_reduce_op = operation; } else if(strcmp(operation,"UPC_MULT") == 0){ reduce_op = UPC_MULT; char_reduce_op = operation; } else if(strcmp(operation,"UPC_AND") == 0){ reduce_op = UPC_AND; char_reduce_op = operation; } else if(strcmp(operation,"UPC_OR") == 0){ reduce_op = UPC_OR; char_reduce_op = operation; } else if(strcmp(operation,"UPC_XOR") == 0){ reduce_op = UPC_XOR; char_reduce_op = operation; } else if(strcmp(operation,"UPC_LOGAND") == 0){ reduce_op = UPC_LOGAND; char_reduce_op = operation; } else if(strcmp(operation,"UPC_LOGOR") == 0){ reduce_op = UPC_LOGOR; char_reduce_op = operation; } else if(strcmp(operation,"UPC_MIN") == 0){ reduce_op = UPC_MIN; char_reduce_op = operation; } else if(strcmp(operation,"UPC_MAX") == 0){ reduce_op = UPC_MAX; char_reduce_op = operation; } else{ return -1; } return 0; } /* Set synchronization mode */ int set_sync_mode(char *mode){ extern upc_flag_t sync_mode; extern char * char_sync_mode; if(strcmp(mode,"UPC_IN_ALLSYNC|UPC_OUT_ALLSYNC") == 0){ sync_mode = UPC_IN_ALLSYNC|UPC_OUT_ALLSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_ALLSYNC|UPC_OUT_MYSYNC") == 0){ sync_mode = UPC_IN_ALLSYNC|UPC_OUT_MYSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_ALLSYNC|UPC_OUT_NOSYNC") == 0){ sync_mode = UPC_IN_ALLSYNC|UPC_OUT_NOSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_MYSYNC|UPC_OUT_ALLSYNC") == 0){ sync_mode = UPC_IN_MYSYNC|UPC_OUT_ALLSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_MYSYNC|UPC_OUT_MYSYNC") == 0){ sync_mode = UPC_IN_MYSYNC|UPC_OUT_MYSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_MYSYNC|UPC_OUT_NOSYNC") == 0){ sync_mode = UPC_IN_MYSYNC|UPC_OUT_NOSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_NOSYNC|UPC_OUT_ALLSYNC") == 0){ sync_mode = UPC_IN_NOSYNC|UPC_OUT_ALLSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_NOSYNC|UPC_OUT_MYSYNC") == 0){ sync_mode = UPC_IN_NOSYNC|UPC_OUT_MYSYNC; char_sync_mode = mode; } else if(strcmp(mode,"UPC_IN_NOSYNC|UPC_OUT_NOSYNC") == 0){ sync_mode = UPC_IN_NOSYNC|UPC_OUT_NOSYNC; char_sync_mode = mode; } else{ return -1; } return 0; } /* Set benchmark list */ void set_bms(int alternative_bm_list, char *bm_file){ extern int *bm_list; extern int num_bms; FILE *fd; /* Default procedure */ if(alternative_bm_list == 0){ num_bms = NUM_BMS; errno = 0; bm_list = malloc(num_bms*sizeof(int)); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Unable to allocate %ld bytes for benchmark list storing: ",num_bms*sizeof(int)); perror(NULL); } upc_barrier; exit(-1); } int j = 0; for(int i = 0; i < num_bms; i++){ if(reduce_op == UPC_AND || reduce_op == UPC_OR || reduce_op == UPC_XOR){ if(i == REDUCE_F || i == PREFIX_REDUCE_F || i == REDUCE_D || i == PREFIX_REDUCE_D || i == REDUCE_LD || i == PREFIX_REDUCE_LD){ continue; } } bm_list[j] = i; j++; } } /* User defined */ else{ if(bm_file == NULL){ if(MYTHREAD == 0){ fprintf(stderr,"Unexpected error when parsing the benchmarks list file\n"); } upc_barrier; exit(-1); } errno = 0; fd = fopen(bm_file,"r"); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error opening file %s: ",bm_file); perror(NULL); } upc_barrier; exit(-1); } char curbm[30]; /* Two phases: one for get the number of benchmarks and the other to actually store them */ while (!feof(fd) && fgets(curbm, 30, fd)) { for(int i = 0; i < 30; i++){ if(curbm[i] == '\n' || curbm[i] == ' '){ curbm[i] = '\0'; } } for(int i = 0; i < NUM_BMS; i++){ if(strcmp(curbm,valid_bms[i]) == 0){ num_bms++; } } } errno = 0; rewind(fd); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error reading file %s: ",bm_file); perror(NULL); } upc_barrier; exit(-1); } errno = 0; bm_list = malloc(num_bms*sizeof(int)); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Unable to allocate %ld bytes for benchmark list storing: ",num_bms*sizeof(int)); perror(NULL); } upc_barrier; exit(-1); } int i = 0; while (!feof(fd) && fgets(curbm, 30, fd)) { for(int j = 0; j < 30; j++){ if(curbm[j] == '\n' || curbm[j] == ' '){ curbm[j] = '\0'; } } for(int j = 0; j < NUM_BMS; j++){ errno = 0; if(strcmp(curbm,valid_bms[j]) == 0){ if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error parsing %s in file %s: ",curbm,bm_file); perror(NULL); } upc_barrier; exit(-1); } bm_list[i] = j; i++; } } } fclose(fd); } if(num_bms < 1){ if(MYTHREAD == 0) fprintf(stderr,"*** No valid benchmarks specified\n"); exit(-1); } } /* Set problem sizes */ void set_sizes(int alternative_sizes, char *sizes_file){ extern long *sizes; extern int num_sizes; FILE *fd; /* Default procedure */ if(alternative_sizes == 0){ num_sizes = roundtoint(log2((double)maxsize)) - roundtoint(log2((double)minsize)) + 1; errno = 0; sizes = malloc(num_sizes*sizeof(long)); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Unable to allocate %ld bytes for message sizes storing: ",num_sizes*sizeof(int)); perror(NULL); } upc_barrier; exit(-1); } sizes[0] = minsize; for(int i = 1; i < num_sizes; i++){ sizes[i] = sizes[i-1]*2; } if(sizes[num_sizes-1] > maxsize){ num_sizes--; //We waste sizeof(long) bytes, but probably we can afford it } } /* User defined */ else{ if(sizes_file == NULL){ if(MYTHREAD == 0){ fprintf(stderr,"Unexpected error when parsing the problem sizes file\n"); } upc_barrier; exit(-1); } errno = 0; fd = fopen(sizes_file,"r"); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error opening file %s: ",sizes_file); perror(NULL); } upc_barrier; exit(-1); } char cursize[20]; /* Two phases: one for get the number of sizes and the other to actually store them */ while (!feof(fd) && fgets(cursize, 20, fd)) { if(cursize[0] >= '0' && cursize[0] <= '9'){ errno = 0; strtol(cursize,NULL,10); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error parsing %s in file %s: ",cursize,sizes_file); perror(NULL); } upc_barrier; exit(-1); } num_sizes++; } else{ /* Silently ignores other lines */ continue; } } errno = 0; rewind(fd); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error reading file %s: ",sizes_file); perror(NULL); } upc_barrier; exit(-1); } errno = 0; sizes = malloc(num_sizes*sizeof(long)); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Unable to allocate %ld bytes for message sizes storing: ",num_sizes*sizeof(int)); perror(NULL); } upc_barrier; exit(-1); } int i = 0; while (!feof(fd) && fgets(cursize, 20, fd)) { if(cursize[0] >= '0' && cursize[0] <= '9'){ errno = 0; sizes[i] = strtol(cursize,NULL,10); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error parsing %s in file %s: ",cursize,sizes_file); perror(NULL); } upc_barrier; exit(-1); } i++; } else{ /* Silently ignores other lines */ continue; } } fclose(fd); } if(num_sizes < 1){ if(MYTHREAD == 0) fprintf(stderr,"*** No block sizes specified\n"); exit(-1); } } // Init functions. E.g., initialize permutation array void UOMS_init(){ int i; extern shared int perm[THREADS]; //for permutation //set the permutation array if ( MYTHREAD == 0 ) { for (i=0; i0; --i) { int j = ((int)rand() >> 3) % i; int tmp = perm[i]; perm[i] = perm[j]; perm[j] = tmp; } } } void init(int argc, char **argv){ extern FILE *unit; extern int cache_invalidation; extern int warmup; char *sizes_file = NULL; char *output_file = NULL; char *bm_file = NULL; int alternative_output_file = 0; int alternative_sizes = 0; int alternative_bm_list = 0; minsize = MINSIZE; maxsize = MAXSIZE; warmup = 0; // Defaults to off set_bms_names(); /* Command line arguments parsing */ for(int i = 1; i < argc; i++){ if(strcmp(argv[i],"-off_cache") == 0){ cache_invalidation = 1; } else if(strcmp(argv[i],"-msglen") == 0){ i++; if(i == argc){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } else{ alternative_sizes = 1; sizes_file = argv[i]; } } else if(strcmp(argv[i],"-input") == 0){ i++; if(i == argc){ if(MYTHREAD == 0) print_usage(argv[0]); upc_barrier; exit(-1); } else{ alternative_bm_list = 1; bm_file = argv[i]; } } else if(strcmp(argv[i],"-reduce_op") == 0){ i++; if(i == argc){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } else{ if(set_reduce_op(argv[i]) != 0){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } } } else if(strcmp(argv[i],"-sync_mode") == 0){ i++; if(i == argc){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } else{ if(set_sync_mode(argv[i]) != 0){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } } } else if(strcmp(argv[i],"-minsize") == 0){ i++; if(i == argc){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } else{ if(set_min_size(argv[i]) != 0){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } } } else if(strcmp(argv[i],"-maxsize") == 0){ i++; if(i == argc){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } else{ if(set_max_size(argv[i]) != 0){ if(MYTHREAD == 0) print_usage(argv[0]); exit(-1); } } } else if(strcmp(argv[i],"-warmup") == 0){ warmup = 1; } else if(strcmp(argv[i],"-help") == 0){ if(MYTHREAD == 0) print_usage(argv[0]); upc_barrier; exit(-1); } else if(strcmp(argv[i],"-version") == 0){ if(MYTHREAD == 0) print_version(); upc_barrier; exit(-1); } else{ if(i == argc-1 && argv[i][0] != '-' ){ alternative_output_file = 1; output_file = argv[i]; } else{ if(MYTHREAD == 0){ printf("Unrecognized option ignored: %s\n",argv[i]); } } } } /* Optional files checking and parsing */ set_sizes(alternative_sizes,sizes_file); set_bms(alternative_bm_list,bm_file); /* Optional output file */ if(alternative_output_file){ errno = 0; unit = fopen(output_file,"w"); if(errno != 0){ if(MYTHREAD == 0){ fprintf(stderr,"*** Error creating or truncating file %s: ",output_file); perror(NULL); } upc_barrier; exit(-1); } } else{ unit = stdout; } UOMS_init(); }