int agg_init(hsignature_t *sig) { const char *val; val = session_getcfg("AGG_FUNC"); if (!val) { session_error("AGG_FUNC configuration key empty"); return -1; } if (strcasecmp(val, "MIN") == 0) agg_type = AGG_MIN; else if (strcasecmp(val, "MAX") == 0) agg_type = AGG_MAX; else if (strcasecmp(val, "MEAN") == 0) agg_type = AGG_MEAN; else if (strcasecmp(val, "MEDIAN") == 0) agg_type = AGG_MEDIAN; else { session_error("Invalide AGG_FUNC configuration value"); return -1; } val = session_getcfg("AGG_TIMES"); if (!val) { session_error("AGG_TIMES configuration key empty"); return -1; } trial_per_point = atoi(val); if (!trial_per_point) { session_error("Invalid AGG_TIMES configuration value"); return -1; } slist = NULL; slist_len = 0; return add_storage(); }
int url_connect(const char *url) { const char *ptr; char *helper_argv[2]; int count; ptr = strstr(url, "//"); if (!ptr) return -1; if (strncmp("dir:", url, ptr - url) == 0 || strncmp("ssh:", url, ptr - url) == 0) { ptr = session_getcfg(CFGKEY_HARMONY_HOME); if (!ptr) return -1; count = snprintf_grow(&buf, &buflen, "%s/libexec/codegen-helper", ptr); if (count < 0) return -1; helper_argv[0] = buf; helper_argv[1] = NULL; return socket_launch(buf, helper_argv, NULL); } else if (strncmp("tcp:", url, ptr - url) == 0) { /* Not implemented yet. */ } return -1; }
/* * Invoked once on module load. * * This routine should return 0 on success, and -1 otherwise. */ int codegen_init(hsignature_t *sig) { const char *url; hcfg_t *cfg; url = session_getcfg(CFGKEY_TARGET_URL); if (!url || url[0] == '\0') { session_error("Destination URL for" " generated code objects not specified"); return -1; } url = session_getcfg(CFGKEY_SERVER_URL); if (!url || url[0] == '\0') { session_error("Codegen server URL not specified"); return -1; } sockfd = url_connect(url); if (sockfd == -1) { session_error("Invalid codegen server URL"); return -1; } /* In the future, we should rewrite the code generator system to * avoid using hmesg_t types. Until then, generate a fake * HMESG_SESSION message to maintain compatibility. */ mesg = HMESG_INITIALIZER; hsignature_copy(&mesg.data.session.sig, sig); cfg = hcfg_alloc(); hcfg_set(cfg, CFGKEY_SERVER_URL, session_getcfg(CFGKEY_SERVER_URL)); hcfg_set(cfg, CFGKEY_TARGET_URL, session_getcfg(CFGKEY_TARGET_URL)); hcfg_set(cfg, CFGKEY_REPLY_URL, session_getcfg(CFGKEY_REPLY_URL)); hcfg_set(cfg, CFGKEY_SLAVE_LIST, session_getcfg(CFGKEY_SLAVE_LIST)); hcfg_set(cfg, CFGKEY_SLAVE_PATH, session_getcfg(CFGKEY_SLAVE_PATH)); mesg.data.session.cfg = cfg; mesg.type = HMESG_SESSION; mesg.status = HMESG_STATUS_REQ; if (mesg_send(sockfd, &mesg) < 1) return -1; if (mesg_recv(sockfd, &mesg) < 1) return -1; if (callback_generate(sockfd, codegen_callback) != 0) { session_error("Could not register callback for codegen plugin"); return -1; } return 0; }
int libvertex_init(hsignature_t *sig) { if (range != sig->range) { range = sig->range; N = sig->range_len; P = atoi( session_getcfg(CFGKEY_PERF_COUNT) ); sizeof_vertex = sizeof(vertex_t) + N * sizeof(double); free(vmin); vmin = vertex_alloc(); if (!vmin || internal_vertex_min(vmin) != 0) return -1; hperf_reset(vmin->perf); free(vmax); vmax = vertex_alloc(); if (!vmax || internal_vertex_max(vmax) != 0) return -1; hperf_reset(vmax->perf); } return 0; }
int parse_strategies(const char *list) { /* Much code stolen from session-core.c's load_layers() */ const char *prefix, *end; char *path; int path_len, retval; void *lib; strategy_t *strat; char *name; path = NULL; name = NULL; path_len = 0; retval = 0; while (list && *list) { if (strat_count == strat_cap) { if (array_grow(&strategies, &strat_cap, sizeof(strategy_t)) < 0) { retval = -1; goto cleanup; } } end = strchr(list, ':'); if (!end) end = list + strlen(list); name = (char *) malloc((end - list + 1) * sizeof(char)); if (!name) { retval = -1; goto cleanup; } strncpy(name, list, end - list); name[end-list] = '\0'; prefix = session_getcfg(CFGKEY_HARMONY_HOME); if (snprintf_grow(&path, &path_len, "%s/libexec/%.*s", prefix, end - list, list) < 0) { retval = -1; goto cleanup; } lib = dlopen(path, RTLD_LAZY | RTLD_LOCAL); if (!lib) { errmsg = dlerror(); retval = -1; goto cleanup; } strat->name = name; strat->lib = lib; // load function pointers into the data structure strat = strategies + strat_count; strat->generate = (strategy_generate_t) dlfptr(lib, "strategy_generate"); strat->rejected = (strategy_rejected_t) dlfptr(lib, "strategy_rejected"); strat->analyze = (strategy_analyze_t) dlfptr(lib, "strategy_analyze"); strat->hint = (strategy_analyze_t) dlfptr(lib, "strategy_hint"); strat->best = (strategy_best_t) dlfptr(lib, "strategy_best"); // make sure the required functions are present if (!(strat->generate && strat->rejected && strat->analyze && strat->best)) { errmsg = "Sub-strategy does not define all required functions"; retval = -1; goto cleanup; } strat->init = (hook_init_t) dlfptr(lib, "strategy_init"); strat->join = (hook_join_t) dlfptr(lib, "strategy_join"); strat->getcfg = (hook_getcfg_t) dlfptr(lib, "strategy_getcfg"); strat->setcfg = (hook_setcfg_t) dlfptr(lib, "strategy_setcfg"); strat->fini = (hook_fini_t) dlfptr(lib, "strategy_fini"); name = NULL; // to avoid freeing it in cleanup lib = NULL; // avoid closing in cleanup // success; prepare for the loop test and next iteration ++strat_count; if (*end) list = end + 1; else list = NULL; } cleanup: free(path); free(name); if (lib) dlclose(lib); if (retval == -1) { // error exit; free allocated space for names, close shared libs int i; for (i = 0; i < strat_count; i++) free_strat(strategies+i); } return retval; }
int strategy_init(hsignature_t *sig) { int retval; best = HPOINT_INITIALIZER; best_perf = INFINITY; // Load constants for sliding window and tradeoff constant const char *window_str = session_getcfg(WINDOW_SIZE_PARAM); if (!window_str) window_size = DEFAULT_WINDOW_SIZE; else { window_size = atoi(window_str); if (window_size <= 0) { session_error("Invalid " WINDOW_SIZE_PARAM); return -1; } } const char *tradeoff_str = session_getcfg(TRADEOFF_PARAM); if (!tradeoff_str) tradeoff = DEFAULT_TRADEOFF; else { tradeoff = atof(tradeoff_str); if (tradeoff <= 0.0) { session_error("Invalid " TRADEOFF_PARAM); return -1; } } explore_factor = tradeoff * sqrt(2.0 * log2((double) window_size)); // Load the sub-strategies and run their init's in order const char *strats = session_getcfg(STRATEGIES_PARAM); if (!strats) { session_error("No strategy list provided in " STRATEGIES_PARAM); return -1; } retval = parse_strategies(strats); if (retval < 0) { session_error(errmsg ? errmsg : "Error parsing strategy list (allocation filed?)"); return -1; } if (strat_count > MAX_NUM_STRATEGIES) { session_error("Too many strategies specified."); free_strategies(); return -1; } best_per_strategy = (hpoint_t *) malloc(strat_count * sizeof(hpoint_t)); best_perf_per_strategy = (double *) malloc(strat_count * sizeof(double)); if (best_per_strategy == NULL || best_perf_per_strategy == NULL) { session_error("Couldn't allocate memory for control structures."); free_strategies(); free(best_per_strategy); free(best_perf_per_strategy); return -1; } // code above this should be run once; below this should be run on // every restart---unless we want to allow window size and tradeoff // to change on restart? if (init_sliding_window() < 0) { free_strategies(); free(best_per_strategy); free(best_perf_per_strategy); return -1; } int i; for (i = 0; i < strat_count; i++) { hook_init_t init = strategies[i].init; if (init) { retval = (strategies[i].init)(sig); if (retval < 0) // sub-strategy should have called session_error return retval; } } // TODO I have not handled restarts; need to understand that better. return retval; }
int strategy_cfg(hsignature_t *sig) { const char *cfgval; char *endp; init_method = SIMPLEX_INIT_CENTER; /* Default value. */ cfgval = session_getcfg(CFGKEY_INIT_METHOD); if (cfgval) { if (strcasecmp(cfgval, "center") == 0) { init_method = SIMPLEX_INIT_CENTER; } else if (strcasecmp(cfgval, "random") == 0) { init_method = SIMPLEX_INIT_RANDOM; } else if (strcasecmp(cfgval, "point") == 0) { init_method = SIMPLEX_INIT_POINT; } else { session_error("Invalid value for " CFGKEY_INIT_METHOD " configuration key."); return -1; } } /* CFGKEY_INIT_POINT will override CFGKEY_INIT_METHOD if necessary. */ cfgval = session_getcfg(CFGKEY_INIT_POINT); if (cfgval) { init_method = SIMPLEX_INIT_POINT; } cfgval = session_getcfg(CFGKEY_INIT_PERCENT); if (cfgval) { init_percent = strtod(cfgval, &endp); if (*endp != '\0') { session_error("Invalid value for " CFGKEY_INIT_PERCENT " configuration key."); return -1; } if (init_percent <= 0 || init_percent > 1) { session_error("Configuration key " CFGKEY_INIT_PERCENT " must be between 0.0 and 1.0 (exclusive)."); return -1; } } cfgval = session_getcfg(CFGKEY_REJECT_METHOD); if (cfgval) { if (strcasecmp(cfgval, "penalty") == 0) { reject_type = REJECT_METHOD_PENALTY; } else if (strcasecmp(cfgval, "random") == 0) { reject_type = REJECT_METHOD_RANDOM; } else { session_error("Invalid value for " CFGKEY_REJECT_METHOD " configuration key."); return -1; } } cfgval = session_getcfg(CFGKEY_REFLECT); if (cfgval) { reflect = strtod(cfgval, &endp); if (*endp != '\0') { session_error("Invalid value for " CFGKEY_REFLECT " configuration key."); return -1; } if (reflect <= 0.0) { session_error("Configuration key " CFGKEY_REFLECT " must be positive."); return -1; } } cfgval = session_getcfg(CFGKEY_EXPAND); if (cfgval) { expand = strtod(cfgval, &endp); if (*endp != '\0') { session_error("Invalid value for " CFGKEY_EXPAND " configuration key."); return -1; } if (expand <= reflect) { session_error("Configuration key " CFGKEY_EXPAND " must be greater than the reflect coefficient."); return -1; } } cfgval = session_getcfg(CFGKEY_SHRINK); if (cfgval) { shrink = strtod(cfgval, &endp); if (*endp != '\0') { session_error("Invalid value for " CFGKEY_SHRINK " configuration key."); return -1; } if (shrink <= 0.0 || shrink >= 1.0) { session_error("Configuration key " CFGKEY_SHRINK " must be between 0.0 and 1.0 (exclusive)."); return -1; } } cfgval = session_getcfg(CFGKEY_FVAL_TOL); if (cfgval) { fval_tol = strtod(cfgval, &endp); if (*endp != '\0') { session_error("Invalid value for " CFGKEY_FVAL_TOL " configuration key."); return -1; } } cfgval = session_getcfg(CFGKEY_SIZE_TOL); if (cfgval) { size_tol = strtod(cfgval, &endp); if (*endp != '\0') { session_error("Invalid value for " CFGKEY_SIZE_TOL " configuration key."); return -1; } } else { /* Default stopping criteria: 0.5% of dist(vertex_min, vertex_max). */ size_tol = vertex_dist(vertex_min(), vertex_max()) * 0.005; } return 0; }
/* * Invoked once on strategy load. */ int strategy_init(hsignature_t *sig) { if (libvertex_init(sig) != 0) { session_error("Could not initialize vertex library."); return -1; } if (!base) { const char *cfgval; /* One time memory allocation and/or initialization. */ cfgval = session_getcfg(CFGKEY_SIMPLEX_SIZE); if (cfgval) simplex_size = atoi(cfgval); /* Make sure the simplex size is N+1 or greater. */ if (simplex_size < sig->range_len + 1) simplex_size = sig->range_len + 1; init_point = vertex_alloc(); if (!init_point) { session_error("Could not allocate memory for initial point."); return -1; } test = simplex_alloc(simplex_size); if (!test) { session_error("Could not allocate memory for candidate simplex."); return -1; } base = simplex_alloc(simplex_size); if (!base) { session_error("Could not allocate memory for reference simplex."); return -1; } /* The best point and trial counter should only be initialized once, * and thus be retained across a restart. */ best = HPOINT_INITIALIZER; best_perf = INFINITY; next_id = 1; } /* Initialization for subsequent calls to strategy_init(). */ vertex_reset(init_point); simplex_reset(test); simplex_reset(base); reported = 0; send_idx = 0; coords = sig->range_len; if (strategy_cfg(sig) != 0) return -1; switch (init_method) { case SIMPLEX_INIT_CENTER: vertex_center(init_point); break; case SIMPLEX_INIT_RANDOM: vertex_rand_trim(init_point, init_percent); break; case SIMPLEX_INIT_POINT: vertex_from_string(session_getcfg(CFGKEY_INIT_POINT), sig, init_point); break; default: session_error("Invalid initial search method."); return -1; } simplex_from_vertex(init_point, init_percent, base); if (session_setcfg(CFGKEY_STRATEGY_CONVERGED, "0") != 0) { session_error("Could not set " CFGKEY_STRATEGY_CONVERGED " config variable."); return -1; } state = SIMPLEX_STATE_INIT; if (pro_next_simplex(test) != 0) { session_error("Could not initiate the simplex."); return -1; } return 0; }
int strategy_cfg(hsignature_t *sig) { const char *cfgval; cfgval = session_getcfg(CFGKEY_OC_BIN); if (cfgval) omega_bin = cfgval; if (!file_exists(omega_bin)) { omega_bin = search_path(omega_bin); if (!omega_bin) { session_error("Could not find Omega Calculator executable." " Use " CFGKEY_OC_BIN " to specify its location."); return -1; } } cfgval = session_getcfg(CFGKEY_QUIET); if (cfgval) { quiet = (*cfgval == '1' || *cfgval == 't' || *cfgval == 'T' || *cfgval == 'y' || *cfgval == 'Y'); } cfgval = session_getcfg(CFGKEY_CONSTRAINTS); if (cfgval) { if (strlen(cfgval) >= sizeof(constraints)) { session_error("Constraint string too long"); return -1; } strncpy(constraints, cfgval, sizeof(constraints)); } else { FILE *fp; cfgval = session_getcfg(CFGKEY_CONSTRAINT_FILE); if (!cfgval) { session_error("No constraints specified. Either " CFGKEY_CONSTRAINTS " or " CFGKEY_CONSTRAINT_FILE " must be defined."); return -1; } fp = fopen(cfgval, "r"); if (!fp) { session_error("Could not open constraint file"); return -1; } fread(constraints, sizeof(char), sizeof(constraints) - 1, fp); constraints[sizeof(constraints) - 1] = '\0'; if (!feof(fp)) { session_error("Constraint file too large"); return -1; } if (fclose(fp) != 0) { session_error("Could not close constraint file"); return -1; } } return 0; }