int do_KLR_mapping(network_t *network, options_t *opt, idx_t *part) { int ret = ORCC_OK; int i; proc_info_t *processors; assert(network != NULL); assert(opt != NULL); assert(part != NULL); processors = init_processors(opt->nb_processors); print_orcc_trace(ORCC_VL_VERBOSE_1, "Applying Kernighan Lin Refinement Weighted strategy for mapping"); sort_actors(network->actors, network->nb_actors); for (i = 0; i < network->nb_actors; i++) { assign_actor_to_min_utilized_processor(network, part, processors, opt->nb_processors, i); } do_KL_algorithm(network, part, processors, opt->nb_processors); if (check_verbosity(ORCC_VL_VERBOSE_2) == TRUE) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : KLRLB result"); for (i = 0; i < network->nb_actors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Actor[%d]\tname = %s\tworkload = %d\tprocessorId = %d", i, network->actors[i]->name, network->actors[i]->workload, network->actors[i]->processor_id); } } delete_processors(processors); return ret; }
/** * Round Robin strategy * @author Long Nguyen */ int do_round_robbin_mapping(network_t *network, options_t *opt, idx_t *part) { int ret = ORCC_OK; int i, k = 0; assert(network != NULL); assert(opt != NULL); assert(part != NULL); print_orcc_trace(ORCC_VL_VERBOSE_1, "Applying Round Robin strategy for mapping"); sort_actors(network->actors, network->nb_actors); for (i = 0; i < network->nb_actors; i++) { network->actors[i]->processor_id = k++; part[i] = network->actors[i]->processor_id; // There must be something needing to be improved here, i.e. invert // the direction of the distribution to have more balancing. if (k >= opt->nb_processors) k = 0; } if (check_verbosity(ORCC_VL_VERBOSE_2) == TRUE) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Round Robin result"); for (i = 0; i < network->nb_actors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Actor[%d]\tname = %s\tworkload = %d\tprocessorId = %d", i, network->actors[i]->name, network->actors[i]->workload, network->actors[i]->processor_id); } } return ret; }
int do_weighted_round_robin_comm_mapping(network_t *network, options_t *opt, idx_t *part) { int ret = ORCC_OK; int i, j; int selectedProc, minCommIndex; proc_info_t *processors; assert(network != NULL); assert(opt != NULL); assert(part != NULL); print_orcc_trace(ORCC_VL_VERBOSE_1, "Applying Communication Optimized Weighted strategy for mapping"); processors = init_processors(opt->nb_processors); sort_actors(network->actors, network->nb_actors); for (i = 0; i < network->nb_actors; i++) { selectedProc = find_min_utilized_processor(processors, opt->nb_processors); minCommIndex = -1; for (j = 0; j < network->nb_actors; j++) { if (network->actors[j]->processor_id == -1) { if (minCommIndex == -1) { minCommIndex = j; } if (calculate_comm_of_actor(network, processors, j, selectedProc) <= calculate_comm_of_actor(network, processors, minCommIndex, selectedProc)) { minCommIndex = j; } } } network->actors[minCommIndex]->processor_id = processors[selectedProc].processor_id; part[minCommIndex] = network->actors[minCommIndex]->processor_id; processors[selectedProc].utilization += network->actors[minCommIndex]->workload; } if (check_verbosity(ORCC_VL_VERBOSE_2) == TRUE) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : COWLB result"); for (i = 0; i < network->nb_actors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Actor[%d]\tname = %s\tworkload = %d\tprocessorId = %d", i, network->actors[i]->name, network->actors[i]->workload, network->actors[i]->processor_id); } for (i = 0; i < opt->nb_processors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Workload Proc[%d]: %d", i, processors[i].utilization); } } delete_processors(processors); return ret; }
int sort_actors(actor_t **actors, int nb_actors) { int ret = ORCC_OK; int i, j; assert(actors != NULL); for (i = 0; i < nb_actors; i++) { for (j = 0; j < nb_actors - i - 1; j++) { if (actors[j]->workload <= actors[j+1]->workload) { swap_actors(actors, j, j+1, nb_actors); } } } if (check_verbosity(ORCC_VL_VERBOSE_2) == TRUE) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : The sorted list:"); for (i = 0; i < nb_actors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Actor[%d]\tid = %s\tworkload = %d", i, actors[i]->name, actors[i]->workload); } } return ret; }
/** * Entry point for all mapping strategies */ int do_mapping(network_t *network, options_t *opt, mapping_t *mapping) { int ret = ORCC_OK; idx_t *part; ticks startTime, endTime; assert(network != NULL); assert(opt != NULL); assert(mapping != NULL); part = (idx_t*) malloc(sizeof(idx_t) * (network->nb_actors)); if(check_verbosity(ORCC_VL_VERBOSE_2)) { print_network(network); } startTime = getticks(); if (opt->nb_processors != 1) { switch (opt->strategy) { #ifdef METIS_ENABLE case ORCC_MS_METIS_REC: ret = do_metis_recursive_partition(network, opt, part); break; case ORCC_MS_METIS_KWAY_CV: ret = do_metis_kway_partition(network, opt, part, METIS_OBJTYPE_CUT); /*TODO : should be METIS_OBJTYPE_VOL : Metis seem's to invert its options */ break; case ORCC_MS_METIS_KWAY_EC: ret = do_metis_kway_partition(network, opt, part, METIS_OBJTYPE_VOL); /*TODO : should be METIS_OBJTYPE_CUT : Metis seem's to invert its options */ break; #endif case ORCC_MS_ROUND_ROBIN: ret = do_round_robbin_mapping(network, opt, part); break; case ORCC_MS_QM: ret = do_quick_mapping(network, opt, part); break; case ORCC_MS_WLB: ret = do_weighted_round_robin_mapping(network, opt, part); break; case ORCC_MS_COWLB: ret = do_weighted_round_robin_comm_mapping(network, opt, part); break; case ORCC_MS_KRWLB: ret = do_KLR_mapping(network, opt, part); break; default: break; } } else { int i; for (i = 0; i < network->nb_actors; i++) { part[i] = 0; } } endTime = getticks(); set_mapping_from_partition(network, part, mapping); if(check_verbosity(ORCC_VL_VERBOSE_1)) { print_mapping(mapping); print_load_balancing(mapping); print_edge_cut(network); print_orcc_trace(ORCC_VL_VERBOSE_2, "Mapping time : %2.lf", elapsed(endTime, startTime)); } free(part); return ret; }
/* Parse a single option. */ static error_t parse_opt(int key, char *opt_arg, struct argp_state *state) { /* Get the input argument from argp_parse, which we know is a pointer to our arguments structure. */ arguments *arg = state->input; switch (key) { case 'q': check_verbosity(state, arg, orcm_quiet); arg->verbosity = orcm_quiet; break; case 'v': check_verbosity(state, arg, orcm_verbose); arg->verbosity = orcm_verbose; break; case 'd': check_verbosity(state, arg, orcm_debug); arg->verbosity = orcm_debug; break; case 'c': check_color(state,arg, orcc_use_color); arg->color = orcc_use_color; break; case 'n': check_color(state,arg, orcc_no_color); arg->color = orcc_no_color; break; case 'e': if(1 != sscanf(opt_arg, "%d", &(arg->max_events))) { orcerror("Events set to a non integer value.\n"); argp_usage(state); } if (1 > arg->max_events) { orcerror("Events set to a 0 or a negative value.\n"); argp_usage(state); } break; case 1001: arg->excludes_len++; size_t size = arg->excludes_len * sizeof(*(arg->excludes)); char **tmp; tmp = realloc(arg->excludes, size); if (0 == tmp) { if (0 != arg->excludes) { free(arg->excludes); } orcerror("%s (%d)\n", strerror(errno), errno); exit(EXIT_FAILURE); } tmp[arg->excludes_len - 1] = opt_arg; arg->excludes = tmp; break; case 'o': arg->out_file = opt_arg; break; case ARGP_KEY_ARG: if (state->arg_num > 1) { /* Too many arguments. */ argp_usage(state); } if (('h'== opt_arg[0] && 't' == opt_arg[1] &&'t' == opt_arg[2] && 'p' == opt_arg[3] && ':' == opt_arg[4] && '/' == opt_arg[5] && '/' == opt_arg[6]) || ('h'== opt_arg[0] && 't' == opt_arg[1] &&'t' == opt_arg[2] && 'p' == opt_arg[3] && 's' == opt_arg[4] && ':' == opt_arg[5] && '/' == opt_arg[6] && '/'== opt_arg[7])) { arg->url = opt_arg; } else { orcerror("Add http:// or https:// to your target url.\n", strerror(errno), errno); exit(EXIT_FAILURE); } break; case ARGP_KEY_END: if (state->arg_num < 1) { /* Not enough arguments. */ argp_usage(state); } break; default: return ARGP_ERR_UNKNOWN; } return 0; }
int do_quick_mapping(network_t *network, options_t *opt, idx_t *part) { int ret = ORCC_OK; int i, unMappedActors, selectedProcIndex, maxCommCost, maxIndex, total_workload = 0; proc_info_t *processors; assert(network != NULL); assert(opt != NULL); assert(part != NULL); processors = init_processors(opt->nb_processors); print_orcc_trace(ORCC_VL_VERBOSE_1, "Applying Quick Mapping strategy for mapping"); unMappedActors = network->nb_actors; selectedProcIndex = 0; for (i = 0; i < network->nb_actors; i++) { total_workload += network->actors[i]->workload; } while (unMappedActors > 0) { maxIndex = 0; maxCommCost = 0; for (i = 0; i < network->nb_actors; i++) { if (network->actors[i]->processor_id == -1) { if (network->actors[i]->triedProcId != processors[selectedProcIndex].processor_id) { network->actors[i]->commCost = 0; network->actors[i]->triedProcId = processors[selectedProcIndex].processor_id; } if (network->actors[i]->commCost >= maxCommCost) { maxCommCost = network->actors[i]->commCost; maxIndex = i; } } } network->actors[maxIndex]->processor_id = processors[selectedProcIndex].processor_id; part[maxIndex] = network->actors[maxIndex]->processor_id; processors[selectedProcIndex].utilization += network->actors[maxIndex]->workload; for (i = 0; i < network->nb_connections; i++) { if (network->connections[i]->src->id == network->actors[maxIndex]->id) { network->actors[network->connections[i]->dst->id]->commCost += network->connections[i]->workload; } if (network->connections[i]->dst->id == network->actors[maxIndex]->id) { network->actors[network->connections[i]->src->id]->commCost += network->connections[i]->workload; } } if (processors[selectedProcIndex].utilization >= total_workload / opt->nb_processors && selectedProcIndex < opt->nb_processors - 1) { selectedProcIndex++; } unMappedActors--; } if (check_verbosity(ORCC_VL_VERBOSE_2) == TRUE) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : QM result"); for (i = 0; i < network->nb_actors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Actor[%d]\tname = %s\tworkload = %d\tprocessorId = %d", i, network->actors[i]->name, network->actors[i]->workload, network->actors[i]->processor_id); } for (i = 0; i < opt->nb_processors; i++) { print_orcc_trace(ORCC_VL_VERBOSE_2, "DEBUG : Workload Proc[%d]: %d", i, processors[i].utilization); } } delete_processors(processors); return ret; }