Esempio n. 1
0
int harmony_fetch(hdesc_t *hdesc)
{
    int i;

    if (hdesc->state < HARMONY_STATE_CONNECTED) {
        hdesc->errstr = "Descriptor not currently joined to any session.";
        errno = EINVAL;
        return -1;
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);

    if (send_request(hdesc, HMESG_FETCH) != 0)
        return -1;

    if (hdesc->mesg.status == HMESG_STATUS_BUSY) {
        if (update_best(hdesc, &hdesc->mesg.data.point) != 0)
            return -1;

        if (hdesc->best.id == -1) {
            /* No best point is available. Inform the user by returning 0. */
            return 0;
        }

        /* Set current point to best point. */
        if (hpoint_copy(&hdesc->curr, &hdesc->best) != 0) {
            hdesc->errstr = "Internal error copying point data.";
            errno = EINVAL;
            return -1;
        }
    }
    else if (hdesc->mesg.status == HMESG_STATUS_OK) {
        if (hpoint_copy(&hdesc->curr, &hdesc->mesg.data.point) != 0) {
            hdesc->errstr = "Internal error copying point data.";
            errno = EINVAL;
            return -1;
        }
    }
    else {
        hdesc->errstr = "Invalid message received from server.";
        errno = EINVAL;
        return -1;
    }

    /* Update the variables from the content of the message. */
    if (set_values(hdesc, &hdesc->curr) != 0)
        return -1;

    /* Initialize our internal performance array. */
    for (i = 0; i < hdesc->perf->n; ++i)
        hdesc->perf->p[i] = NAN;

    /* Client variables were changed.  Inform the user by returning 1. */
    hdesc->state = HARMONY_STATE_TESTING;
    return 1;
}
Esempio n. 2
0
/*
 * 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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
int update_best(hdesc_t *hdesc, const hpoint_t *pt)
{
    if (hdesc->best.id >= pt->id)
        return 0;

    if (hpoint_copy(&hdesc->best, pt) != 0) {
        hdesc->errstr = "Internal error copying point data.";
        errno = EINVAL;
        return -1;
    }
    return 0;
}
Esempio n. 6
0
int cglog_insert(const hpoint_t *point)
{
    if (cglog_len == cglog_cap)
        if (array_grow(&cglog, &cglog_cap, sizeof(codegen_log_t)) < 0)
            return -1;

    cglog[cglog_len].point = HPOINT_INITIALIZER;
    hpoint_copy(&cglog[cglog_len].point, point);
    cglog[cglog_len].status = CODEGEN_STATUS_REQUESTED;
    ++cglog_len;

    return 0;
}
Esempio n. 7
0
/*
 * 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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}