- scheduler and back end: add new fields to result table:

elapsed_time: the elapsed time (runtime) as reported by client
    flops_estimate: the app's estimated FLOPS as reported by app_plan()
    app_version_id: the DB ID of the app_version used
        (or -1 if anonymous platform)
    TODO: show these in the web interfaces,
    and use them where appropriate

svn path=/trunk/boinc/; revision=19002
This commit is contained in:
David Anderson 2009-09-03 20:26:31 +00:00
parent f3954476d6
commit da7e82fe15
8 changed files with 90 additions and 37 deletions

View File

@ -7494,3 +7494,22 @@ David 2 Sept 2009
client/
cpu_sched.cpp
David 3 Sept 2009
- scheduler and back end: add new fields to result table:
elapsed_time: the elapsed time (runtime) as reported by client
flops_estimate: the app's estimated FLOPS as reported by app_plan()
app_version_id: the DB ID of the app_version used
(or -1 if anonymous platform)
TODO: show these in the web interfaces,
and use them where appropriate
db/
boinc_db.cpp,h
schema.sql
html/ops/
db_update.php
sched/
sched_result.cpp
sched_send.cpp
sched_types.cpp

View File

@ -661,7 +661,7 @@ void DB_WORKUNIT::db_print(char* buf){
"max_total_results=%d, max_success_results=%d, "
"result_template_file='%s', "
"priority=%d, "
"rsc_bandwidth_bound=%.15e ",
"rsc_bandwidth_bound=%.15e ",
create_time, appid,
name, xml_doc, batch,
rsc_fpops_est, rsc_fpops_bound, rsc_memory_bound, rsc_disk_bound,
@ -743,7 +743,8 @@ void DB_RESULT::db_print(char* buf){
"batch=%d, file_delete_state=%d, validate_state=%d, "
"claimed_credit=%.15e, granted_credit=%.15e, opaque=%f, random=%d, "
"app_version_num=%d, appid=%d, exit_status=%d, teamid=%d, "
"priority=%d, mod_time=null",
"priority=%d, mod_time=null, elapsed_time=%f, flops_estimate=%f, "
"app_version_id=%d",
create_time, workunitid,
server_state, outcome, client_state,
hostid, userid,
@ -753,7 +754,7 @@ void DB_RESULT::db_print(char* buf){
batch, file_delete_state, validate_state,
claimed_credit, granted_credit, opaque, random,
app_version_num, appid, exit_status, teamid,
priority
priority, elapsed_time, flops_estimate, app_version_id
);
UNESCAPE(xml_doc_out);
UNESCAPE(stderr_out);
@ -774,7 +775,7 @@ void DB_RESULT::db_print_values(char* buf){
"'%s', '%s', '%s', "
"%d, %d, %d, "
"%.15e, %.15e, %f, %d, "
"%d, %d, %d, %d, %d, null)",
"%d, %d, %d, %d, %d, null, 0, 0, 0)",
create_time, workunitid,
server_state, outcome, client_state,
hostid, userid,
@ -798,9 +799,10 @@ int DB_RESULT::mark_as_sent(int old_server_state) {
int retval;
sprintf(query,
"update result set server_state=%d, hostid=%d, userid=%d, sent_time=%d, report_deadline=%d where id=%d and server_state=%d",
server_state, hostid, userid, sent_time, report_deadline, id,
old_server_state
"update result set server_state=%d, hostid=%d, userid=%d, sent_time=%d, report_deadline=%d, flops_estimate=%f, app_version_id=%d where id=%d and server_state=%d",
server_state, hostid, userid, sent_time, report_deadline,
flops_estimate, app_version_id,
id, old_server_state
);
retval = db->do_query(query);
if (retval) return retval;
@ -840,6 +842,9 @@ void DB_RESULT::db_parse(MYSQL_ROW &r) {
teamid = atoi(r[i++]);
priority = atoi(r[i++]);
strcpy2(mod_time, r[i++]);
elapsed_time = atof(r[i++]);
flops_estimate = atof(r[i++]);
app_version_id = atoi(r[i++]);
}
void DB_MSG_FROM_HOST::db_print(char* buf) {
@ -998,9 +1003,9 @@ void DB_CREDIT_MULTIPLIER::get_nearest(int _appid, int t) {
snprintf(query,MAX_QUERY_LEN,
"select * from credit_multiplier where appid=%d and "
"abs(time-%d)=("
"select min(abs(time-%d)) from credit_multiplier where appid=%d"
") limit 1",
"abs(time-%d)=("
"select min(abs(time-%d)) from credit_multiplier where appid=%d"
") limit 1",
appid, t, t, appid
);
if (db->do_query(query) != 0) return;
@ -1175,7 +1180,9 @@ int DB_TRANSITIONER_ITEM_SET::update_result(TRANSITIONER_ITEM& ti) {
ti.res_file_delete_state,
ti.res_id
);
return db->do_query(query);
int retval = db->do_query(query);
if (db->affected_rows() != 1) return ERR_DB_NOT_FOUND;
return retval;
}
int DB_TRANSITIONER_ITEM_SET::update_workunit(
@ -1386,7 +1393,9 @@ int DB_VALIDATOR_ITEM_SET::update_result(RESULT& res) {
res.opaque,
res.id
);
return db->do_query(query);
int retval = db->do_query(query);
if (db->affected_rows() != 1) return ERR_DB_NOT_FOUND;
return retval;
}
@ -1407,7 +1416,9 @@ int DB_VALIDATOR_ITEM_SET::update_workunit(WORKUNIT& wu) {
wu.canonical_credit,
wu.id
);
return db->do_query(query);
int retval = db->do_query(query);
if (db->affected_rows() != 1) return ERR_DB_NOT_FOUND;
return retval;
}
void WORK_ITEM::parse(MYSQL_ROW& r) {
@ -1626,7 +1637,7 @@ int DB_SCHED_RESULT_ITEM_SET::enumerate() {
" id, "
" name, "
" workunitid, "
" appid, "
" appid, "
" server_state, "
" hostid, "
" userid, "
@ -1706,7 +1717,8 @@ int DB_SCHED_RESULT_ITEM_SET::update_result(SCHED_RESULT_ITEM& ri) {
" stderr_out='%s', "
" xml_doc_out='%s', "
" validate_state=%d, "
" teamid=%d "
" teamid=%d, "
" elapsed_time=%f "
"WHERE "
" id=%d",
ri.hostid,
@ -1722,11 +1734,13 @@ int DB_SCHED_RESULT_ITEM_SET::update_result(SCHED_RESULT_ITEM& ri) {
ri.xml_doc_out,
ri.validate_state,
ri.teamid,
ri.elapsed_time,
ri.id
);
retval = db->do_query(query);
UNESCAPE(ri.xml_doc_out);
UNESCAPE(ri.stderr_out);
if (db->affected_rows() != 1) return ERR_DB_NOT_FOUND;
return retval;
}

View File

@ -475,8 +475,6 @@ struct RESULT {
int received_time; // when result was received from host
char name[256];
double cpu_time; // CPU time used to complete result
// NOTE: with the current scheduler and client,
// this is elapsed time, not the CPU time
char xml_doc_in[BLOB_SIZE]; // descriptions of output files
char xml_doc_out[BLOB_SIZE]; // MD5s of output files
char stderr_out[BLOB_SIZE]; // stderr output, if any
@ -493,6 +491,9 @@ struct RESULT {
int teamid;
int priority;
char mod_time[16];
double elapsed_time; // AKA runtime
double flops_estimate; // as returned by app_plan()
int app_version_id; // or -1 if anonymous platform
// the following used by the scheduler, but not stored in the DB
//
@ -844,6 +845,7 @@ struct SCHED_RESULT_ITEM {
int app_version_num;
int exit_status;
int file_delete_state;
double elapsed_time;
void clear();
void parse(MYSQL_ROW& row);

View File

@ -247,6 +247,9 @@ create table result (
teamid integer not null,
priority integer not null,
mod_time timestamp,
elapsed_time double not null,
flops_estimate double not null,
app_version_id integer not null,
primary key (id)
) engine=InnoDB;

View File

@ -646,6 +646,18 @@ function update_6_16_2009() {
}
function update_9_3_2009() {
do_query("alter table result add (
elapsed_time double not null,
flops_estimate double not null,
app_version_id integer not null
)
");
}
// Updates are done automatically if you use "upgrade".
//
// If you need to do updates manually,
// modify the following to call the function you want.
// Make sure you do all needed functions, in order.
// (Look at your DB structure using "explain" queries to see
@ -655,6 +667,7 @@ function update_6_16_2009() {
$db_updates = array (
array(18490, "update_6_16_2009"),
array(19001, "update_9_3_2009"),
);
?>

View File

@ -69,14 +69,16 @@ int handle_results() {
}
// read results from database into "result_handler".
//
// Quantities that must be read from the DB are those
// where srip (see below) appears as an rval.
// These are: id, name, server_state, received_time, hostid, validate_state.
//
// Quantities that must be written to the DB are those for
// which srip appears as an lval. These are:
// hostid, teamid, received_time, client_state, cpu_time, exit_status,
// app_version_num, claimed_credit, server_state, stderr_out,
// xml_doc_out, outcome, validate_state
// xml_doc_out, outcome, validate_state, elapsed_time
//
retval = result_handler.enumerate();
if (retval) {
@ -240,26 +242,31 @@ int handle_results() {
srip->received_time = time(0);
srip->client_state = rp->client_state;
srip->cpu_time = rp->cpu_time;
srip->elapsed_time = rp->elapsed_time;
// check for impossible CPU time
//
double elapsed_time = srip->received_time - srip->sent_time;
if (elapsed_time < 0) {
double turnaround_time = srip->received_time - srip->sent_time;
if (turnaround_time < 0) {
log_messages.printf(MSG_NORMAL,
"[HOST#%d] [RESULT#%d] [WU#%d] inconsistent sent/received times\n", srip->hostid, srip->id, srip->workunitid
);
} else {
if (srip->cpu_time > elapsed_time) {
if (srip->elapsed_time > turnaround_time) {
log_messages.printf(MSG_NORMAL,
"[HOST#%d] [RESULT#%d] [WU#%d] excessive CPU time: reported %f > elapsed %f%s\n",
srip->hostid, srip->id, srip->workunitid, srip->cpu_time, elapsed_time, changed_host?" [OK: HOST changed]":""
"[HOST#%d] [RESULT#%d] [WU#%d] excessive elapsed time: reported %f > elapsed %f%s\n",
srip->hostid, srip->id, srip->workunitid,
srip->elapsed_time, turnaround_time,
changed_host?" [OK: HOST changed]":""
);
if (!changed_host) srip->cpu_time = elapsed_time;
}
}
srip->exit_status = rp->exit_status;
srip->app_version_num = rp->app_version_num;
// TODO: this is outdated, and doesn't belong here
if (rp->fpops_cumulative || rp->intops_cumulative) {
srip->claimed_credit = fpops_to_credit(rp->fpops_cumulative, rp->intops_cumulative);
} else if (rp->fpops_per_cpu_sec || rp->intops_per_cpu_sec) {

View File

@ -1028,6 +1028,12 @@ int add_result_to_reply(
result.userid = g_reply->user.id;
result.sent_time = time(0);
result.report_deadline = result.sent_time + wu.delay_bound;
result.flops_estimate = bavp->host_usage.flops;
if (bavp->avp) {
result.app_version_id = bavp->avp->id;
} else {
result.app_version_id = -1;
}
int old_server_state = result.server_state;
if (result.server_state != RESULT_SERVER_STATE_IN_PROGRESS) {

View File

@ -981,29 +981,18 @@ int RESULT::write_to_client(FILE* fout) {
int RESULT::parse_from_client(FILE* fin) {
char buf[256];
double final_cpu_time = 0, final_elapsed_time = 0;
// should be non-zero if exit_status is not found
exit_status = ERR_NO_EXIT_STATUS;
memset(this, 0, sizeof(RESULT));
while (fgets(buf, sizeof(buf), fin)) {
if (match_tag(buf, "</result>")) {
// newer clients (>6.6.15) report final elapsed time;
// use it if possible
//
// actually, let's hold off on this
//if (final_elapsed_time) {
// cpu_time = final_elapsed_time;
//} else {
cpu_time = final_cpu_time;
//}
return 0;
}
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
if (parse_int(buf, "<state>", client_state)) continue;
if (parse_double(buf, "<final_cpu_time>", final_cpu_time)) continue;
if (parse_double(buf, "<final_elapsed_time>", final_elapsed_time)) continue;
if (parse_double(buf, "<final_cpu_time>", cpu_time)) continue;
if (parse_double(buf, "<final_elapsed_time>", elapsed_time)) continue;
if (parse_int(buf, "<exit_status>", exit_status)) continue;
if (parse_int(buf, "<app_version_num>", app_version_num)) continue;
if (parse_double(buf, "<fpops_per_cpu_sec>", fpops_per_cpu_sec)) continue;