2012-05-08 12:31:37 +00:00
|
|
|
// This file is part of BOINC.
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2012 University of California
|
|
|
|
//
|
|
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
|
|
// under the terms of the GNU Lesser General Public License
|
|
|
|
// as published by the Free Software Foundation,
|
|
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2012-08-01 21:21:38 +00:00
|
|
|
#include <cmath>
|
2012-07-02 19:31:34 +00:00
|
|
|
|
2012-05-08 12:31:37 +00:00
|
|
|
#include "util.h"
|
2012-06-25 23:09:45 +00:00
|
|
|
#include "coproc.h"
|
|
|
|
|
2012-05-08 12:31:37 +00:00
|
|
|
#include "sched_config.h"
|
|
|
|
#include "sched_customize.h"
|
|
|
|
#include "plan_class_spec.h"
|
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
using std::string;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2014-05-27 09:27:30 +00:00
|
|
|
|
|
|
|
// this returns a numerical OS version for Darwin/OSX and Windows,
|
|
|
|
// allowing to define a numerical _range_ for these OS versions
|
|
|
|
static double os_version_num(HOST h) {
|
|
|
|
if (strstr(h.os_name, "Darwin")) {
|
|
|
|
unsigned int a,b,c;
|
|
|
|
if (sscanf(h.os_version, "%u.%u.%u", &a, &b, &c) == 3) {
|
|
|
|
return 10000.0*a + 100.0*b + c;
|
|
|
|
}
|
|
|
|
} else if (strstr(h.os_name, "Windows")) {
|
|
|
|
unsigned int a,b,c,d;
|
|
|
|
// example: "Enterprise Server Edition, Service Pack 1, (06.01.7601.00)"
|
|
|
|
char*p = strrchr(h.os_version,'(');
|
|
|
|
if (p && (sscanf(p, "(%u.%u.%u.%u)", &a, &b, &c, &d) == 4)) {
|
|
|
|
return 100000000.0*a + 1000000.0*b + 100.0*c +d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// could not determine numerical OS version
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-06 03:47:13 +00:00
|
|
|
int PLAN_CLASS_SPECS::parse_file(const char* path) {
|
2012-05-08 12:31:37 +00:00
|
|
|
#ifndef _USING_FCGI_
|
|
|
|
FILE* f = fopen(path, "r");
|
|
|
|
#else
|
|
|
|
FCGI_FILE *f = FCGI::fopen(path, "r");
|
|
|
|
#endif
|
|
|
|
if (!f) return ERR_FOPEN;
|
|
|
|
int retval = parse_specs(f);
|
|
|
|
fclose(f);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2014-06-05 06:39:10 +00:00
|
|
|
bool PLAN_CLASS_SPEC::opencl_check(OPENCL_DEVICE_PROP& opencl_prop) {
|
|
|
|
if (min_opencl_version && opencl_prop.opencl_device_version_int
|
|
|
|
&& min_opencl_version > opencl_prop.opencl_device_version_int
|
|
|
|
) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] OpenCL device version required min: %d, supplied: %d\n",
|
|
|
|
min_opencl_version, opencl_prop.opencl_device_version_int
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_opencl_version && opencl_prop.opencl_device_version_int
|
|
|
|
&& max_opencl_version < opencl_prop.opencl_device_version_int
|
|
|
|
) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] OpenCL device version required max: %d, supplied: %d\n",
|
|
|
|
max_opencl_version, opencl_prop.opencl_device_version_int
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (min_opencl_driver_revision && opencl_prop.opencl_device_version_int
|
|
|
|
&& min_opencl_driver_revision > opencl_prop.opencl_driver_revision
|
|
|
|
) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] OpenCL driver revision required min: %d, supplied: %d\n",
|
|
|
|
min_opencl_driver_revision, opencl_prop.opencl_driver_revision
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_opencl_driver_revision && opencl_prop.opencl_device_version_int
|
|
|
|
&& max_opencl_driver_revision < opencl_prop.opencl_driver_revision
|
|
|
|
) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] OpenCL driver revision required max: %d, supplied: %d\n",
|
|
|
|
max_opencl_driver_revision, opencl_prop.opencl_driver_revision
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
bool PLAN_CLASS_SPEC::check(SCHEDULER_REQUEST& sreq, HOST_USAGE& hu) {
|
2012-05-14 19:49:12 +00:00
|
|
|
COPROC* cpp = NULL;
|
2012-06-06 04:45:12 +00:00
|
|
|
bool can_use_multicore = true;
|
2012-05-14 06:54:38 +00:00
|
|
|
|
2012-06-22 07:35:54 +00:00
|
|
|
hu.sequential_app(sreq.host.p_fpops);
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
// CPU features
|
2012-05-14 06:54:38 +00:00
|
|
|
//
|
2012-06-03 17:31:00 +00:00
|
|
|
// older clients report CPU features in p_model,
|
|
|
|
// within square brackets
|
|
|
|
//
|
|
|
|
// the requested features are surrounded by spaces,
|
|
|
|
// so we can look for them with strstr()
|
|
|
|
//
|
|
|
|
if (!cpu_features.empty()) {
|
|
|
|
char buf[8192], buf2[512];
|
|
|
|
sprintf(buf, " %s ", sreq.host.p_features);
|
|
|
|
char* p = strrchr(sreq.host.p_model, '[');
|
|
|
|
if (p) {
|
|
|
|
sprintf(buf2, " %s", p+1);
|
|
|
|
p = strchr(buf2, ']');
|
|
|
|
if (p) {
|
|
|
|
*p = 0;
|
|
|
|
}
|
|
|
|
strcat(buf2, " ");
|
|
|
|
strcat(buf, buf2);
|
|
|
|
}
|
|
|
|
downcase_string(buf);
|
|
|
|
|
|
|
|
for (unsigned int i=0; i<cpu_features.size(); i++) {
|
2012-06-06 03:47:13 +00:00
|
|
|
if (!strstr(buf, cpu_features[i].c_str())) {
|
2012-06-03 17:31:00 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: CPU lacks feature '%s' (got '%s')\n",
|
2012-06-03 17:31:00 +00:00
|
|
|
cpu_features[i].c_str(), sreq.host.p_features
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-06 04:45:12 +00:00
|
|
|
// min NCPUS
|
|
|
|
//
|
|
|
|
if (min_ncpus && g_wreq->effective_ncpus < min_ncpus) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: not enough CPUs: %d < %f\n",
|
2012-06-06 04:45:12 +00:00
|
|
|
g_wreq->effective_ncpus, min_ncpus
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-04-15 19:00:14 +00:00
|
|
|
// host summary
|
|
|
|
//
|
|
|
|
if (have_host_summary_regex
|
|
|
|
&& regexec(&(host_summary_regex), g_reply->host.serialnum, 0, NULL, 0)
|
|
|
|
) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: host summary '%s' didn't match regexp\n",
|
|
|
|
g_reply->host.serialnum
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
// OS version
|
|
|
|
//
|
|
|
|
if (have_os_regex && regexec(&(os_regex), sreq.host.os_version, 0, NULL, 0)) {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: OS version '%s' didn't match regexp\n",
|
2012-05-14 06:54:38 +00:00
|
|
|
sreq.host.os_version
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-27 09:27:30 +00:00
|
|
|
if (min_os_version || max_os_version) {
|
|
|
|
double host_os_version_num = os_version_num(sreq.host);
|
|
|
|
if (!host_os_version_num) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: Can't determine numerical OS version '%s'\n",
|
|
|
|
sreq.host.os_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (min_os_version && (host_os_version_num < min_os_version)) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: OS version '%s' too low (%.0f / %.0f)\n",
|
|
|
|
sreq.host.os_version, host_os_version_num, min_os_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (max_os_version && (host_os_version_num > max_os_version)) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: OS version '%s' too high (%.0f / %.0f)\n",
|
|
|
|
sreq.host.os_version, host_os_version_num, max_os_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2014-05-27 09:27:30 +00:00
|
|
|
// BOINC versions
|
2013-01-28 23:22:02 +00:00
|
|
|
//
|
|
|
|
if (min_core_client_version && sreq.core_client_version < min_core_client_version) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: Need newer BOINC core client: %d < %d\n",
|
|
|
|
sreq.core_client_version, min_core_client_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
add_no_work_message("A newer BOINC may be required for some tasks.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (max_core_client_version && sreq.core_client_version > max_core_client_version) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: Need older BOINC core client: %d > %d\n",
|
|
|
|
sreq.core_client_version, max_core_client_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-06-06 04:45:12 +00:00
|
|
|
if (virtualbox) {
|
|
|
|
|
|
|
|
// host must run 7.0+ client
|
|
|
|
//
|
|
|
|
if (sreq.core_client_major_version < 7) {
|
|
|
|
add_no_work_message("BOINC client 7.0+ required for Virtualbox jobs");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// host must have VirtualBox 3.2 or later
|
|
|
|
//
|
|
|
|
if (strlen(sreq.host.virtualbox_version) == 0) {
|
|
|
|
add_no_work_message("VirtualBox is not installed");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int n, maj, min, rel;
|
|
|
|
n = sscanf(sreq.host.virtualbox_version, "%d.%d.%d", &maj, &min, &rel);
|
|
|
|
if (n != 3) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: can't parse vbox version\n"
|
2012-06-06 04:45:12 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int v = maj*10000 + min*100 + rel;
|
|
|
|
if (min_vbox_version && v < min_vbox_version) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: vbox version too low: %d < %d\n",
|
2012-06-06 04:45:12 +00:00
|
|
|
v, min_vbox_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (max_vbox_version && v > max_vbox_version) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: vbox version too high: %d > %d\n",
|
2012-06-06 04:45:12 +00:00
|
|
|
v, max_vbox_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 23:54:56 +00:00
|
|
|
if (vm_accel_required) {
|
|
|
|
if ((!strstr(sreq.host.p_features, "vmx") && !strstr(sreq.host.p_features, "svm"))
|
|
|
|
|| sreq.host.p_vm_extensions_disabled
|
|
|
|
) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: missing VM HW acceleration\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-06 04:45:12 +00:00
|
|
|
// host must have VM acceleration in order to run multi-core jobs
|
|
|
|
//
|
|
|
|
if (max_threads > 1) {
|
|
|
|
if ((!strstr(sreq.host.p_features, "vmx") && !strstr(sreq.host.p_features, "svm"))
|
|
|
|
|| sreq.host.p_vm_extensions_disabled
|
|
|
|
) {
|
|
|
|
can_use_multicore = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// only send the version for host's primary platform.
|
|
|
|
// A Win64 host can't run a 32-bit VM app:
|
|
|
|
// it will look in the 32-bit half of the registry and fail
|
|
|
|
//
|
|
|
|
PLATFORM* p = g_request->platforms.list[0];
|
|
|
|
if (is_64b_platform(p->name)) {
|
|
|
|
if (!is64bit) return false;
|
|
|
|
} else {
|
|
|
|
if (is64bit) return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-08 12:31:37 +00:00
|
|
|
// project-specific preference
|
2012-05-14 06:54:38 +00:00
|
|
|
//
|
|
|
|
if (have_project_prefs_regex && strlen(project_prefs_tag)) {
|
|
|
|
char tag[256], value[256];
|
2012-05-08 12:31:37 +00:00
|
|
|
char buf[65536];
|
2013-06-04 03:24:48 +00:00
|
|
|
extract_venue(g_reply->user.project_prefs, g_reply->host.venue, buf, sizeof(buf));
|
2012-05-08 12:31:37 +00:00
|
|
|
sprintf(tag,"<%s>",project_prefs_tag);
|
2012-05-14 06:54:38 +00:00
|
|
|
bool p = parse_str(buf, tag, value, sizeof(value));
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: parsed project prefs setting '%s' : %s\n",
|
2012-05-14 06:54:38 +00:00
|
|
|
project_prefs_tag, p?"true":"false"
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
2014-05-27 07:38:40 +00:00
|
|
|
if (p ? regexec(&(project_prefs_regex), value, 0, NULL, 0) : !project_prefs_default_true) {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2013-04-05 06:58:15 +00:00
|
|
|
"[version] plan_class_spec: project prefs setting '%s' value='%s' prevents using plan class.\n",
|
|
|
|
project_prefs_tag, p ? value : "(tag missing)"
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
double gpu_ram = 0;
|
|
|
|
int driver_version = 0;
|
2012-05-08 12:31:37 +00:00
|
|
|
double gpu_utilization = 1.0;
|
|
|
|
|
|
|
|
// user defined gpu_utilization
|
2012-05-14 06:54:38 +00:00
|
|
|
//
|
|
|
|
if (strlen(gpu_utilization_tag)) {
|
2012-05-08 12:31:37 +00:00
|
|
|
char tag[256];
|
|
|
|
char buf[65536];
|
|
|
|
double v = 0;
|
2013-06-04 03:24:48 +00:00
|
|
|
extract_venue(g_reply->user.project_prefs, g_reply->host.venue, buf, sizeof(buf));
|
2012-05-08 12:31:37 +00:00
|
|
|
sprintf(tag,"<%s>",gpu_utilization_tag);
|
|
|
|
bool p = parse_double(buf, tag, v);
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: parsed project prefs setting '%s' : %s : %f\n",
|
2012-05-08 12:31:37 +00:00
|
|
|
gpu_utilization_tag, p?"true":"false", v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (v) {
|
|
|
|
gpu_utilization = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-06 06:05:14 +00:00
|
|
|
// AMD
|
2012-05-14 06:54:38 +00:00
|
|
|
//
|
2012-06-06 10:05:00 +00:00
|
|
|
if (!strcmp(gpu_type, "amd") || !strcmp(gpu_type, "ati")) {
|
2012-05-14 06:54:38 +00:00
|
|
|
COPROC_ATI& cp = sreq.coprocs.ati;
|
2012-05-14 19:49:12 +00:00
|
|
|
cpp = &cp;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
if (!cp.count) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: No AMD GPUs found\n"
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (min_gpu_ram_mb) {
|
2012-06-25 23:09:45 +00:00
|
|
|
gpu_requirements[PROC_TYPE_AMD_GPU].update(0, min_gpu_ram_mb * MEGA);
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
if (min_driver_version) {
|
2012-06-25 23:09:45 +00:00
|
|
|
gpu_requirements[PROC_TYPE_AMD_GPU].update(abs(min_driver_version), 0);
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-06-07 03:39:37 +00:00
|
|
|
|
|
|
|
if (need_ati_libs) {
|
|
|
|
if (!cp.atirt_detected) {
|
2013-04-03 00:23:37 +00:00
|
|
|
if (config.debug_version_select) {
|
2012-07-05 20:24:17 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: ATI libraries not found\n"
|
|
|
|
);
|
2012-07-05 15:29:38 +00:00
|
|
|
}
|
2012-06-07 03:39:37 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
2013-06-26 02:17:46 +00:00
|
|
|
if (need_amd_libs && !cp.amdrt_detected) {
|
2013-04-03 00:23:37 +00:00
|
|
|
if (config.debug_version_select) {
|
2012-07-05 20:24:17 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: AMD libraries not found\n"
|
|
|
|
);
|
2012-07-05 15:29:38 +00:00
|
|
|
}
|
2012-06-07 03:39:37 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-25 20:28:41 +00:00
|
|
|
if (without_opencl) {
|
|
|
|
if (cp.have_opencl) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2013-04-25 23:33:22 +00:00
|
|
|
"[version] plan_class_spec: OpenCL detected. Plan restricted to CAL only GPUs\n"
|
2013-04-25 20:28:41 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-07 21:08:47 +00:00
|
|
|
if (min_cal_target && cp.attribs.target < min_cal_target) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: CAL target less than minimum (%d < %d)\n",
|
2012-06-07 21:08:47 +00:00
|
|
|
cp.attribs.target, min_cal_target
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (max_cal_target && cp.attribs.target > max_cal_target) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: CAL target greater than maximum (%d > %d)\n",
|
2012-06-07 21:08:47 +00:00
|
|
|
cp.attribs.target, max_cal_target
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
cp.set_peak_flops();
|
2012-05-14 06:54:38 +00:00
|
|
|
gpu_ram = cp.opencl_prop.global_mem_size;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
driver_version = 0;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (cp.have_cal) {
|
|
|
|
int major, minor, release, scanned;
|
|
|
|
scanned = sscanf(cp.version, "%d.%d.%d", &major, &minor, &release);
|
|
|
|
if (scanned != 3) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: driver version '%s' couldn't be parsed\n",
|
2012-05-14 06:54:38 +00:00
|
|
|
cp.version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
} else {
|
2012-07-05 15:29:38 +00:00
|
|
|
driver_version = ati_version_int(major,minor,release);
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
} else {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: no CAL, driver version couldn't be determined\n"
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2012-06-06 10:05:00 +00:00
|
|
|
|
|
|
|
// NVIDIA
|
|
|
|
//
|
2012-05-14 06:54:38 +00:00
|
|
|
} else if (!strcmp(gpu_type, "nvidia")) {
|
|
|
|
COPROC_NVIDIA& cp = sreq.coprocs.nvidia;
|
2012-05-14 19:49:12 +00:00
|
|
|
cpp = &cp;
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
if (!cp.count) {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: No NVIDIA GPUs found\n"
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-05-19 18:08:36 +00:00
|
|
|
|
|
|
|
// in analogy to ATI/AMD
|
|
|
|
driver_version=cp.display_driver_version;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
if (min_gpu_ram_mb) {
|
2012-06-25 23:09:45 +00:00
|
|
|
gpu_requirements[PROC_TYPE_NVIDIA_GPU].update(0, min_gpu_ram_mb * MEGA);
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
if (min_driver_version) {
|
2012-06-25 23:09:45 +00:00
|
|
|
gpu_requirements[PROC_TYPE_NVIDIA_GPU].update(abs(min_driver_version), 0);
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
// compute capability
|
|
|
|
int v = (cp.prop.major)*100 + cp.prop.minor;
|
2012-05-14 19:49:12 +00:00
|
|
|
if (min_nvidia_compcap && min_nvidia_compcap > v) {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: NVIDIA compute capability required min: %d, supplied: %d\n",
|
2012-05-14 19:49:12 +00:00
|
|
|
min_nvidia_compcap, v
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2012-05-14 19:49:12 +00:00
|
|
|
if (max_nvidia_compcap && max_nvidia_compcap < v) {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: CUDA compute capability required max: %d, supplied: %d\n",
|
2012-05-14 19:49:12 +00:00
|
|
|
max_nvidia_compcap, v
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
if (cuda) {
|
|
|
|
// CUDA version
|
|
|
|
if (min_cuda_version && min_cuda_version > cp.cuda_version) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: CUDA version required min: %d, supplied: %d\n",
|
2012-05-14 06:54:38 +00:00
|
|
|
min_cuda_version, cp.cuda_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
if (max_cuda_version && max_cuda_version < cp.cuda_version) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: CUDA version required max: %d, supplied: %d\n",
|
2012-05-14 06:54:38 +00:00
|
|
|
max_cuda_version, cp.cuda_version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
gpu_ram = cp.prop.totalGlobalMem;
|
2012-05-14 19:49:12 +00:00
|
|
|
cp.set_peak_flops();
|
2012-06-25 23:09:45 +00:00
|
|
|
|
|
|
|
// Intel GPU
|
|
|
|
//
|
2013-06-26 02:17:46 +00:00
|
|
|
} else if (strstr(gpu_type, "intel")==gpu_type) {
|
2012-06-25 23:09:45 +00:00
|
|
|
COPROC& cp = sreq.coprocs.intel_gpu;
|
|
|
|
cpp = &cp;
|
|
|
|
|
|
|
|
if (!cp.count) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] [version] No Intel GPUs found\n"
|
2012-06-25 23:09:45 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (min_gpu_ram_mb) {
|
|
|
|
gpu_requirements[PROC_TYPE_INTEL_GPU].update(0, min_gpu_ram_mb * MEGA);
|
|
|
|
}
|
2012-05-14 06:54:38 +00:00
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-06-03 17:31:00 +00:00
|
|
|
if (opencl) {
|
2014-06-05 06:39:10 +00:00
|
|
|
if (cpp) {
|
|
|
|
if (!cpp->have_opencl) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] GPU doesn't support OpenCL\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2012-06-03 17:31:00 +00:00
|
|
|
}
|
2014-06-05 06:39:10 +00:00
|
|
|
if (!opencl_check(cpp->opencl_prop)) {
|
|
|
|
return false;
|
2013-04-11 01:20:22 +00:00
|
|
|
}
|
2014-06-05 06:39:10 +00:00
|
|
|
gpu_ram = cpp->opencl_prop.global_mem_size;
|
|
|
|
} else {
|
|
|
|
// OpenCL CPU app version.
|
|
|
|
// The host may have several OpenCL CPU libraries.
|
|
|
|
// See if any of them works.
|
|
|
|
// TODO: there should be a way of saying which library
|
|
|
|
// the app version requires,
|
|
|
|
// or a way of conveying to the app which one to use.
|
|
|
|
//
|
|
|
|
bool found = false;
|
|
|
|
for (int i=0; i<sreq.host.num_opencl_cpu_platforms; i++) {
|
|
|
|
if (opencl_check(sreq.host.opencl_cpu_prop[i].opencl_prop)) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
2013-04-11 01:20:22 +00:00
|
|
|
}
|
2014-06-05 06:39:10 +00:00
|
|
|
if (!found) {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] CPU doesn't support OpenCL\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2013-04-11 01:20:22 +00:00
|
|
|
}
|
|
|
|
}
|
2012-06-03 17:31:00 +00:00
|
|
|
}
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
// general GPU
|
|
|
|
//
|
|
|
|
if (strlen(gpu_type)) {
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
// GPU RAM
|
2012-05-14 06:54:38 +00:00
|
|
|
if (min_gpu_ram_mb && min_gpu_ram_mb * MEGA > gpu_ram) {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: GPU RAM required min: %f, supplied: %f\n",
|
2012-05-14 06:54:38 +00:00
|
|
|
min_gpu_ram_mb * MEGA, gpu_ram
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// (display) driver version
|
2012-05-14 19:49:12 +00:00
|
|
|
if (min_driver_version && driver_version) {
|
|
|
|
if (min_driver_version > driver_version) {
|
2012-05-14 06:54:38 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: driver version required min: %d, supplied: %d\n",
|
2012-05-14 19:49:12 +00:00
|
|
|
abs(min_driver_version), driver_version
|
2012-05-14 06:54:38 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
}
|
2012-05-14 19:49:12 +00:00
|
|
|
if (max_driver_version && driver_version) {
|
|
|
|
if (max_driver_version < driver_version) {
|
2012-05-14 06:54:38 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: driver version required max: %d, supplied: %d\n",
|
2012-05-14 19:49:12 +00:00
|
|
|
abs(max_driver_version), driver_version
|
2012-05-14 06:54:38 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hu.gpu_ram = (gpu_ram_used_mb?gpu_ram_used_mb:min_gpu_ram_mb) * MEGA;
|
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
double gpu_usage;
|
|
|
|
|
|
|
|
// if ngpus < 0, set gpu_usage by the fraction of the total
|
2012-05-14 06:54:38 +00:00
|
|
|
// video RAM a tasks would take
|
2012-05-08 12:31:37 +00:00
|
|
|
// i.e. fill the device memory with tasks
|
2012-05-14 06:54:38 +00:00
|
|
|
//
|
2012-05-08 12:31:37 +00:00
|
|
|
if (ngpus < 0) {
|
2012-05-14 19:49:12 +00:00
|
|
|
gpu_usage = (floor(gpu_ram/ hu.gpu_ram) * hu.gpu_ram) / gpu_ram ;
|
2012-05-08 12:31:37 +00:00
|
|
|
} else if (ngpus > 0) {
|
2012-05-14 19:49:12 +00:00
|
|
|
gpu_usage = ngpus * gpu_utilization;
|
2012-05-08 12:31:37 +00:00
|
|
|
} else {
|
2012-05-14 19:49:12 +00:00
|
|
|
gpu_usage = gpu_utilization;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
coproc_perf(
|
|
|
|
capped_host_fpops(),
|
2012-05-14 19:49:12 +00:00
|
|
|
gpu_peak_flops_scale * gpu_usage * cpp->peak_flops,
|
2012-05-08 12:31:37 +00:00
|
|
|
cpu_frac,
|
|
|
|
hu.projected_flops,
|
|
|
|
hu.avg_ncpus
|
|
|
|
);
|
|
|
|
if (avg_ncpus) {
|
|
|
|
hu.avg_ncpus = avg_ncpus;
|
|
|
|
}
|
2012-09-10 22:56:46 +00:00
|
|
|
// I believe the first term here is just hu.projected_flops,
|
|
|
|
// but I'm leaving it spelled out to match GPU scheduling
|
|
|
|
// code in sched_customize.cpp
|
2012-09-12 22:31:23 +00:00
|
|
|
//
|
2012-09-10 22:56:46 +00:00
|
|
|
hu.peak_flops = gpu_peak_flops_scale*gpu_usage*cpp->peak_flops + hu.avg_ncpus*capped_host_fpops();
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-06-06 10:05:00 +00:00
|
|
|
if (!strcmp(gpu_type, "amd") || !strcmp(gpu_type, "ati")) {
|
2012-06-25 23:09:45 +00:00
|
|
|
hu.proc_type = PROC_TYPE_AMD_GPU;
|
2012-06-22 07:35:54 +00:00
|
|
|
hu.gpu_usage = gpu_usage;
|
2012-05-14 19:49:12 +00:00
|
|
|
} else if (!strcmp(gpu_type, "nvidia")) {
|
2012-06-25 23:09:45 +00:00
|
|
|
hu.proc_type = PROC_TYPE_NVIDIA_GPU;
|
2012-06-22 07:35:54 +00:00
|
|
|
hu.gpu_usage = gpu_usage;
|
2013-06-26 02:17:46 +00:00
|
|
|
} else if (strstr(gpu_type, "intel")==gpu_type) {
|
2012-06-25 23:09:45 +00:00
|
|
|
hu.proc_type = PROC_TYPE_INTEL_GPU;
|
2012-06-22 07:35:54 +00:00
|
|
|
hu.gpu_usage = gpu_usage;
|
2013-06-26 02:17:46 +00:00
|
|
|
} else {
|
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] plan_class_spec: unknown GPU supplied: %s\n",
|
|
|
|
gpu_type
|
|
|
|
);
|
|
|
|
}
|
2012-05-14 19:49:12 +00:00
|
|
|
}
|
2012-06-06 10:05:00 +00:00
|
|
|
// CPU only
|
|
|
|
//
|
|
|
|
} else {
|
2012-05-08 12:31:37 +00:00
|
|
|
if (avg_ncpus) {
|
|
|
|
hu.avg_ncpus = avg_ncpus;
|
|
|
|
} else {
|
2012-06-06 04:45:12 +00:00
|
|
|
if (can_use_multicore) {
|
|
|
|
if (max_threads > g_wreq->effective_ncpus) {
|
|
|
|
hu.avg_ncpus = g_wreq->effective_ncpus;
|
|
|
|
} else {
|
|
|
|
hu.avg_ncpus = max_threads;
|
|
|
|
}
|
2012-06-03 17:31:00 +00:00
|
|
|
} else {
|
2012-06-06 04:45:12 +00:00
|
|
|
hu.avg_ncpus = 1;
|
2012-06-03 17:31:00 +00:00
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hu.peak_flops = capped_host_fpops() * hu.avg_ncpus;
|
2012-05-14 19:49:12 +00:00
|
|
|
hu.projected_flops = capped_host_fpops() * hu.avg_ncpus * projected_flops_scale;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-05-14 19:49:12 +00:00
|
|
|
hu.max_ncpus = hu.avg_ncpus;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2013-05-19 18:08:36 +00:00
|
|
|
#if 0
|
2012-05-08 12:31:37 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2012-07-05 20:24:17 +00:00
|
|
|
"[version] plan_class_spec: host_flops: %e, \tscale: %.2f, \tprojected_flops: %e, \tpeak_flops: %e\n",
|
2012-05-14 19:49:12 +00:00
|
|
|
sreq.host.p_fpops, projected_flops_scale, hu.projected_flops,
|
|
|
|
hu.peak_flops
|
2012-05-08 12:31:37 +00:00
|
|
|
);
|
|
|
|
}
|
2013-05-19 18:08:36 +00:00
|
|
|
#endif
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
bool PLAN_CLASS_SPECS::check(
|
|
|
|
SCHEDULER_REQUEST& sreq, char* plan_class, HOST_USAGE& hu
|
|
|
|
) {
|
2012-05-08 12:31:37 +00:00
|
|
|
for (unsigned int i=0; i<classes.size(); i++) {
|
|
|
|
if (!strcmp(classes[i].name, plan_class)) {
|
|
|
|
return classes[i].check(sreq, hu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log_messages.printf(MSG_CRITICAL, "Unknown plan class: %s\n", plan_class);
|
|
|
|
return false;
|
2012-05-14 06:54:38 +00:00
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
int PLAN_CLASS_SPEC::parse(XML_PARSER& xp) {
|
|
|
|
char buf[256];
|
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (xp.match_tag("/plan_class")) {
|
2012-05-14 19:49:12 +00:00
|
|
|
return 0;
|
2012-05-14 06:54:38 +00:00
|
|
|
}
|
|
|
|
if (xp.parse_str("name", name, sizeof(name))) continue;
|
2013-01-28 23:22:02 +00:00
|
|
|
if (xp.parse_int("min_core_client_version", min_core_client_version)) continue;
|
|
|
|
if (xp.parse_int("max_core_client_version", max_core_client_version)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_str("gpu_type", gpu_type, sizeof(gpu_type))) continue;
|
2012-05-14 19:49:12 +00:00
|
|
|
if (xp.parse_bool("cuda", cuda)) continue;
|
|
|
|
if (xp.parse_bool("cal", cal)) continue;
|
|
|
|
if (xp.parse_bool("opencl", opencl)) continue;
|
|
|
|
if (xp.parse_bool("virtualbox", virtualbox)) continue;
|
|
|
|
if (xp.parse_bool("is64bit", is64bit)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_str("cpu_feature", buf, sizeof(buf))) {
|
|
|
|
cpu_features.push_back(" " + (string)buf + " ");
|
|
|
|
continue;
|
|
|
|
}
|
2012-06-06 04:45:12 +00:00
|
|
|
if (xp.parse_double("min_ncpus", min_ncpus)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_int("max_threads", max_threads)) continue;
|
|
|
|
if (xp.parse_double("projected_flops_scale", projected_flops_scale)) continue;
|
|
|
|
if (xp.parse_str("os_regex", buf, sizeof(buf))) {
|
2012-05-14 19:49:12 +00:00
|
|
|
if (regcomp(&(os_regex), buf, REG_EXTENDED|REG_NOSUB) ) {
|
2012-05-14 06:54:38 +00:00
|
|
|
log_messages.printf(MSG_CRITICAL, "BAD REGEXP: %s\n", buf);
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
have_os_regex = true;
|
|
|
|
continue;
|
|
|
|
}
|
2013-04-15 19:00:14 +00:00
|
|
|
if (xp.parse_str("host_summary_regex", buf, sizeof(buf))) {
|
|
|
|
if (regcomp(&(host_summary_regex), buf, REG_EXTENDED|REG_NOSUB) ) {
|
|
|
|
log_messages.printf(MSG_CRITICAL, "BAD REGEXP: %s\n", buf);
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
have_host_summary_regex = true;
|
|
|
|
continue;
|
|
|
|
}
|
2014-05-27 09:27:30 +00:00
|
|
|
if (xp.parse_double("min_os_version", min_os_version)) continue;
|
|
|
|
if (xp.parse_double("max_os_version", max_os_version)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_str("project_prefs_tag", project_prefs_tag, sizeof(project_prefs_tag))) continue;
|
2012-05-14 19:49:12 +00:00
|
|
|
if (xp.parse_str("project_prefs_regex", buf, sizeof(buf))) {
|
|
|
|
if (regcomp(&(project_prefs_regex), buf, REG_EXTENDED|REG_NOSUB) ) {
|
2012-05-14 06:54:38 +00:00
|
|
|
log_messages.printf(MSG_CRITICAL, "BAD REGEXP: %s\n", buf);
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
2012-05-14 19:49:12 +00:00
|
|
|
have_project_prefs_regex = true;
|
2012-05-14 06:54:38 +00:00
|
|
|
continue;
|
|
|
|
}
|
2014-05-27 07:38:40 +00:00
|
|
|
if (xp.parse_bool("project_prefs_default_true", project_prefs_default_true)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_double("avg_ncpus", avg_ncpus)) continue;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
if (xp.parse_double("cpu_frac", cpu_frac)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_double("min_gpu_ram_mb", min_gpu_ram_mb)) continue;
|
|
|
|
if (xp.parse_double("gpu_ram_used_mb", gpu_ram_used_mb)) continue;
|
2012-05-14 19:49:12 +00:00
|
|
|
if (xp.parse_double("gpu_peak_flops_scale", gpu_peak_flops_scale)) continue;
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_double("ngpus", ngpus)) continue;
|
|
|
|
if (xp.parse_int("min_driver_version", min_driver_version)) continue;
|
|
|
|
if (xp.parse_int("max_driver_version", max_driver_version)) continue;
|
|
|
|
if (xp.parse_str("gpu_utilization_tag", gpu_utilization_tag, sizeof(gpu_utilization_tag))) continue;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-06-07 03:39:37 +00:00
|
|
|
if (xp.parse_bool("need_ati_libs", need_ati_libs)) continue;
|
2013-06-26 02:17:46 +00:00
|
|
|
if (xp.parse_bool("need_amd_libs", need_amd_libs)) continue;
|
2013-04-25 20:28:41 +00:00
|
|
|
if (xp.parse_bool("without_opencl", without_opencl)) continue;
|
2012-06-07 21:08:47 +00:00
|
|
|
if (xp.parse_int("min_cal_target", min_cal_target)) continue;
|
|
|
|
if (xp.parse_int("max_cal_target", max_cal_target)) continue;
|
2012-06-07 03:39:37 +00:00
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_int("min_nvidia_compcap", min_nvidia_compcap)) continue;
|
|
|
|
if (xp.parse_int("max_nvidia_compcap", max_nvidia_compcap)) continue;
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_int("min_cuda_version", min_cuda_version)) continue;
|
|
|
|
if (xp.parse_int("max_cuda_version", max_cuda_version)) continue;
|
|
|
|
|
|
|
|
if (xp.parse_int("min_opencl_version", min_opencl_version)) continue;
|
|
|
|
if (xp.parse_int("max_opencl_version", max_opencl_version)) continue;
|
|
|
|
|
2013-04-11 01:20:22 +00:00
|
|
|
if (xp.parse_int("min_opencl_driver_revision", min_opencl_driver_revision)) continue;
|
|
|
|
if (xp.parse_int("max_opencl_driver_revision", max_opencl_driver_revision)) continue;
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
if (xp.parse_int("min_vbox_version", min_vbox_version)) continue;
|
|
|
|
if (xp.parse_int("max_vbox_version", max_vbox_version)) continue;
|
2013-12-03 23:54:56 +00:00
|
|
|
if (xp.parse_bool("vm_accel_required", vm_accel_required)) continue;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-05-14 19:49:12 +00:00
|
|
|
return ERR_XML_PARSE;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int PLAN_CLASS_SPECS::parse_specs(FILE* f) {
|
|
|
|
MIOFILE mf;
|
|
|
|
XML_PARSER xp(&mf);
|
|
|
|
mf.init_file(f);
|
|
|
|
if (!xp.parse_start("plan_classes")) return ERR_XML_PARSE;
|
|
|
|
while (!xp.get_tag()) {
|
|
|
|
if (!xp.is_tag) {
|
|
|
|
fprintf(stderr, "PLAN_CLASS_SPECS::parse(): unexpected text %s\n", xp.parsed_tag);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (xp.match_tag("/plan_classes")) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (xp.match_tag("plan_class")) {
|
|
|
|
PLAN_CLASS_SPEC pc;
|
2012-05-14 19:49:12 +00:00
|
|
|
int retval = pc.parse(xp);
|
2012-05-14 06:54:38 +00:00
|
|
|
if (retval) return retval;
|
2012-05-08 12:31:37 +00:00
|
|
|
classes.push_back(pc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
2012-05-14 06:54:38 +00:00
|
|
|
}
|
2012-05-08 12:31:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
PLAN_CLASS_SPEC::PLAN_CLASS_SPEC() {
|
2012-05-14 06:54:38 +00:00
|
|
|
strcpy(name, "");
|
|
|
|
strcpy(gpu_type, "");
|
|
|
|
cuda = false;
|
|
|
|
cal = false;
|
|
|
|
opencl = false;
|
|
|
|
virtualbox = false;
|
|
|
|
is64bit = false;
|
|
|
|
min_ncpus = 0;
|
2012-06-06 03:47:13 +00:00
|
|
|
max_threads = 1;
|
2012-05-14 06:54:38 +00:00
|
|
|
projected_flops_scale = 1;
|
|
|
|
have_os_regex = false;
|
2014-05-27 09:27:30 +00:00
|
|
|
min_os_version = 0;
|
|
|
|
max_os_version = 0;
|
2012-05-14 06:54:38 +00:00
|
|
|
strcpy(project_prefs_tag, "");
|
2013-04-05 06:58:15 +00:00
|
|
|
have_project_prefs_regex = false;
|
2014-05-27 07:38:40 +00:00
|
|
|
project_prefs_default_true = false;
|
2012-05-14 06:54:38 +00:00
|
|
|
avg_ncpus = 0;
|
2014-06-01 17:21:16 +00:00
|
|
|
min_core_client_version = 0;
|
|
|
|
max_core_client_version = 0;
|
|
|
|
have_host_summary_regex = false;
|
2012-05-14 06:54:38 +00:00
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
cpu_frac = .1;
|
2012-05-14 06:54:38 +00:00
|
|
|
min_gpu_ram_mb = 0;
|
|
|
|
gpu_ram_used_mb = 0;
|
|
|
|
gpu_peak_flops_scale = 1;
|
|
|
|
ngpus = 1;
|
|
|
|
min_driver_version = 0;
|
|
|
|
max_driver_version = 0;
|
|
|
|
strcpy(gpu_utilization_tag, "");
|
2012-05-08 12:31:37 +00:00
|
|
|
|
2012-06-07 03:39:37 +00:00
|
|
|
need_ati_libs = false;
|
2013-06-26 02:17:46 +00:00
|
|
|
need_amd_libs = false;
|
2014-06-01 17:21:16 +00:00
|
|
|
min_cal_target = 0;
|
|
|
|
max_cal_target = 0;
|
2013-04-25 20:28:41 +00:00
|
|
|
without_opencl = false;
|
2012-06-07 03:39:37 +00:00
|
|
|
|
2012-05-14 19:49:12 +00:00
|
|
|
min_nvidia_compcap = 0;
|
|
|
|
max_nvidia_compcap = 0;
|
2012-05-08 12:31:37 +00:00
|
|
|
min_cuda_version = 0;
|
|
|
|
max_cuda_version = 0;
|
|
|
|
|
|
|
|
min_opencl_version = 0;
|
2012-05-14 06:54:38 +00:00
|
|
|
max_opencl_version = 0;
|
2013-04-11 01:20:22 +00:00
|
|
|
min_opencl_driver_revision = 0;
|
|
|
|
max_opencl_driver_revision = 0;
|
|
|
|
|
2012-05-14 06:54:38 +00:00
|
|
|
min_vbox_version = 0;
|
|
|
|
max_vbox_version = 0;
|
2013-12-03 23:54:56 +00:00
|
|
|
vm_accel_required = false;
|
2012-05-08 12:31:37 +00:00
|
|
|
}
|
2012-06-06 03:47:13 +00:00
|
|
|
|
|
|
|
#ifdef PLAN_CLASS_TEST
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
SCHEDULER_REQUEST sreq;
|
|
|
|
SCHEDULER_REPLY sreply;
|
|
|
|
g_request = &sreq;
|
|
|
|
g_reply = &sreply;
|
|
|
|
g_wreq = &sreply.wreq;
|
|
|
|
|
|
|
|
PLAN_CLASS_SPECS pcs;
|
2012-06-06 06:05:14 +00:00
|
|
|
int retval = pcs.parse_file("plan_class_spec.xml.sample");
|
2012-06-06 03:47:13 +00:00
|
|
|
if (retval) {
|
2014-01-09 06:00:13 +00:00
|
|
|
printf("parse_file: %d\n", retval);
|
2012-06-06 03:47:13 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
config.debug_version_select = true;
|
|
|
|
|
|
|
|
HOST_USAGE hu;
|
|
|
|
|
2013-08-08 18:00:29 +00:00
|
|
|
strcpy(sreq.host.p_features, "pni");
|
2012-06-06 03:47:13 +00:00
|
|
|
sreq.host.p_fpops =5e9;
|
|
|
|
g_wreq->effective_ncpus = 4;
|
|
|
|
if (1) {
|
|
|
|
sreq.coprocs.nvidia.fake(18000, 512*MEGA, 490*MEGA, 1);
|
2012-06-06 06:05:14 +00:00
|
|
|
sreq.coprocs.nvidia.opencl_prop.opencl_device_version_int = 0;
|
|
|
|
} else {
|
|
|
|
sreq.coprocs.nvidia.count = 0;
|
|
|
|
}
|
|
|
|
if (1) {
|
|
|
|
sreq.coprocs.ati.fake(512*MEGA, 256*MEGA, 1);
|
|
|
|
sreq.coprocs.ati.have_cal = true;
|
|
|
|
sreq.coprocs.ati.opencl_prop.opencl_device_version_int = 0;
|
|
|
|
} else {
|
|
|
|
sreq.coprocs.ati.count = 0;
|
2012-06-06 03:47:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int i=0; i<pcs.classes.size(); i++) {
|
|
|
|
bool b = pcs.check(sreq, pcs.classes[i].name, hu);
|
|
|
|
if (b) {
|
|
|
|
printf("%s: check succeeded\n", pcs.classes[i].name);
|
2012-06-06 06:05:14 +00:00
|
|
|
printf("\tncudas: %f\n\tnatis: %f\n\tgpu_ram: %fMB\n\tavg_ncpus: %f\n\tprojected_flops: %fG\n\tpeak_flops: %fG\n",
|
2012-06-06 03:47:13 +00:00
|
|
|
hu.ncudas,
|
|
|
|
hu.natis,
|
|
|
|
hu.gpu_ram/1e6,
|
|
|
|
hu.avg_ncpus,
|
|
|
|
hu.projected_flops/1e9,
|
|
|
|
hu.peak_flops/1e9
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
printf("%s: check failed\n", pcs.classes[i].name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|