code cleanup: in scheduler, factor project prefs into their own struct

This commit is contained in:
David Anderson 2016-07-27 15:15:08 -07:00
parent a9761176de
commit 671446ced1
11 changed files with 99 additions and 90 deletions

View File

@ -42,7 +42,6 @@
#include <cerrno>
#include <sys/stat.h>
#include <sys/file.h>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <sys/time.h>

View File

@ -381,7 +381,7 @@ void send_work_old() {
// (projects should load beta work with care,
// otherwise your users won't get production work done!
//
if (g_wreq->allow_beta_work) {
if (g_wreq->project_prefs.allow_beta_work) {
g_wreq->beta_only = true;
if (config.debug_send_scan) {
log_messages.printf(MSG_NORMAL,
@ -429,12 +429,12 @@ void send_work_old() {
// If user has selected apps but will accept any,
// and we haven't found any jobs for selected apps, try others
//
if (!g_wreq->njobs_sent && g_wreq->allow_non_preferred_apps ) {
if (!g_wreq->njobs_sent && g_wreq->project_prefs.allow_non_selected_apps ) {
g_wreq->user_apps_only = false;
preferred_app_message_index = g_wreq->no_work_messages.size();
selected_app_message_index = g_wreq->no_work_messages.size();
if (config.debug_send_scan) {
log_messages.printf(MSG_NORMAL,
"[send_scan] scanning for jobs from non-preferred applications\n"
"[send_scan] scanning for jobs from non-selected applications\n"
);
}
if (scan_work_array()) return;

View File

@ -50,10 +50,10 @@ const char* infeasible_string(int code) {
bool app_not_selected(int appid) {
unsigned int i;
if (g_wreq->preferred_apps.size() == 0) return false;
for (i=0; i<g_wreq->preferred_apps.size(); i++) {
if (appid == g_wreq->preferred_apps[i].appid) {
g_wreq->preferred_apps[i].work_available = true;
if (g_wreq->project_prefs.selected_apps.size() == 0) return false;
for (i=0; i<g_wreq->project_prefs.selected_apps.size(); i++) {
if (appid == g_wreq->project_prefs.selected_apps[i].appid) {
g_wreq->project_prefs.selected_apps[i].work_available = true;
return false;
}
}

View File

@ -296,7 +296,7 @@ static int possibly_send_result(SCHED_DB_RESULT& result) {
retval = wu.lookup_id(result.workunitid);
if (retval) return ERR_DB_NOT_FOUND;
// This doesn't take into account g_wreq->allow_non_preferred_apps,
// This doesn't take into account g_wreq->allow_non_selected_apps,
// however Einstein@Home, which is the only project that currently uses
// this locality scheduler, doesn't support the respective project-specific
// preference setting

View File

@ -163,14 +163,14 @@ int send_nci() {
}
continue;
}
if (app.beta && !g_wreq->allow_beta_work) {
if (app.beta && !g_wreq->project_prefs.allow_beta_work) {
if (config.debug_send) {
log_messages.printf(MSG_NORMAL, "%s is beta\n", app.name);
}
continue;
}
if (app_not_selected(app.id)) {
if (!g_wreq->allow_non_preferred_apps) {
if (!g_wreq->project_prefs.allow_non_selected_apps) {
if (config.debug_send) {
log_messages.printf(MSG_NORMAL,
"%s is not selected\n", app.name

View File

@ -64,7 +64,7 @@ bool JOB::get_score(WU_RESULT& wu_result) {
}
if (app->beta) {
if (g_wreq->allow_beta_work) {
if (g_wreq->project_prefs.allow_beta_work) {
score += 1;
} else {
if (config.debug_send_job) {
@ -78,7 +78,7 @@ bool JOB::get_score(WU_RESULT& wu_result) {
}
if (app_not_selected(app->id)) {
if (g_wreq->allow_non_preferred_apps) {
if (g_wreq->project_prefs.allow_non_selected_apps) {
score -= 1;
} else {
if (config.debug_send_job) {

View File

@ -64,7 +64,7 @@
//
const double DEFAULT_RAM_SIZE = 64000000;
int preferred_app_message_index=0;
int selected_app_message_index=0;
static inline bool file_present_on_host(const char* name) {
for (unsigned i=0; i<g_request->file_infos.size(); i++) {
@ -481,59 +481,6 @@ double estimate_duration(WORKUNIT& wu, BEST_APP_VERSION& bav) {
return ed;
}
// Parse user's project prferences.
// TODO: use XML_PARSER
//
static void get_prefs_info() {
char buf[8096];
std::string str;
unsigned int pos = 0;
int temp_int=0;
bool flag;
extract_venue(g_reply->user.project_prefs, g_reply->host.venue, buf, sizeof(buf));
str = buf;
// scan user's project prefs for elements of the form <app_id>N</app_id>,
// indicating the apps they want to run.
//
g_wreq->preferred_apps.clear();
while (parse_int(str.substr(pos,str.length()-pos).c_str(), "<app_id>", temp_int)) {
APP_INFO ai;
ai.appid = temp_int;
ai.work_available = false;
g_wreq->preferred_apps.push_back(ai);
pos = str.find("<app_id>", pos) + 1;
}
if (parse_bool(buf,"allow_non_preferred_apps", flag)) {
g_wreq->allow_non_preferred_apps = flag;
}
if (parse_bool(buf,"allow_beta_work", flag)) {
g_wreq->allow_beta_work = flag;
}
if (parse_bool(buf,"no_gpus", flag)) {
// deprecated, but need to handle
if (flag) {
for (int i=1; i<NPROC_TYPES; i++) {
g_wreq->dont_use_proc_type[i] = true;
}
}
}
if (parse_bool(buf,"no_cpu", flag)) {
g_wreq->dont_use_proc_type[PROC_TYPE_CPU] = flag;
}
if (parse_bool(buf,"no_cuda", flag)) {
g_wreq->dont_use_proc_type[PROC_TYPE_NVIDIA_GPU] = flag;
}
if (parse_bool(buf,"no_ati", flag)) {
g_wreq->dont_use_proc_type[PROC_TYPE_AMD_GPU] = flag;
}
if (parse_bool(buf,"no_intel_gpu", flag)) {
g_wreq->dont_use_proc_type[PROC_TYPE_INTEL_GPU] = flag;
}
}
void update_n_jobs_today() {
for (unsigned int i=0; i<g_wreq->host_app_versions.size(); i++) {
DB_HOST_APP_VERSION& hav = g_wreq->host_app_versions[i];
@ -1256,16 +1203,16 @@ static void send_user_messages() {
// Inform the user about applications with no work
//
for (i=0; i<g_wreq->preferred_apps.size(); i++) {
if (!g_wreq->preferred_apps[i].work_available) {
APP* app = ssp->lookup_app(g_wreq->preferred_apps[i].appid);
for (i=0; i<g_wreq->project_prefs.selected_apps.size(); i++) {
if (!g_wreq->project_prefs.selected_apps[i].work_available) {
APP* app = ssp->lookup_app(g_wreq->project_prefs.selected_apps[i].appid);
// don't write message if the app is deprecated
//
if (app) {
char explanation[256];
sprintf(explanation,
"No tasks are available for %s",
find_user_friendly_name(g_wreq->preferred_apps[i].appid)
find_user_friendly_name(g_wreq->project_prefs.selected_apps[i].appid)
);
g_reply->insert_message( explanation, "low");
}
@ -1274,7 +1221,7 @@ static void send_user_messages() {
// Tell the user about applications they didn't qualify for
//
for (j=0; j<preferred_app_message_index; j++){
for (j=0; j<selected_app_message_index; j++){
g_reply->insert_message(g_wreq->no_work_messages.at(j));
}
g_reply->insert_message(
@ -1295,14 +1242,14 @@ static void send_user_messages() {
// Tell the user about applications with no work
//
for (i=0; i<g_wreq->preferred_apps.size(); i++) {
if (!g_wreq->preferred_apps[i].work_available) {
APP* app = ssp->lookup_app(g_wreq->preferred_apps[i].appid);
for (i=0; i<g_wreq->project_prefs.selected_apps.size(); i++) {
if (!g_wreq->project_prefs.selected_apps[i].work_available) {
APP* app = ssp->lookup_app(g_wreq->project_prefs.selected_apps[i].appid);
// don't write message if the app is deprecated
if (app != NULL) {
sprintf(buf, "No tasks are available for %s",
find_user_friendly_name(
g_wreq->preferred_apps[i].appid
g_wreq->project_prefs.selected_apps[i].appid
)
);
g_reply->insert_message(buf, "low");
@ -1357,7 +1304,7 @@ static void send_user_messages() {
);
}
for (i=0; i<NPROC_TYPES; i++) {
if (g_wreq->dont_use_proc_type[i] && ssp->have_apps_for_proc_type[i]) {
if (g_wreq->project_prefs.dont_use_proc_type[i] && ssp->have_apps_for_proc_type[i]) {
sprintf(buf,
_("Tasks for %s are available, but your preferences are set to not accept them"),
proc_type_name(i)
@ -1410,7 +1357,7 @@ void send_work_setup() {
// parse project preferences (e.g. no GPUs)
//
get_prefs_info();
g_wreq->project_prefs.parse();
if (g_wreq->anonymous_platform) {
estimate_flops_anon_platform();

View File

@ -56,7 +56,7 @@ extern const char* find_user_friendly_name(int appid);
extern bool work_needed(bool);
extern void send_work_setup();
extern int effective_ncpus();
extern int preferred_app_message_index;
extern int selected_app_message_index;
extern void update_n_jobs_today();
extern int nfiles_on_host(WORKUNIT&);

View File

@ -169,6 +169,58 @@ int CLIENT_PLATFORM::parse(XML_PARSER& xp) {
return ERR_XML_PARSE;
}
// Parse user's project preferences.
// TODO: use XML_PARSER
//
void PROJECT_PREFS::parse() {
char buf[8096];
std::string str;
unsigned int pos = 0;
int temp_int=0;
bool flag;
extract_venue(g_reply->user.project_prefs, g_reply->host.venue, buf, sizeof(buf));
str = buf;
// scan user's project prefs for elements of the form <app_id>N</app_id>,
// indicating the apps they want to run.
//
selected_apps.clear();
while (parse_int(str.substr(pos,str.length()-pos).c_str(), "<app_id>", temp_int)) {
APP_INFO ai;
ai.appid = temp_int;
ai.work_available = false;
selected_apps.push_back(ai);
pos = str.find("<app_id>", pos) + 1;
}
if (parse_bool(buf,"allow_non_selected_apps", flag)) {
allow_non_selected_apps = flag;
}
if (parse_bool(buf,"allow_beta_work", flag)) {
allow_beta_work = flag;
}
if (parse_bool(buf,"no_gpus", flag)) {
// deprecated, but need to handle
if (flag) {
for (int i=1; i<NPROC_TYPES; i++) {
dont_use_proc_type[i] = true;
}
}
}
if (parse_bool(buf,"no_cpu", flag)) {
dont_use_proc_type[PROC_TYPE_CPU] = flag;
}
if (parse_bool(buf,"no_cuda", flag)) {
dont_use_proc_type[PROC_TYPE_NVIDIA_GPU] = flag;
}
if (parse_bool(buf,"no_ati", flag)) {
dont_use_proc_type[PROC_TYPE_AMD_GPU] = flag;
}
if (parse_bool(buf,"no_intel_gpu", flag)) {
dont_use_proc_type[PROC_TYPE_INTEL_GPU] = flag;
}
}
void WORK_REQ::add_no_work_message(const char* message) {
for (unsigned int i=0; i<no_work_messages.size(); i++) {

View File

@ -362,8 +362,25 @@ struct DISK_LIMITS {
double min_free;
};
// parsed version of project prefs that relate to scheduling
//
struct PROJECT_PREFS {
std::vector<APP_INFO> selected_apps;
bool dont_use_proc_type[NPROC_TYPES];
bool allow_non_selected_apps;
bool allow_beta_work;
void parse();
PROJECT_PREFS() {
memset(&dont_use_proc_type, 0, sizeof(dont_use_proc_type));
allow_non_selected_apps = false;
allow_beta_work = false;
}
};
// summary of a client's request for work, and our response to it
// Note: this is zeroed out in SCHEDULER_REPLY constructor
// Note: this is zeroed out in SCHEDULER_REPLY constructor,
// so don't put any vectors here
//
struct WORK_REQ_BASE {
bool anonymous_platform;
@ -389,12 +406,6 @@ struct WORK_REQ_BASE {
// by the client. It may have contained results,
// so check and resend just in case.
// user preferences
//
bool dont_use_proc_type[NPROC_TYPES];
bool allow_non_preferred_apps;
bool allow_beta_work;
bool has_reliable_version;
// whether the host has a reliable app version
@ -489,7 +500,7 @@ struct WORK_REQ_BASE {
};
struct WORK_REQ : public WORK_REQ_BASE {
std::vector<APP_INFO> preferred_apps;
PROJECT_PREFS project_prefs;
std::vector<USER_MESSAGE> no_work_messages;
std::vector<BEST_APP_VERSION*> best_app_versions;
std::vector<DB_HOST_APP_VERSION> host_app_versions;

View File

@ -699,7 +699,7 @@ BEST_APP_VERSION* get_app_version(
if (av.appid != wu.appid) continue;
if (av.platformid != p->id) continue;
if (av.beta) {
if (!g_wreq->allow_beta_work) {
if (!g_wreq->project_prefs.allow_beta_work) {
continue;
}
}
@ -732,7 +732,7 @@ BEST_APP_VERSION* get_app_version(
// skip versions that go against resource prefs
//
int pt = host_usage.proc_type;
if (g_wreq->dont_use_proc_type[pt]) {
if (g_wreq->project_prefs.dont_use_proc_type[pt]) {
if (config.debug_version_select) {
log_messages.printf(MSG_NORMAL,
"[version] [AV#%lu] Skipping %s version - user prefs say no %s\n",