static inline int check_disk(WORKUNIT& wu) { double diff = wu.rsc_disk_bound - g_wreq->disk_available; if (diff > 0) { char message[256]; sprintf(message, "%s needs %0.2fMB more disk space. You currently have %0.2f MB available and it needs %0.2f MB.", find_user_friendly_name(wu.appid), diff/MEGA, g_wreq->disk_available/MEGA, wu.rsc_disk_bound/MEGA ); add_no_work_message(message); g_wreq->disk.set_insufficient(diff); return INFEASIBLE_DISK; } return 0; }
static inline int check_bandwidth(WORKUNIT& wu) { if (wu.rsc_bandwidth_bound == 0) return 0; // if n_bwdown is zero, the host has never downloaded anything, // so skip this check // if (g_reply->host.n_bwdown == 0) return 0; double diff = wu.rsc_bandwidth_bound - g_reply->host.n_bwdown; if (diff > 0) { char message[256]; sprintf(message, "%s requires %0.2f KB/sec download bandwidth. Your computer has been measured at %0.2f KB/sec.", find_user_friendly_name(wu.appid), wu.rsc_bandwidth_bound/KILO, g_reply->host.n_bwdown/KILO ); add_no_work_message(message); g_wreq->bandwidth.set_insufficient(diff); return INFEASIBLE_BANDWIDTH; } return 0; }
static inline int check_memory(WORKUNIT& wu) { double diff = wu.rsc_memory_bound - g_wreq->usable_ram; if (diff > 0) { char message[256]; sprintf(message, "%s needs %0.2f MB RAM but only %0.2f MB is available for use.", find_user_friendly_name(wu.appid), wu.rsc_memory_bound/MEGA, g_wreq->usable_ram/MEGA ); add_no_work_message(message); if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] [WU#%u %s] needs %0.2fMB RAM; [HOST#%d] has %0.2fMB, %0.2fMB usable\n", wu.id, wu.name, wu.rsc_memory_bound/MEGA, g_reply->host.id, g_wreq->ram/MEGA, g_wreq->usable_ram/MEGA ); } g_wreq->mem.set_insufficient(wu.rsc_memory_bound); g_reply->set_delay(DELAY_NO_WORK_TEMP); return INFEASIBLE_MEM; } return 0; }
// scan through client's anonymous apps and pick the best one // CLIENT_APP_VERSION* get_app_version_anonymous( APP& app, bool need_64b, bool reliable_only ) { unsigned int i; CLIENT_APP_VERSION* best = NULL; bool found = false; char message[256]; if (config.debug_version_select) { log_messages.printf(MSG_NORMAL, "[version] get_app_version_anonymous: app %s%s\n", app.name, reliable_only?" (reliable only)":"" ); } for (i=0; i<g_request->client_app_versions.size(); i++) { CLIENT_APP_VERSION& cav = g_request->client_app_versions[i]; if (!cav.app) continue; if (cav.app->id != app.id) { continue; } if (need_64b && !is_64b_platform(cav.platform)) { continue; } int gavid = host_usage_to_gavid(cav.host_usage, app); if (reliable_only && !app_version_is_reliable(gavid)) { if (config.debug_version_select) { log_messages.printf(MSG_NORMAL, "[version] %d %s not reliable\n", cav.version_num, cav.plan_class ); } continue; } if (daily_quota_exceeded(gavid, cav.host_usage)) { if (config.debug_version_select) { log_messages.printf(MSG_NORMAL, "[version] %d %s daily quota exceeded\n", cav.version_num, cav.plan_class ); } continue; } if (cav.version_num < app.min_version) { if (config.debug_version_select) { log_messages.printf(MSG_NORMAL, "[version] %d %s version < min version\n", cav.version_num, cav.plan_class ); } continue; } found = true; if (!need_this_resource(cav.host_usage, NULL, &cav)) { if (config.debug_version_select) { log_messages.printf(MSG_NORMAL, "[version] %d %s don't need resource\n", cav.version_num, cav.plan_class ); } continue; } if (best) { if (cav.host_usage.projected_flops > best->host_usage.projected_flops) { best = &cav; } } else { best = &cav; } } if (!best) { if (config.debug_version_select) { log_messages.printf(MSG_NORMAL, "[version] Didn't find anonymous platform app for %s\n", app.name ); } } if (!found) { sprintf(message, "%s %s.", _("Your app_info.xml file doesn't have a usable version of"), app.user_friendly_name ); add_no_work_message(message); } return best; }
// return BEST_APP_VERSION for the given host, or NULL if none // // check_req: check whether we still need work for the resource // reliable_only: use only versions for which this host is "reliable" // BEST_APP_VERSION* get_app_version( WORKUNIT& wu, bool check_req, bool reliable_only ) { bool found; unsigned int i; int retval, j; BEST_APP_VERSION* bavp; char message[256], buf[256]; // see if app is already in memoized array // /* std::vector<BEST_APP_VERSION*>::iterator bavi; bavi = g_wreq->best_app_versions.begin(); while (bavi != g_wreq->best_app_versions.end()) { bavp = *bavi; if (bavp->appid == wu.appid) { if (!bavp->present) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] returning cached NULL\n" ); } return NULL; } // if we previously chose a CUDA app but don't need more CUDA work, // delete record, fall through, and find another version // if (check_req && g_wreq->rsc_spec_request && bavp->host_usage.ncudas > 0 && !g_wreq->need_cuda() ) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] have CUDA version but no more CUDA work needed\n" ); } g_wreq->best_app_versions.erase(bavi); break; } // same, ATI if (check_req && g_wreq->rsc_spec_request && bavp->host_usage.natis > 0 && !g_wreq->need_ati() ) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] have ATI version but no more ATI work needed\n" ); } g_wreq->best_app_versions.erase(bavi); break; } // same, CPU // if (check_req && g_wreq->rsc_spec_request && !bavp->host_usage.ncudas && !bavp->host_usage.natis && !g_wreq->need_cpu() ) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] have CPU version but no more CPU work needed\n" ); } g_wreq->best_app_versions.erase(bavi); break; } if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] returning cached version\n" ); } return bavp; } bavi++; } */ APP* app = ssp->lookup_app(wu.appid); if (!app) { log_messages.printf(MSG_CRITICAL, "WU refers to nonexistent app: %d\n", wu.appid ); return NULL; } if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] looking for version of %s\n", app->name ); } bavp = new BEST_APP_VERSION; bavp->appid = wu.appid; if (g_wreq->anonymous_platform) { CLIENT_APP_VERSION* cavp = get_app_version_anonymous( *app, reliable_only ); if (!cavp) { bavp->present = false; } else { bavp->present = true; // if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] Found anonymous platform app for %s: plan class %s\n", app->name, cavp->plan_class ); // } bavp->host_usage = cavp->host_usage; bavp->cavp = cavp; int gavid = host_usage_to_gavid(cavp->host_usage, *app); bavp->reliable = app_version_is_reliable(gavid); bavp->trusted = app_version_is_trusted(gavid); } g_wreq->best_app_versions.push_back(bavp); if (!bavp->present) return NULL; return bavp; } // Go through the client's platforms. // Scan the app versions for each platform. // Find the one with highest expected FLOPS // bavp->host_usage.projected_flops = 0; bavp->avp = NULL; bool no_version_for_platform = true; for (i=0; i<g_request->platforms.list.size(); i++) { PLATFORM* p = g_request->platforms.list[i]; for (j=0; j<ssp->napp_versions; j++) { HOST_USAGE host_usage; APP_VERSION& av = ssp->app_versions[j]; if (av.appid != wu.appid) continue; if (av.platformid != p->id) continue; no_version_for_platform = false; if (daily_quota_exceeded(av.id)) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] daily quota exceeded\n" ); } continue; } if (reliable_only && !app_version_is_reliable(av.id)) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] not reliable\n"); } continue; } if (g_request->core_client_version < av.min_core_version) { log_messages.printf(MSG_NORMAL, "outdated client version %d < min core version %d\n", g_request->core_client_version, av.min_core_version ); g_wreq->outdated_client = true; continue; } if (strlen(av.plan_class)) { if (!g_request->client_cap_plan_class) { log_messages.printf(MSG_NORMAL, "client version %d lacks plan class capability\n", g_request->core_client_version ); continue; } if (!app_plan(*g_request, av.plan_class, host_usage)) { continue; } } else { host_usage.sequential_app(g_reply->host.p_fpops); } // skip versions for resources we don't need // /* if (!need_this_resource(host_usage, &av, NULL)) { continue; } */ // skip versions that go against resource prefs // if (host_usage.ncudas && g_wreq->no_cuda) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] Skipping CUDA version - user prefs say no CUDA\n" ); g_wreq->no_cuda_prefs = true; } continue; } if (host_usage.natis && g_wreq->no_ati) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] Skipping ATI version - user prefs say no ATI\n" ); g_wreq->no_ati_prefs = true; } continue; } if (!(host_usage.ncudas || host_usage.natis) && g_wreq->no_cpu) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] Skipping CPU version - user prefs say no CPUs\n" ); g_wreq->no_cpu_prefs = true; } continue; } estimate_flops(host_usage, av); // pick the fastest version // if (host_usage.projected_flops > bavp->host_usage.projected_flops) { bavp->host_usage = host_usage; bavp->avp = &av; bavp->reliable = app_version_is_reliable(av.id); bavp->trusted = app_version_is_trusted(av.id); } } } if (bavp->avp) { if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] Best version of app %s is ID %d (%.2f GFLOPS)\n", app->name, bavp->avp->id, bavp->host_usage.projected_flops/1e9 ); } bavp->present = true; g_wreq->best_app_versions.push_back(bavp); } else { // Here if there's no app version we can use. // if (config.debug_version_select||1) { log_messages.printf(MSG_NORMAL, "[version] returning NULL; platforms:\n" ); for (i=0; i<g_request->platforms.list.size(); i++) { PLATFORM* p = g_request->platforms.list[i]; log_messages.printf(MSG_NORMAL, "[version] %s\n", p->name ); } } if (no_version_for_platform) { sprintf(message, "%s is not available for your type of computer.", app->user_friendly_name ); add_no_work_message(message); } g_wreq->best_app_versions.push_back(bavp); return NULL; } return bavp; }
// scan through client's anonymous apps and pick the best one // CLIENT_APP_VERSION* get_app_version_anonymous(APP& app, bool reliable_only) { unsigned int i; CLIENT_APP_VERSION* best = NULL; bool found = false; char message[256]; for (i=0; i<g_request->client_app_versions.size(); i++) { CLIENT_APP_VERSION& cav = g_request->client_app_versions[i]; if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[version] get_app_version_anonymous: %s %d\n", cav.app_name, cav.version_num ); } if (cav.app->id != app.id) { continue; } int gavid = host_usage_to_gavid(cav.host_usage, app); /* if (reliable_only && !app_version_is_reliable(gavid)) { log_messages.printf(MSG_NORMAL, "[version] not reliable\n"); continue; } */ if (daily_quota_exceeded(gavid)) { log_messages.printf(MSG_NORMAL, "[version] daily quota exceeded\n"); continue; } if (cav.version_num < app.min_version) { log_messages.printf(MSG_NORMAL, "[version] bad version\n"); continue; } found = true; if (!need_this_resource(cav.host_usage, NULL, &cav)) { log_messages.printf(MSG_NORMAL, "[version] don't need resource\n"); continue; } if (best) { // if (cav.host_usage.projected_flops > best->host_usage.projected_flops) { best = &cav; // } } else { best = &cav; } } if (!best) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] Didn't find anonymous platform app for %s\n", app.name ); } } if (!found) { sprintf(message, "Your app_info.xml file doesn't have a version of %s.", app.user_friendly_name ); add_no_work_message(message); } return best; }