- remote job submission: bug fix and tweaks

- client: cc_config.xml: if <devnum> is omitted from a <exclude_gpu>,
    it means exclude all instances of that GPU type
- client: if all instances of a GPU type are excluded for a project,
    don't ask the project for jobs of that type


svn path=/trunk/boinc/; revision=23898
This commit is contained in:
David Anderson 2011-07-29 00:07:20 +00:00
parent c9e44ce0bc
commit 5b159c6735
13 changed files with 112 additions and 41 deletions

View File

@ -4421,3 +4421,26 @@ Charlie 28 July 11
clientscr/
Mac_Saver_ModuleView.m
David 28 July 2011
- remote job submission: bug fix and tweaks
- client: cc_config.xml: if <devnum> is omitted from a <exclude_gpu>,
it means exclude all instances of that GPU type
- client: if all instances of a GPU type are excluded for a project,
don't ask the project for jobs of that type
html/
ops/
submit_permissions.php
inc/
util.h
user/
submit_example.php
lib/
cc_config.cpp,h
client/
work_fetch.cpp,h
client_types.cpp,h
client_state.cpp
gui_rpc_server_ops.cpp
cpu_sched.cpp

View File

@ -210,15 +210,6 @@ const char* rsc_name(int i) {
return coprocs.coprocs[i].type;
}
void init_exclude_gpu() {
for (unsigned int i=0; i<config.exclude_gpus.size(); i++) {
EXCLUDE_GPU& eg = config.exclude_gpus[i];
PROJECT* p = gstate.lookup_project(eg.url.c_str());
if (!p) continue;
p->exclude_gpus.push_back(eg);
}
}
// set no_X_apps for anonymous platform project
//
static void check_no_apps(PROJECT* p) {
@ -417,6 +408,8 @@ int CLIENT_STATE::init() {
}
}
set_no_rsc_config();
// check for app_info.xml file in project dirs.
// If find, read app info from there, set project.anonymous_platform
// - this must follow coproc.get() (need to know if GPUs are present)
@ -628,10 +621,6 @@ int CLIENT_STATE::init() {
//
check_too_large_jobs();
// fill in exclude-GPU flags
//
init_exclude_gpu();
project_priority_init();
initialized = true;

View File

@ -67,11 +67,11 @@ void PROJECT::init() {
resource_share = 100;
for (int i=0; i<MAX_RSC; i++) {
no_rsc_pref[i] = false;
no_rsc_config[i] = false;
no_rsc_apps[i] = false;
no_rsc_ams[i] = false;
rsc_defer_sched[i] = false;
}
exclude_gpus.clear();
strcpy(host_venue, "");
using_venue_specific_prefs = false;
scheduler_urls.clear();

View File

@ -254,9 +254,10 @@ struct PROJECT : PROJ_AM {
//
bool no_rsc_pref[MAX_RSC];
// list of GPUs not to use for this project
// derived from GPU exclusions in cc_config.xml;
// disable work fetch if all instances excluded
//
std::vector<EXCLUDE_GPU> exclude_gpus;
bool no_rsc_config[MAX_RSC];
// the following are from the project itself
// (or derived from app version list if anonymous platform)

View File

@ -1123,11 +1123,12 @@ void CLIENT_STATE::append_unfinished_time_slice(vector<RESULT*> &run_list) {
static inline bool excluded(RESULT* rp, COPROC* cp, int ind) {
PROJECT* p = rp->project;
for (unsigned int i=0; i<p->exclude_gpus.size(); i++) {
EXCLUDE_GPU& eg = p->exclude_gpus[i];
for (unsigned int i=0; i<config.exclude_gpus.size(); i++) {
EXCLUDE_GPU& eg = config.exclude_gpus[i];
if (strcmp(eg.url.c_str(), p->master_url)) continue;
if (!eg.type.empty() && (eg.type != cp->type)) continue;
if (!eg.appname.empty() && (eg.appname != rp->app->name)) continue;
if (eg.devnum != cp->device_nums[ind]) continue;
if (eg.devnum >= 0 && eg.devnum != cp->device_nums[ind]) continue;
return true;
}
return false;

View File

@ -1217,6 +1217,7 @@ int GUI_RPC_CONN::handle_rpc() {
gstate.set_ncpus();
gstate.request_schedule_cpus("Core client configuration");
gstate.request_work_fetch("Core client configuration");
set_no_rsc_config();
} else if (match_req(request_msg, "get_notices")) {
handle_get_notices(request_msg, *this, mf, false);
clear_notice_refresh();

View File

@ -67,11 +67,47 @@ static const char* criterion_name(int criterion) {
inline bool dont_fetch(PROJECT* p, int rsc_type) {
if (p->no_rsc_pref[rsc_type]) return true;
if (p->no_rsc_config[rsc_type]) return true;
if (p->no_rsc_apps[rsc_type]) return true;
if (p->no_rsc_ams[rsc_type]) return true;
return false;
}
// if the configuration file disallows the use of a GPU type
// for a project, set a flag to that effect
//
void set_no_rsc_config() {
for (unsigned int i=0; i<gstate.projects.size(); i++) {
PROJECT& p = *gstate.projects[i];
for (int j=1; j<coprocs.n_rsc; j++) {
bool allowed[MAX_COPROC_INSTANCES];
memset(allowed, 0, sizeof(allowed));
COPROC& c = coprocs.coprocs[j];
for (int k=0; k<c.count; k++) {
allowed[c.device_nums[k]] = true;
}
for (unsigned int k=0; k<config.exclude_gpus.size(); k++) {
EXCLUDE_GPU& e = config.exclude_gpus[k];
if (strcmp(e.url.c_str(), p.master_url)) continue;
if (strcmp(e.type.c_str(), c.type)) continue;
if (!e.appname.empty()) continue;
if (e.devnum < 0) {
memset(allowed, 0, sizeof(allowed));
break;
}
allowed[e.devnum] = false;
}
p.no_rsc_config[j] = true;
for (int k=0; k<c.count; k++) {
if (allowed[k]) {
p.no_rsc_config[j] = false;
break;
}
}
}
}
}
// does the project have a downloading or runnable job?
//
static bool has_a_job(PROJECT* p) {
@ -436,12 +472,13 @@ void RSC_WORK_FETCH::print_state(const char* name) {
if (p->non_cpu_intensive) continue;
RSC_PROJECT_WORK_FETCH& pwf = project_state(p);
bool no_rsc_pref = p->no_rsc_pref[rsc_type];
bool no_rsc_config = p->no_rsc_config[rsc_type];
bool no_rsc_apps = p->no_rsc_apps[rsc_type];
bool no_rsc_ams = p->no_rsc_ams[rsc_type];
double bt = pwf.backoff_time>gstate.now?pwf.backoff_time-gstate.now:0;
if (use_rec) {
msg_printf(p, MSG_INFO,
"[work_fetch] %s: fetch share %.2f rec %.5f prio %.5f backoff dt %.2f int %.2f%s%s%s%s%s%s%s%s",
"[work_fetch] %s: fetch share %.2f rec %.5f prio %.5f backoff dt %.2f int %.2f%s%s%s%s%s%s%s%s%s",
name,
pwf.fetchable_share, p->pwf.rec, project_priority(p), bt, pwf.backoff_interval,
p->suspended_via_gui?" (susp via GUI)":"",
@ -451,11 +488,12 @@ if (use_rec) {
p->too_many_uploading_results?" (too many uploads)":"",
no_rsc_pref?" (blocked by prefs)":"",
no_rsc_apps?" (no apps)":"",
no_rsc_ams?" (blocked by account manager)":""
no_rsc_ams?" (blocked by account manager)":"",
no_rsc_config?" (blocked by configuration file)":""
);
} else {
msg_printf(p, MSG_INFO,
"[work_fetch] %s: fetch share %.2f LTD %.2f backoff dt %.2f int %.2f%s%s%s%s%s%s%s",
"[work_fetch] %s: fetch share %.2f LTD %.2f backoff dt %.2f int %.2f%s%s%s%s%s%s%s%s",
name,
pwf.fetchable_share, pwf.long_term_debt, bt, pwf.backoff_interval,
p->suspended_via_gui?" (susp via GUI)":"",
@ -464,7 +502,8 @@ if (use_rec) {
p->dont_request_more_work?" (no new tasks)":"",
pwf.overworked()?" (overworked)":"",
p->too_many_uploading_results?" (too many uploads)":"",
no_rsc_pref?" (blocked by prefs)":""
no_rsc_pref?" (blocked by prefs)":"",
no_rsc_config?" (blocked by configuration file)":""
);
}
}

View File

@ -303,6 +303,8 @@ struct WORK_FETCH {
extern RSC_WORK_FETCH rsc_work_fetch[MAX_RSC];
extern WORK_FETCH work_fetch;
extern void set_no_rsc_config();
//#ifdef USE_REC
void project_priority_init();
double project_priority(PROJECT*);

View File

@ -261,7 +261,7 @@ function time_str($x) {
function local_time_str($x) {
if ($x == 0) return "---";
return date('j M Y | H:i:s', $x);
return date('j M Y, H:i T', $x);
}
function pretty_time_str($x) {

View File

@ -127,7 +127,8 @@ function handle_edit_action() {
function handle_add_form() {
admin_page_head("Add user");
echo "
<form action=submit_permissions.php?action=add_action>
<form action=submit_permissions.php>
<input type=hidden name=action value=add_action>
User ID: <input name=user_id>
<br>
<input type=submit value=OK>

View File

@ -51,7 +51,6 @@ function handle_main() {
page_head("Job submission and control");
echo date("F j, Y, g:i a");
show_button("submit_example.php?action=create_form", "Create new batch");
$first = true;
@ -73,7 +72,9 @@ function handle_main() {
local_time_str($batch->create_time)
);
}
if (!$first) {
if ($first) {
echo "<p>You have no in-progress batches.\n";
} else {
end_table();
}
@ -82,7 +83,7 @@ function handle_main() {
if ($batch->state != BATCH_STATE_COMPLETE) continue;
if ($first) {
$first = false;
echo "<h2>Completed</h2>\n";
echo "<h2>Completed batches</h2>\n";
start_table();
table_header("name", "ID", "# jobs", "submitted");
}
@ -93,7 +94,9 @@ function handle_main() {
local_time_str($batch->create_time)
);
}
if (!$first) {
if ($first) {
echo "<p>You have no completed batches.\n";
} else {
end_table();
}
@ -102,7 +105,7 @@ function handle_main() {
if ($batch->state != BATCH_STATE_ABORTED) continue;
if ($first) {
$first = false;
echo "<h2>Aborted</h2>\n";
echo "<h2>Aborted batches</h2>\n";
start_table();
table_header("name", "ID", "# jobs", "submitted");
}
@ -243,8 +246,6 @@ function handle_query_batch() {
if ($errmsg) error_page($errmsg);
page_head("Batch $req->batch_id");
$url = boinc_get_output_files($req);
show_button($url, "Get zipped output files");
start_table();
row2("name", $batch->name);
row2("application", $batch->app_name);
@ -259,6 +260,8 @@ function handle_query_batch() {
row2("Credit, canonical instances", $batch->credit_canonical);
row2("Credit, total", $batch->credit_total);
end_table();
$url = boinc_get_output_files($req);
show_button($url, "Get zipped output files");
switch ($batch->state) {
case BATCH_STATE_IN_PROGRESS:
echo "<br>";
@ -279,17 +282,25 @@ function handle_query_batch() {
echo "<h2>Jobs</h2>\n";
start_table();
table_header("Job ID", "Canonical instance");
table_header(
"Job ID<br><span class=note>click for details or to get output files</span>",
"status",
"Canonical instance<br><span class=note>click to see result page on BOINC server</span>"
);
foreach($batch->jobs as $job) {
$id = (int)$job->id;
$resultid = (int)$job->canonical_instance_id;
if ($resultid) {
$x = "<a href=result.php?resultid=$resultid>$resultid</a>";
$y = "completed";
} else {
$x = "---";
$y = "in progress";
}
echo "<tr>
<td><a href=submit_example.php?action=query_job&job_id=$id>$id</a></td>
<td>$y</td>
<td>$x</td>
</tr>
";
@ -307,8 +318,13 @@ function handle_query_job() {
if ($errmsg) error_page($errmsg);
page_head("Job $req->job_id");
echo "<a href=$project/workunit.php?wuid=$req->job_id>View workunit page on BOINC server</a>\n";
echo "<h2>Instances</h2>\n";
start_table();
table_header("Instance ID", "State", "Output files");
table_header(
"Instance ID<br><span class=note>click for result page on BOINC server</span>",
"State", "Output files"
);
foreach($reply->instances as $inst) {
echo "<tr>
<td><a href=result.php?resultid=$inst->id>$inst->id</a></td>

View File

@ -238,24 +238,21 @@ void CONFIG::defaults() {
static bool parse_exclude_gpu(XML_PARSER& xp, EXCLUDE_GPU& eg) {
char tag[1024];
bool is_tag;
bool found_devnum = false;
bool found_url = false;
eg.type = "";
eg.appname = "";
eg.devnum = -1;
while (!xp.get(tag, sizeof(tag), is_tag)) {
if (!is_tag) continue;
if (!strcmp(tag, "/exclude_gpu")) {
return (found_devnum && found_url);
}
if (xp.parse_int(tag, "devnum", eg.devnum)) {
found_devnum = true;
continue;
return found_url;
}
if (xp.parse_string(tag, "url", eg.url)) {
canonicalize_master_url(eg.url);
found_url = true;
continue;
}
if (xp.parse_int(tag, "devnum", eg.devnum)) continue;
if (xp.parse_string(tag, "type", eg.type)) continue;
if (xp.parse_string(tag, "app", eg.appname)) continue;
}
@ -278,6 +275,7 @@ int CONFIG::parse_options(XML_PARSER& xp) {
exclusive_gpu_apps.clear();
ignore_nvidia_dev.clear();
ignore_ati_dev.clear();
exclude_gpus.clear();
while (!xp.get(tag, sizeof(tag), is_tag)) {
if (!is_tag) {

View File

@ -116,7 +116,7 @@ struct EXCLUDE_GPU {
std::string url;
std::string type;
std::string appname;
int devnum;
int devnum; // -1 means all
};
// if you add anything, you must add it to