int codegen_callback(int fd, hflow_t *flow, int n, htrial_t **trial) { int i; if (mesg_recv(fd, &mesg) < 1) return -1; i = cglog_find(&mesg.data.fetch.cand); if (i < 0) { session_error("Could not find point from code server in log"); return -1; } cglog[i].status = CODEGEN_STATUS_COMPLETE; /* Search waitlist for index of returned point. */ for (i = 0; i < n; ++i) { if (trial[i]->point.id == mesg.data.fetch.cand.id) { flow->status = HFLOW_ACCEPT; return i; } } session_error("Could not find point from code server in waitlist"); return -1; }
/* * Called after search driver generates a candidate point, but before * that point is returned to the client API. * * This routine should fill the flow variable appropriately and return * 0 upon success. Otherwise, it should call session_error() with a * human-readable error message and return -1. */ int codegen_generate(hflow_t *flow, htrial_t *trial) { int i; i = cglog_find(&trial->point); if (i >= 0) { if (cglog[i].status == CODEGEN_STATUS_COMPLETE) flow->status = HFLOW_ACCEPT; if (cglog[i].status == CODEGEN_STATUS_REQUESTED) flow->status = HFLOW_WAIT; return 0; } if (cglog_insert(&trial->point) != 0) { session_error("Internal error: Could not grow codegen log"); return -1; } mesg = HMESG_INITIALIZER; mesg.type = HMESG_FETCH; mesg.status = HMESG_STATUS_OK; mesg.data.fetch.cand = HPOINT_INITIALIZER; mesg.data.fetch.best = HPOINT_INITIALIZER; hpoint_copy(&mesg.data.fetch.cand, &trial->point); if (mesg_send(sockfd, &mesg) < 1) { session_error( strerror(errno) ); return -1; } flow->status = HFLOW_WAIT; return 0; }
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(); }
/* * 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; }
// We'll identify points using 7 bits for the strategy index and 24 for the // ID the strategy is using internally. If the strategy uses an ID that // doesn't fit in 24 bits, we'll throw an error and I have to use a freaking // lookup table or something. int translate_id_from_sub(int strategy_id, int point_id) { int new_id = point_id & POINT_ID_MASK; if (new_id != point_id) { session_error("substrategy point ID didn't fit in 24 bits"); return -1; } if (strategy_id < 0 || strategy_id >= MAX_NUM_STRATEGIES) { session_error("internal error: strategy_id outside valid range"); return -1; } new_id |= (strategy_id << POINT_ID_BITS); return new_id; }
int build_user_text(void) { const char *ptr = constraints; const char *end; int len = 0; while (*ptr) { while (isspace(*ptr)) ++ptr; end = ptr + strcspn(ptr, "\n"); len += end - ptr; if (len < sizeof(user_text)) strncat(user_text, ptr, end - ptr); while (isspace(*end)) ++end; if (*end) { len += 4; if (len < sizeof(user_text)) strcat(user_text, " && "); } if (len >= sizeof(user_text)) { session_error("User constraint string overflow"); return -1; } ptr = end; } return 0; }
int strategy_best(hpoint_t *point) { if (hpoint_copy(point, &best) != 0) { session_error("Could not copy best point during request for best."); return -1; } return 0; }
/* * Return the best performing point thus far in the search. */ int strategy_best(hpoint_t *point) { if (hpoint_copy(point, &best) != 0) { session_error("Internal error: Could not copy point."); return -1; } return 0; }
void server_handle_message(ssh_session s, ssh_message m, int type, int subtype, int *state) { int handled = 0; if((*state == SERVER_CONNECTED) && (type == SSH_REQUEST_AUTH) && (subtype == SSH_AUTH_METHOD_PUBLICKEY)) { ssh_public_key key = ssh_message_auth_publickey(m); ssh_string keystr = publickey_to_string(key); char *keyhash = pubkey_hash(keystr); int has_sig = ssh_message_auth_publickey_state(m); if(has_sig == SSH_PUBLICKEY_STATE_NONE) { if(authenticate(keyhash, 1)) { //FIXME: type detection ssh_string algostr = ssh_string_from_char("ssh-rsa"); ssh_message_auth_reply_pk_ok(m, algostr, keystr); handled = 1; ssh_string_free(algostr); } } else if(has_sig == SSH_PUBLICKEY_STATE_VALID) { if(authenticate(keyhash, 0)) { session_event(s, "authenticated", keyhash); ssh_message_auth_reply_success(m, 0); handled = 1; *state = SERVER_AUTHENTICATED; } else { ssh_message_reply_default(m); handled = 1; *state = SERVER_CLOSED; } } ssh_string_free(keystr); free(keyhash); } else if((*state == SERVER_AUTHENTICATED) && (type == SSH_REQUEST_CHANNEL_OPEN) && (subtype == SSH_CHANNEL_SESSION)) { ssh_channel chan = ssh_message_channel_request_open_reply_accept(m); if(!chan) session_error(s, "open-channel"); handled = 1; session_event(s, "channel-opened", NULL); channel_to_file(chan, 1); ssh_channel_free(chan); *state = SERVER_CLOSED; } if(!handled) ssh_message_reply_default(m); }
int add_storage(void) { int prev_len = slist_len; if (array_grow(&slist, &slist_len, sizeof(store_t)) != 0) { session_error("Could not allocate memory for aggregator list"); return -1; } while (prev_len < slist_len) { slist[prev_len].id = -1; slist[prev_len].trial = (hperf_t **) calloc(trial_per_point, sizeof(hperf_t *)); if (!slist[prev_len].trial) { session_error("Could not allocate memory for trial list"); return -1; } ++prev_len; } return 0; }
void context::open_session() { _M_code = setcred(); if(errc(_M_code) != errc::success) throw cred_error(_M_pamh, _M_code); _M_code = pam_open_session(_M_pamh, 0); if(errc(_M_code) != errc::success) { rmcred(); throw session_error(_M_pamh, _M_code); } }
void context::close_session() { _M_code = pam_close_session(_M_pamh, 0); if(errc(_M_code) != errc::success) { rmcred(); throw session_error(_M_pamh, _M_code); } _M_code = rmcred(); if(errc(_M_code) != errc::success) throw cred_error(_M_pamh, _M_code); }
// Listen for incoming SSH connections. // When a connection is established, write all data received to stdout. void server_pipe(char *host, int port) { ssh_bind b = ssh_bind_new(); ssh_session s = ssh_new(); ssh_bind_options_set(b, SSH_BIND_OPTIONS_BINDADDR, host); ssh_bind_options_set(b, SSH_BIND_OPTIONS_BINDPORT, &port); ssh_bind_options_set(b, SSH_BIND_OPTIONS_RSAKEY, "test-server-key"); ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "5"); if(ssh_bind_listen(b) < 0) session_error(b, "listen"); if(ssh_bind_accept(b, s) != SSH_OK) session_error(b, "accept"); if(ssh_accept(s) < 0) session_error(s, "handshake"); int state = SERVER_CONNECTED; while(1) { ssh_message m = ssh_message_get(s); if(m) { int type = ssh_message_type(m); int subtype = ssh_message_subtype(m); ssh_message_auth_set_methods(m, SSH_AUTH_METHOD_PUBLICKEY); server_handle_message(s, m, type, subtype, &state); ssh_message_free(m); if(state == SERVER_CLOSED) { ssh_disconnect(s); ssh_bind_free(b); ssh_finalize(); return; } } else { session_error(s, "session"); } } }
/* * Analyze the observed performance for this configuration point. */ int strategy_analyze(htrial_t *trial) { int i; double perf = hperf_unify(trial->perf); for (i = 0; i < simplex_size; ++i) { if (test->vertex[i]->id == trial->point.id) break; } if (i == simplex_size) { /* Ignore rouge vertex reports. */ return 0; } ++reported; hperf_copy(test->vertex[i]->perf, trial->perf); if (hperf_cmp(test->vertex[i]->perf, test->vertex[best_test]->perf) < 0) best_test = i; if (reported == simplex_size) { if (pro_algorithm() != 0) { session_error("Internal error: PRO algorithm failure."); return -1; } reported = 0; send_idx = 0; } /* Update the best performing point, if necessary. */ if (best_perf > perf) { best_perf = perf; if (hpoint_copy(&best, &trial->point) != 0) { session_error( strerror(errno) ); return -1; } } return 0; }
int vertex_from_string(const char *str, hsignature_t *sig, vertex_t *result) { int retval = 0; hpoint_t pt = HPOINT_INITIALIZER; if (!str) { session_error("Cannot convert null string to vertex"); return -1; } if (hpoint_init(&pt, sig->range_len) != 0) { session_error("Error initializing temporary hpoint"); return -1; } if (hpoint_parse(&pt, sig, str) != 0) { session_error("Error parsing point string"); retval = -1; goto cleanup; } if (hpoint_align(&pt, sig) != 0) { session_error("Error aligning point to session signature"); retval = -1; goto cleanup; } if (vertex_from_hpoint(&pt, result) != 0) { session_error("Error converting point to vertex"); retval = -1; } cleanup: hpoint_fini(&pt); return retval; }
int strategy_rejected(hflow_t *flow, hpoint_t *point) { int strategy_id, sub_point_id, orig_point_id; // We always let the original sub-strategy regenerate its own point. orig_point_id = point->id; sub_point_id = translate_id_to_sub(point->id, &strategy_id); if (strategy_id < 0 || strategy_id >= MAX_NUM_STRATEGIES) { session_error("Invalid strategy ID in strategy_rejected."); return -1; } if (flow->point.id == orig_point_id) flow->point.id = sub_point_id; point->id = sub_point_id; int result = strategies[strategy_id].rejected(flow, point); point->id = translate_id_from_sub(strategy_id, point->id); return result; }
// Connect to a SSH server. // When the connection is established, read data from stdin and send it to the server. void client_pipe(char *host, int port) { ssh_session s = ssh_new(); ssh_options_set(s, SSH_OPTIONS_HOST, host); ssh_options_set(s, SSH_OPTIONS_PORT, &port); ssh_options_set(s, SSH_OPTIONS_USER, "xya"); //ssh_options_set(s, SSH_OPTIONS_LOG_VERBOSITY_STR, "5"); if(ssh_connect(s) != SSH_OK) return session_error(s, "connect"); char *hash = pubkey_hash(ssh_get_pubkey(s)); if(authenticate(hash, 0)) { session_event(s, "authenticated", hash); free(hash); } else { free(hash); exit(1); } int keytype; ssh_string pub = publickey_from_file(s, "test-client-key.pub", &keytype); if(!pub) session_error(s, "open-public-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_offer_pubkey(s, NULL, keytype, pub)) session_error(s, "offer-public-key"); ssh_private_key priv = privatekey_from_file(s, "test-client-key", keytype, NULL); if(!priv) session_error(s, "open-private-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_pubkey(s, NULL, pub, priv)) session_error(s, "user-auth"); string_free(pub); privatekey_free(priv); ssh_channel chan = channel_new(s); if(!chan) session_error(s, "create-channel"); if(channel_open_session(chan) < 0) session_error(s, "open-channel"); session_event(s, "channel-opened", NULL); channel_from_file(chan, 0); channel_free(chan); ssh_disconnect(s); ssh_finalize(); }
/* * Generate a new candidate configuration point. */ int strategy_generate(hflow_t *flow, hpoint_t *point) { if (send_idx == simplex_size || state == SIMPLEX_STATE_CONVERGED) { flow->status = HFLOW_WAIT; return 0; } test->vertex[send_idx]->id = next_id; if (vertex_to_hpoint(test->vertex[send_idx], point) != 0) { session_error( strerror(errno) ); return -1; } ++next_id; ++send_idx; flow->status = HFLOW_ACCEPT; return 0; }
// request executes an SNMP GETBULK request. char *request(void *sessp, long max_repetitions, oid *name, size_t name_length, struct snmp_pdu **response) { struct snmp_pdu *request = snmp_pdu_create(SNMP_MSG_GETBULK); request->non_repeaters = NON_REPEATERS; request->max_repetitions = max_repetitions; snmp_add_null_var(request, name, name_length); int status = snmp_sess_synch_response(sessp, request, response); if (status != STAT_SUCCESS) { char *errstr = session_error(sessp); char *err = NULL; int failure = asprintf(&err, "SNMP request error: %s", errstr); if (failure == -1) { err = errstr; } else { free(errstr); } return err; } return NULL; }
int assign_scores(double *scores) { int istrat; int isubtrial; int usage_counts[MAX_NUM_STRATEGIES]; int result_counts[MAX_NUM_STRATEGIES]; int auc[MAX_NUM_STRATEGIES]; subtrial_t *subtrial; double best_score = -1.0; int best_strategy = -1; memset(usage_counts, '\0', (MAX_NUM_STRATEGIES)*sizeof(int)); memset(result_counts, '\0', (MAX_NUM_STRATEGIES)*sizeof(int)); memset(auc, '\0', (MAX_NUM_STRATEGIES)*sizeof(int)); for (isubtrial = 0; isubtrial < window_population; isubtrial++) { subtrial = window+isubtrial; if (subtrial->strategy_id < 0 || subtrial->strategy_id >= MAX_NUM_STRATEGIES) { session_error("Internal error: unexpected invalid strategy id"); return -1; } usage_counts[subtrial->strategy_id]++; if (subtrial->complete) result_counts[subtrial->strategy_id]++; if (subtrial->new_best) // implies complete auc[subtrial->strategy_id] += usage_counts[subtrial->strategy_id]; } for (istrat = 0; istrat < strat_count; istrat++) { // handle "unused" and "used but no results" separately if (usage_counts[istrat] == 0) { scores[istrat] = INFINITY; } else { double nuses = (double) usage_counts[istrat]; double nresults = (double) result_counts[istrat]; scores[istrat] = 2.0 * auc[istrat] / nresults / (nresults + 1.0); scores[istrat] += explore_factor / sqrt(nuses); } if (scores[istrat] > best_score) best_strategy = istrat; } return best_strategy; }
gboolean session_timeout(gpointer data){ Session *s; GgServer *serv; g_assert(data!=NULL); s=(Session *)data; serv=(GgServer*)s->current_server->data; user_load_locale(s->user); s->timeout_func=0; g_warning(N_("Session timeout for %s"),s->jid); if(serv->port!=1){ g_warning(N_("Timeout for server %u - failure count: %d"), g_list_position(gg_servers, s->current_server), serv->error_count); } else { g_warning(N_("Timeout for hub %u"), g_list_position(gg_servers, s->current_server)); } return session_error(s); }
int init_sliding_window(void) { int i; if (window != NULL) { // this is a restart, so we need to reset the old contents // we free the old buffer because the size might have changed free(window); } window = (subtrial_t *) malloc(window_size * sizeof(subtrial_t)); if (!window) { session_error("Couldn't allocate memory for sliding window."); return -1; } for (i = 0; i < window_size; i++) { window[i].strategy_id = -1; } window_population = 0; window_next = 0; requests_outstanding = 0; return 0; }
/* * Regenerate a point deemed invalid by a later plug-in. */ int strategy_rejected(hflow_t *flow, hpoint_t *point) { int i; hpoint_t *hint = &flow->point; /* Find the rejected vertex. */ for (i = 0; i < simplex_size; ++i) { if (test->vertex[i]->id == point->id) break; } if (i == simplex_size) { session_error("Internal error: Could not find rejected point."); return -1; } if (hint && hint->id != -1) { int orig_id = point->id; /* Update our state to include the hint point. */ if (vertex_from_hpoint(hint, test->vertex[i]) != 0) { session_error("Internal error: Could not make vertex from point."); return -1; } if (hpoint_copy(point, hint) != 0) { session_error("Internal error: Could not copy point."); return -1; } point->id = orig_id; } else { if (reject_type == REJECT_METHOD_PENALTY) { /* Apply an infinite penalty to the invalid point and * allow the algorithm to determine the next point to try. */ hperf_reset(test->vertex[i]->perf); ++reported; if (reported == simplex_size) { if (pro_algorithm() != 0) { session_error("Internal error: PRO algorithm failure."); return -1; } reported = 0; send_idx = 0; i = 0; } if (send_idx == simplex_size) { flow->status = HFLOW_WAIT; return 0; } test->vertex[send_idx]->id = next_id; if (vertex_to_hpoint(test->vertex[send_idx], point) != 0) { session_error("Internal error: Could not make point" " from vertex."); return -1; } ++next_id; ++send_idx; } else if (reject_type == REJECT_METHOD_RANDOM) { /* Replace the rejected point with a random point. */ vertex_rand(test->vertex[i]); if (vertex_to_hpoint(test->vertex[i], point) != 0) { session_error("Internal error: Could not make point" " from vertex."); return -1; } } } flow->status = HFLOW_ACCEPT; return 0; }
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; }
int strategy_analyze(htrial_t *trial) { // find the relevant subtrial // for now I'm being dumb about searching the window, because it's small int window_entry; for (window_entry = 0; window_entry < window_size; window_entry++) { if (window[window_entry].point_id == trial->point.id) break; } if (window_entry == window_size) // i'm not responsible for this return 0; // indicate that this point is complete window[window_entry].complete = 1; // track global optimum // TODO use hperf_cmp to make this suitable for multi-objective search if (hperf_unify(trial->perf) < best_perf) { if (hpoint_copy(&best, &trial->point) < 0) { session_error("failed to copy new global optimum"); return -1; } best_perf = hperf_unify(trial->perf); window[window_entry].new_best = 1; } // decrement count of outstanding generates requests_outstanding--; // now pass the result to the sub-strategies // We call strategy_analyze from the strategy that generated the point, // and strategy_hint for all other strategies. Their interfaces are // identical, so a new strategy can just define strategy_hint to call // strategy_analyze if it doesn't need to match with a point it's found. int strategy_id, sub_point_id; sub_point_id = translate_id_to_sub(trial->point.id, &strategy_id); if (strategy_id < 0 || strategy_id >= MAX_NUM_STRATEGIES) { session_error("Invalid strategy ID in strategy_analyze."); return -1; } // call "analyze" for originating strategy // have to bend over backwards to respect "const" qualifier on trial->point // while still giving the substrategy the id it expects htrial_t trial_clone; hpoint_t point_clone; if (hpoint_copy(&point_clone, &trial->point) < 0) { session_error("Failed to copy point for substrategy"); return -1; } point_clone.id = sub_point_id; if (hpoint_copy((hpoint_t *)&trial_clone.point, &point_clone) < 0) { session_error("Failed second point copy for substrategy"); return -1; } trial_clone.perf = trial->perf; // pointer copy; any reason to clone? int result = strategies[strategy_id].analyze(&trial_clone); if (result < 0) return -1; // call "hint" for all others int i; for (i = 0; i < strat_count; i++) if (i != strategy_id) { if (strategies[i].hint(trial) < 0) return -1; } return 0; }
char *call_omega_calc(const char *cmd) { static char *buf = NULL; static int buf_cap = 4096; char *child_argv[2]; char *ptr; pid_t oc_pid; int fd, count; if (buf == NULL) { buf = (char *) malloc(sizeof(char) * buf_cap); if (!buf) return NULL; } child_argv[0] = (char *) omega_bin; child_argv[1] = NULL; fd = socket_launch(omega_bin, child_argv, &oc_pid); if (!fd) { session_error("Could not launch Omega Calculator"); return NULL; } if (socket_write(fd, cmd, strlen(cmd)) < 0) { session_error("Could not send command to Omega Calculator"); return NULL; } if (shutdown(fd, SHUT_WR) != 0) { session_error("Internal error: Could not shutdown write to Omega"); return NULL; } ptr = buf; while ( (count = socket_read(fd, ptr, buf_cap - (buf - ptr))) > 0) { ptr += count; if (ptr == buf + buf_cap) { if (array_grow(&buf, &buf_cap, sizeof(char)) != 0) { session_error("Internal error: Could not grow buffer for" " Omega Calculator input"); return NULL; } ptr = buf + strlen(buf); } *ptr = '\0'; } if (count < 0) { session_error("Could not read output from Omega Calculator"); return NULL; } if (close(fd) != 0) { session_error("Internal error: Could not close Omega socket"); return NULL; } if (waitpid(oc_pid, NULL, 0) != oc_pid) { session_error("Internal error: Could not reap Omega process"); return NULL; } return buf; }
/* XXX - We don't actually update the session signature just yet, * resulting in correct, but less optimal point generation. */ int update_bounds(hsignature_t *sig) { char cmd[MAX_CMD_LEN]; char *retstr; int i, retval; for (i = 0; i < local_sig.range_len; ++i) { hrange_t *range = &local_sig.range[i]; /* Write the domain text with variable constraints to the file */ snprintf(cmd, sizeof(cmd), "symbolic %s;\n" "D:={[%s]: %s && %s};\n" "range D;", range->name, vars_text, bounds_text, user_text); /* Call omega calculator */ retstr = call_omega_calc(cmd); if (!retstr) return -1; /* Parse the result */ while (*retstr) { if (strncmp(">>>", retstr, 3) == 0) goto nextline; /* Skip echo lines. */ switch (range->type) { case HVAL_INT: retval = sscanf(retstr, "{ %ld <= %*s <= %ld }\n", &range->bounds.i.min, &range->bounds.i.max); break; case HVAL_REAL: retval = sscanf(retstr, "{ %lf <= %*s <= %lf }\n", &range->bounds.r.min, &range->bounds.r.max); break; case HVAL_STR: default: session_error("Constraint layer cannot handle string types"); return -1; } if (retval != 2) fprintf(stderr, "Unexpected Omega Calculator output: %.*s\n", (int) strcspn(retstr, "\n"), retstr); break; nextline: retstr += strcspn(retstr, "\n"); if (*retstr) ++retstr; } if (retval != 2) { session_error("Error parsing Omega Calculator output"); return -1; } } if (!quiet) { if (!hsignature_equal(sig, &local_sig)) { fprintf(stderr, "For the given constraints, we suggest re-running" " the session with these bounds:\n"); for (i = 0; i < local_sig.range_len; ++i) { hrange_t *range = &local_sig.range[i]; switch (range->type) { case HVAL_INT: fprintf(stderr, "INT %s = {%ld, %ld, %ld}\n", range->name, range->bounds.i.min, range->bounds.i.max, range->bounds.i.step); break; case HVAL_REAL: fprintf(stderr, "REAL %s = {%lf, %lf, %lf}\n", range->name, range->bounds.r.min, range->bounds.r.max, range->bounds.r.step); break; case HVAL_STR: default: return -1; } } } } return 0; }
int strategy_generate(hflow_t *flow, hpoint_t *point) { double scores[MAX_NUM_STRATEGIES]; // don't let the generates get too far ahead of the analyses; otherwise // we might wind up chasing down a strategy that is doing poorly if (requests_outstanding > MAX_REQUESTS_OUTSTANDING) { flow->status = HFLOW_WAIT; return 0; } int best_strategy = assign_scores(scores); if (best_strategy < 0) { // session_error set below return -1; } // assign_scores tells us which strategy had the highest score. we will // just use that, unless that strategy wants to HFLOW_WAIT. in that case, // we'll go to the second best, and so forth. // I assume strategies won't pay attention to the "point" field in flow. do { int result = strategies[best_strategy].generate(flow, point); if (result < 0) return -1; if (flow->status == HFLOW_WAIT) { // find the next best strategy scores[best_strategy] = -1.0; best_strategy = -1; double best_score = -1.0; int i; for (i = 0; i < strat_count; i++) if (scores[i] > best_score) { best_score = scores[i]; best_strategy = i; } } } while (best_strategy >= 0 && flow->status == HFLOW_WAIT); if (best_strategy < 0) // all strategies want to wait, so we will. return 0; // best_strategy has generated a point. we modify the id so we can remember // who is responsible for it. point->id = translate_id_from_sub(best_strategy, point->id); if (point->id < 0) return -1; // save the request in the window if (window_next < 0 || window_next >= window_size || window_next > window_population) { session_error("Invalid window_next value."); return -1; } subtrial_t *subtrial = window + window_next; subtrial->strategy_id = best_strategy; subtrial->point_id = point->id; subtrial->complete = subtrial->new_best = 0; window_next++; if (window_next == window_size) window_next = 0; if (window_population < window_size) window_population++; requests_outstanding++; return 0; }
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; }
/* * 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; }