mirror of https://github.com/BOINC/boinc.git
- scheduler: add <max_ncpus> config option.
Use this with N=1 if your application primarily uses a coprocessor svn path=/trunk/boinc/; revision=14772
This commit is contained in:
parent
3ce02d1a2b
commit
79f6720547
|
@ -1543,3 +1543,10 @@ Rom Feb 21 2008
|
||||||
curl/
|
curl/
|
||||||
<Various Files>
|
<Various Files>
|
||||||
|
|
||||||
|
David Feb 21 2008
|
||||||
|
- scheduler: add <max_ncpus> config option.
|
||||||
|
Use this with N=1 if your application primarily uses a coprocessor
|
||||||
|
|
||||||
|
sched/
|
||||||
|
sched_config.C,h
|
||||||
|
sched_send.C
|
||||||
|
|
|
@ -21,6 +21,7 @@ $spoken_languages = array(
|
||||||
'English',
|
'English',
|
||||||
'French',
|
'French',
|
||||||
'German',
|
'German',
|
||||||
|
'Greek',
|
||||||
'Gujarati',
|
'Gujarati',
|
||||||
'Hausa',
|
'Hausa',
|
||||||
'Hindi',
|
'Hindi',
|
||||||
|
|
|
@ -4,23 +4,28 @@ require_once("../inc/bolt_db.inc");
|
||||||
require_once("../inc/util_ops.inc");
|
require_once("../inc/util_ops.inc");
|
||||||
|
|
||||||
function show_course($course) {
|
function show_course($course) {
|
||||||
echo "<tr>
|
$x = "<b>$course->name</b>
|
||||||
<td>Name: $course->name<br>Description: $course->description<br>Created: ".date_str($course->create_time)."</td>
|
<br>Description: $course->description
|
||||||
<td>$course->doc_file</td>
|
<br>Created: ".date_str($course->create_time)."
|
||||||
<td>
|
<br>Course document: $course->doc_file
|
||||||
";
|
";
|
||||||
|
$y = "<a href=bolt_map.php?course_id=$course->id>Course map</a>
|
||||||
|
<br><a href=bolt_compare.php?course_id=$course->id>Lesson compare</a>
|
||||||
|
<br>
|
||||||
|
";
|
||||||
|
row2_init($x, $y);
|
||||||
if ($course->hidden) {
|
if ($course->hidden) {
|
||||||
show_button("bolt_admin.php?action=unhide&course_id=$course->id", "Unhide", "Unhide this course");
|
show_button("bolt_admin.php?action=unhide&course_id=$course->id", "Unhide", "Unhide this course");
|
||||||
} else {
|
} else {
|
||||||
show_button("bolt_admin.php?action=hide&course_id=$course->id", "Hide", "Hide this course");
|
show_button("bolt_admin.php?action=hide&course_id=$course->id", "Hide", "Hide this course");
|
||||||
}
|
}
|
||||||
|
echo "</td></tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_courses() {
|
function show_courses() {
|
||||||
$courses = BoltCourse::enum();
|
$courses = BoltCourse::enum();
|
||||||
start_table();
|
start_table();
|
||||||
row1("Existing courses", 3);
|
table_header("Course", "Tools");
|
||||||
table_header("Name/description", "Course document", "");
|
|
||||||
foreach ($courses as $course) {
|
foreach ($courses as $course) {
|
||||||
show_course($course);
|
show_course($course);
|
||||||
}
|
}
|
||||||
|
@ -30,14 +35,15 @@ function show_courses() {
|
||||||
function add_course_form() {
|
function add_course_form() {
|
||||||
echo "
|
echo "
|
||||||
<form action=bolt_admin.php method=get>
|
<form action=bolt_admin.php method=get>
|
||||||
|
<input type=hidden name=action value=add_course>
|
||||||
";
|
";
|
||||||
start_table();
|
start_table();
|
||||||
row1("Add course");
|
row1("Add course");
|
||||||
row2("Name<span class=note><br>Visible to users</span>", "<input name=course_name>");
|
row2("Course name<span class=note><br>Visible to users</span>", "<input name=course_name>");
|
||||||
row2("Internal name<span class=note><br>Not visible to users; used as a directory name, so no spaces or special chars</span>", "<input name=short_name>");
|
row2("Internal name<span class=note><br>Not visible to users; used as a directory name, so no spaces or special chars</span>", "<input name=short_name>");
|
||||||
row2("Description<span class=note><br>Visible to users</span>", "<textarea name=description cols=60></textarea>");
|
row2("Description<span class=note><br>Visible to users</span>", "<textarea name=description cols=60></textarea>");
|
||||||
row2("Course document", "<input name=doc_file>");
|
row2("Course document", "<input name=doc_file>");
|
||||||
row2("", "<input type=submit name=submit value=\"Create course\">");
|
row2("", "<input type=submit name=submit value=\"Add course\">");
|
||||||
end_table();
|
end_table();
|
||||||
echo "</form>";
|
echo "</form>";
|
||||||
}
|
}
|
||||||
|
@ -45,14 +51,16 @@ function add_course_form() {
|
||||||
function user_settings() {
|
function user_settings() {
|
||||||
global $user;
|
global $user;
|
||||||
$flags = $user->bolt->flags;
|
$flags = $user->bolt->flags;
|
||||||
echo "<form action=bolt_admin.php method=get>";
|
echo "<form action=bolt_admin.php method=get>
|
||||||
|
<input type=hidden name=action value=update_user>
|
||||||
|
";
|
||||||
start_table();
|
start_table();
|
||||||
row1("User settings");
|
row1("User settings");
|
||||||
$x = ($flags&BOLT_FLAGS_SHOW_ALL)?"checked":"";
|
$x = ($flags&BOLT_FLAGS_SHOW_ALL)?"checked":"";
|
||||||
row2("Show hidden courses?", "<input type=checkbox name=show_all $x>");
|
row2("Show hidden courses?", "<input type=checkbox name=show_all $x>");
|
||||||
$x = ($flags&BOLT_FLAGS_DEBUG)?"checked":"";
|
$x = ($flags&BOLT_FLAGS_DEBUG)?"checked":"";
|
||||||
row2("Show debugging output?", "<input type=checkbox name=debug $x>");
|
row2("Show debugging output?", "<input type=checkbox name=debug $x>");
|
||||||
row2("", "<input type=submit name=submit value=\"Update user\">");
|
row2("", "<input type=submit name=submit value=\"Update settings\">");
|
||||||
end_table();
|
end_table();
|
||||||
echo "</form>";
|
echo "</form>";
|
||||||
}
|
}
|
||||||
|
@ -60,18 +68,27 @@ function user_settings() {
|
||||||
function show_all() {
|
function show_all() {
|
||||||
admin_page_head("Bolt course administration");
|
admin_page_head("Bolt course administration");
|
||||||
show_courses();
|
show_courses();
|
||||||
echo "<p>";
|
echo "<p>
|
||||||
add_course_form();
|
<a href=bolt_admin.php?action=add_course_form>Add course</a>
|
||||||
echo "<p>";
|
<p>
|
||||||
user_settings();
|
<a href=bolt_admin.php?action=update_user_form>User settings</a>
|
||||||
|
";
|
||||||
admin_page_tail();
|
admin_page_tail();
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = get_logged_in_user();
|
$user = get_logged_in_user();
|
||||||
BoltUser::lookup($user);
|
BoltUser::lookup($user);
|
||||||
|
$course_id = get_int('course_id', true);
|
||||||
|
if ($course_id) $course = BoltCourse::lookup_id($course_id);
|
||||||
|
|
||||||
$submit = get_str('submit', true);
|
$action = get_str('action', true);
|
||||||
if ($submit == 'Create course') {
|
switch ($action) {
|
||||||
|
case 'add_course_form':
|
||||||
|
admin_page_head("Add course");
|
||||||
|
add_course_form();
|
||||||
|
admin_page_tail();
|
||||||
|
break;
|
||||||
|
case 'add_course':
|
||||||
$short_name = BoltDb::escape_string(get_str('short_name'));
|
$short_name = BoltDb::escape_string(get_str('short_name'));
|
||||||
$name = BoltDb::escape_string(get_str('course_name'));
|
$name = BoltDb::escape_string(get_str('course_name'));
|
||||||
$description = BoltDb::escape_string(get_str('description'));
|
$description = BoltDb::escape_string(get_str('description'));
|
||||||
|
@ -79,36 +96,36 @@ if ($submit == 'Create course') {
|
||||||
$now = time();
|
$now = time();
|
||||||
BoltCourse::insert("(create_time, short_name, name, description, doc_file) values ($now, '$short_name', '$name', '$description', '$doc_file')");
|
BoltCourse::insert("(create_time, short_name, name, description, doc_file) values ($now, '$short_name', '$name', '$description', '$doc_file')");
|
||||||
Header('Location: bolt_admin.php');
|
Header('Location: bolt_admin.php');
|
||||||
exit();
|
break;
|
||||||
} else if ($submit == 'Update user') {
|
case 'update_user_form':
|
||||||
|
admin_page_head("Bolt user settings");
|
||||||
|
user_settings();
|
||||||
|
admin_page_tail();
|
||||||
|
break;
|
||||||
|
case 'update_user':
|
||||||
$flags = 0;
|
$flags = 0;
|
||||||
if (get_str('show_all', true)) $flags |= BOLT_FLAGS_SHOW_ALL;
|
if (get_str('show_all', true)) $flags |= BOLT_FLAGS_SHOW_ALL;
|
||||||
if (get_str('debug', true)) $flags |= BOLT_FLAGS_DEBUG;
|
if (get_str('debug', true)) $flags |= BOLT_FLAGS_DEBUG;
|
||||||
$user->bolt->update("flags=$flags");
|
$user->bolt->update("flags=$flags");
|
||||||
$user->bolt->flags = $flags;
|
$user->bolt->flags = $flags;
|
||||||
Header('Location: bolt_admin.php');
|
Header('Location: bolt_admin.php');
|
||||||
exit();
|
break;
|
||||||
} else {
|
case 'hide':
|
||||||
$action = get_str('action', true);
|
if (!$course) error_page("no such course");
|
||||||
if ($action) {
|
$course->update("hidden=1");
|
||||||
$course_id = get_int('course_id');
|
Header('Location: bolt_admin.php');
|
||||||
$course = BoltCourse::lookup_id($course_id);
|
break;
|
||||||
if (!$course) error_page("no such course");
|
case 'unhide':
|
||||||
switch ($action) {
|
if (!$course) error_page("no such course");
|
||||||
case 'hide':
|
$course->update("hidden=0");
|
||||||
$course->update("hidden=1");
|
Header('Location: bolt_admin.php');
|
||||||
break;
|
break;
|
||||||
case 'unhide':
|
case '':
|
||||||
$course->update("hidden=0");
|
show_all();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_page("unknown action $action");
|
error_page("unknown action $action");
|
||||||
}
|
|
||||||
Header('Location: bolt_admin.php');
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show_all();
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
|
|
||||||
const char* CONFIG_FILE = "config.xml";
|
const char* CONFIG_FILE = "config.xml";
|
||||||
|
|
||||||
|
const int MAX_NCPUS = 8;
|
||||||
|
// max multiplier for daily_result_quota and max_wus_in_progress;
|
||||||
|
// need to change as multicore processors expand
|
||||||
|
|
||||||
int SCHED_CONFIG::parse(FILE* f) {
|
int SCHED_CONFIG::parse(FILE* f) {
|
||||||
char tag[1024], temp[1024];
|
char tag[1024], temp[1024];
|
||||||
bool is_tag;
|
bool is_tag;
|
||||||
|
@ -51,7 +55,7 @@ int SCHED_CONFIG::parse(FILE* f) {
|
||||||
sched_debug_level = SCHED_MSG_LOG::MSG_NORMAL;
|
sched_debug_level = SCHED_MSG_LOG::MSG_NORMAL;
|
||||||
fuh_debug_level = SCHED_MSG_LOG::MSG_NORMAL;
|
fuh_debug_level = SCHED_MSG_LOG::MSG_NORMAL;
|
||||||
strcpy(httpd_user, "apache");
|
strcpy(httpd_user, "apache");
|
||||||
|
max_ncpus = MAX_NCPUS;
|
||||||
|
|
||||||
if (!xp.parse_start("boinc")) return ERR_XML_PARSE;
|
if (!xp.parse_start("boinc")) return ERR_XML_PARSE;
|
||||||
if (!xp.parse_start("config")) return ERR_XML_PARSE;
|
if (!xp.parse_start("config")) return ERR_XML_PARSE;
|
||||||
|
@ -141,6 +145,7 @@ int SCHED_CONFIG::parse(FILE* f) {
|
||||||
if (xp.parse_int(tag, "file_deletion_strategy", file_deletion_strategy)) continue;
|
if (xp.parse_int(tag, "file_deletion_strategy", file_deletion_strategy)) continue;
|
||||||
if (xp.parse_bool(tag, "request_time_stats_log", request_time_stats_log)) continue;
|
if (xp.parse_bool(tag, "request_time_stats_log", request_time_stats_log)) continue;
|
||||||
if (xp.parse_bool(tag, "enable_assignment", enable_assignment)) continue;
|
if (xp.parse_bool(tag, "enable_assignment", enable_assignment)) continue;
|
||||||
|
if (xp.parse_int(tag, "max_ncpus", max_ncpus)) continue;
|
||||||
|
|
||||||
// don't complain about unparsed XML;
|
// don't complain about unparsed XML;
|
||||||
// there are lots of tags the scheduler doesn't know about
|
// there are lots of tags the scheduler doesn't know about
|
||||||
|
|
|
@ -111,6 +111,7 @@ public:
|
||||||
// select method of automatically deleting files from host
|
// select method of automatically deleting files from host
|
||||||
bool request_time_stats_log;
|
bool request_time_stats_log;
|
||||||
bool enable_assignment;
|
bool enable_assignment;
|
||||||
|
int max_ncpus;
|
||||||
|
|
||||||
int parse(FILE*);
|
int parse(FILE*);
|
||||||
int parse_file(const char* dir=".");
|
int parse_file(const char* dir=".");
|
||||||
|
|
|
@ -72,9 +72,13 @@ const char* infeasible_string(int code) {
|
||||||
|
|
||||||
const int MIN_SECONDS_TO_SEND = 0;
|
const int MIN_SECONDS_TO_SEND = 0;
|
||||||
const int MAX_SECONDS_TO_SEND = (28*SECONDS_IN_DAY);
|
const int MAX_SECONDS_TO_SEND = (28*SECONDS_IN_DAY);
|
||||||
const int MAX_CPUS = 8;
|
|
||||||
// max multiplier for daily_result_quota and max_wus_in_progress;
|
inline int effective_ncpus(HOST& host) {
|
||||||
// need to change as multicore processors expand
|
int ncpus = host.p_ncpus;
|
||||||
|
if (ncpus > config.max_ncpus) ncpus = config.max_ncpus;
|
||||||
|
if (ncpus < 1) ncpus = 1;
|
||||||
|
return ncpus;
|
||||||
|
}
|
||||||
|
|
||||||
const double DEFAULT_RAM_SIZE = 64000000;
|
const double DEFAULT_RAM_SIZE = 64000000;
|
||||||
// if host sends us an impossible RAM size, use this instead
|
// if host sends us an impossible RAM size, use this instead
|
||||||
|
@ -297,6 +301,9 @@ static int get_host_info(SCHEDULER_REPLY& reply) {
|
||||||
double avg_turnaround = reply.host.avg_turnaround;
|
double avg_turnaround = reply.host.avg_turnaround;
|
||||||
update_average(0, 0, CREDIT_HALF_LIFE, expavg_credit, expavg_time);
|
update_average(0, 0, CREDIT_HALF_LIFE, expavg_credit, expavg_time);
|
||||||
double credit_scale, turnaround_scale;
|
double credit_scale, turnaround_scale;
|
||||||
|
|
||||||
|
// TODO: is the following still needed? Why?
|
||||||
|
//
|
||||||
if (strstr(reply.host.os_name,"Windows") || strstr(reply.host.os_name,"Linux")
|
if (strstr(reply.host.os_name,"Windows") || strstr(reply.host.os_name,"Linux")
|
||||||
) {
|
) {
|
||||||
credit_scale = 1;
|
credit_scale = 1;
|
||||||
|
@ -306,7 +313,8 @@ static int get_host_info(SCHEDULER_REPLY& reply) {
|
||||||
turnaround_scale = 1.25;
|
turnaround_scale = 1.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((expavg_credit/reply.host.p_ncpus) > config.reliable_min_avg_credit*credit_scale || config.reliable_min_avg_credit == 0)
|
int ncpus = effective_ncpus(reply.host);
|
||||||
|
if (((expavg_credit/ncpus) > config.reliable_min_avg_credit*credit_scale || config.reliable_min_avg_credit == 0)
|
||||||
&& (avg_turnaround < config.reliable_max_avg_turnaround*turnaround_scale || config.reliable_max_avg_turnaround == 0)
|
&& (avg_turnaround < config.reliable_max_avg_turnaround*turnaround_scale || config.reliable_max_avg_turnaround == 0)
|
||||||
){
|
){
|
||||||
reply.wreq.host_info.reliable = true;
|
reply.wreq.host_info.reliable = true;
|
||||||
|
@ -481,7 +489,7 @@ int wu_is_infeasible(
|
||||||
double est_cpu = estimate_cpu_duration(wu, reply);
|
double est_cpu = estimate_cpu_duration(wu, reply);
|
||||||
IP_RESULT candidate("", wu.delay_bound, est_cpu);
|
IP_RESULT candidate("", wu.delay_bound, est_cpu);
|
||||||
strcpy(candidate.name, wu.name);
|
strcpy(candidate.name, wu.name);
|
||||||
if (check_candidate(candidate, reply.host.p_ncpus, request.ip_results)) {
|
if (check_candidate(candidate, effective_ncpus(reply.host), request.ip_results)) {
|
||||||
// it passed the feasibility test,
|
// it passed the feasibility test,
|
||||||
// but don't add it the the workload yet;
|
// but don't add it the the workload yet;
|
||||||
// wait until we commit to sending it
|
// wait until we commit to sending it
|
||||||
|
@ -719,12 +727,7 @@ bool SCHEDULER_REPLY::work_needed(bool locality_sched) {
|
||||||
}
|
}
|
||||||
if (wreq.nresults >= config.max_wus_to_send) return false;
|
if (wreq.nresults >= config.max_wus_to_send) return false;
|
||||||
|
|
||||||
// daily quota and max jobs per host are scaled by #CPUs,
|
int ncpus = effective_ncpus(host);
|
||||||
// but only up to MAX_CPUs (currently 8)
|
|
||||||
//
|
|
||||||
int ncpus = host.p_ncpus;
|
|
||||||
if (ncpus > MAX_CPUS) ncpus = MAX_CPUS;
|
|
||||||
if (ncpus < 1) ncpus = 1;
|
|
||||||
|
|
||||||
// host.max_results_day is between 1 and config.daily_result_quota inclusive
|
// host.max_results_day is between 1 and config.daily_result_quota inclusive
|
||||||
// wreq.daily_result_quota is between ncpus
|
// wreq.daily_result_quota is between ncpus
|
||||||
|
@ -892,7 +895,7 @@ int add_result_to_reply(
|
||||||
}
|
}
|
||||||
reply.insert_result(result);
|
reply.insert_result(result);
|
||||||
reply.wreq.seconds_to_fill -= wu_seconds_filled;
|
reply.wreq.seconds_to_fill -= wu_seconds_filled;
|
||||||
request.estimated_delay += wu_seconds_filled/reply.host.p_ncpus;
|
request.estimated_delay += wu_seconds_filled/effective_ncpus(reply.host);
|
||||||
reply.wreq.nresults++;
|
reply.wreq.nresults++;
|
||||||
reply.wreq.nresults_on_host++;
|
reply.wreq.nresults_on_host++;
|
||||||
if (!resent_result) reply.host.nresults_today++;
|
if (!resent_result) reply.host.nresults_today++;
|
||||||
|
@ -965,7 +968,7 @@ void send_work(
|
||||||
|
|
||||||
if (config.workload_sim && sreq.have_other_results_list) {
|
if (config.workload_sim && sreq.have_other_results_list) {
|
||||||
init_ip_results(
|
init_ip_results(
|
||||||
sreq.global_prefs.work_buf_min(), reply.host.p_ncpus, sreq.ip_results
|
sreq.global_prefs.work_buf_min(), effective_ncpus(reply.host), sreq.ip_results
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue