- client: add new config options:

<ignore_cuda_dev>n</ignore_cuda_dev>
    <ignore_ati_dev>n</ignore_ati_dev>
    to ignore (not use) specific NVIDIA or ATI GPUs.
    You can ignore more than one.

svn path=/trunk/boinc/; revision=19566
This commit is contained in:
David Anderson 2009-11-12 23:44:49 +00:00
parent f4a2c9cc0d
commit 4bf2ef5198
6 changed files with 97 additions and 32 deletions

View File

@ -9157,3 +9157,16 @@ David 12 Nov 2009
sched_array.cpp
sched_score.cpp
sched_send.cpp
David 12 Nov 2009
- client: add new config options:
<ignore_cuda_dev>n</ignore_cuda_dev>
<ignore_ati_dev>n</ignore_ati_dev>
to ignore (not use) specific NVIDIA or ATI GPUs.
You can ignore more than one.
client/
client_state.cpp
log_flags.cpp,h
lib/
coproc.cpp,h

View File

@ -261,7 +261,10 @@ int CLIENT_STATE::init() {
if (!config.no_gpus) {
vector<string> descs;
vector<string> warnings;
coprocs.get(config.use_all_gpus, descs, warnings);
coprocs.get(
config.use_all_gpus, descs, warnings,
config.ignore_cuda_dev, config.ignore_ati_dev
);
for (i=0; i<descs.size(); i++) {
msg_printf(NULL, MSG_INFO, descs[i].c_str());
}

View File

@ -163,6 +163,12 @@ void LOG_FLAGS::show() {
}
}
static void show_gpu_ignore(vector<int>& devs, const char* name) {
for (unsigned int i=0; i<devs.size(); i++) {
msg_printf(NULL, MSG_INFO, "Config: ignoring %s GPU %d", name, devs[i]);
}
}
// TODO: show other config options
//
void CONFIG::show() {
@ -184,6 +190,8 @@ void CONFIG::show() {
if (config.zero_debts) {
msg_printf(NULL, MSG_INFO, "Config: zero long-term debts on startup");
}
show_gpu_ignore(ignore_cuda_dev, "NVIDIA");
show_gpu_ignore(ignore_ati_dev, "ATI");
}
CONFIG::CONFIG() {
@ -201,6 +209,8 @@ void CONFIG::clear() {
exclusive_apps.clear();
force_auth = "default";
http_1_0 = false;
ignore_cuda_dev.clear();
ignore_ati_dev.clear();
max_file_xfers = MAX_FILE_XFERS;
max_file_xfers_per_project = MAX_FILE_XFERS_PER_PROJECT;
max_stderr_file_size = 0;
@ -227,6 +237,7 @@ int CONFIG::parse_options(XML_PARSER& xp) {
char tag[1024], path[256];
bool is_tag, btemp;
string s;
int n;
clear();
while (!xp.get(tag, sizeof(tag), is_tag)) {
@ -275,6 +286,14 @@ int CONFIG::parse_options(XML_PARSER& xp) {
continue;
}
if (xp.parse_bool(tag, "http_1_0", http_1_0)) continue;
if (xp.parse_int(tag, "ignore_cuda_dev", n)) {
ignore_cuda_dev.push_back(n);
continue;
}
if (xp.parse_int(tag, "ignore_ati_dev", n)) {
ignore_ati_dev.push_back(n);
continue;
}
if (xp.parse_int(tag, "max_file_xfers", max_file_xfers)) continue;
if (xp.parse_int(tag, "max_file_xfers_per_project", max_file_xfers_per_project)) continue;
if (xp.parse_int(tag, "max_stderr_file_size", max_stderr_file_size)) continue;

View File

@ -114,6 +114,8 @@ struct CONFIG {
std::vector<std::string> exclusive_apps;
std::string force_auth;
bool http_1_0;
std::vector<int> ignore_cuda_dev;
std::vector<int> ignore_ati_dev;
int max_file_xfers;
int max_file_xfers_per_project;
int max_stderr_file_size;

View File

@ -137,40 +137,48 @@ void COPROCS::summary_string(char* buf, int len) {
strcpy(buf, bigbuf);
}
#ifdef _WIN32
void COPROCS::get(bool use_all, vector<string>&descs, vector<string>&warnings) {
COPROC_CUDA::get(*this, use_all, descs, warnings);
COPROC_ATI::get(*this, descs, warnings);
static bool in_vector(int n, vector<int>& v) {
for (unsigned int i=0; i<v.size(); i++) {
if (v[i] == n) return true;
}
return false;
}
#else
#ifndef _WIN32
jmp_buf resume;
void segv_handler(int) {
longjmp(resume, 1);
}
#endif
void COPROCS::get(bool use_all, vector<string>&descs, vector<string>&warnings) {
void COPROCS::get(
bool use_all, vector<string>&descs, vector<string>&warnings,
vector<int>& ignore_cuda_dev,
vector<int>& ignore_ati_dev
) {
#ifdef _WIN32
COPROC_CUDA::get(*this, use_all, descs, warnings, ignore_cuda_dev);
COPROC_ATI::get(*this, descs, warnings, ignore_ati_dev);
#else
void (*old_sig)(int) = signal(SIGSEGV, segv_handler);
if (setjmp(resume)) {
warnings.push_back("Caught SIGSEGV in NVIDIA GPU detection");
} else {
COPROC_CUDA::get(*this, use_all, descs, warnings);
COPROC_CUDA::get(*this, use_all, descs, warnings, ignore_cuda_dev);
}
#ifndef __APPLE__ // ATI does not yet support CAL on Macs
if (setjmp(resume)) {
warnings.push_back("Caught SIGSEGV in ATI GPU detection");
} else {
COPROC_ATI::get(*this, descs, warnings);
COPROC_ATI::get(*this, descs, warnings, ignore_ati_dev);
}
#endif
signal(SIGSEGV, old_sig);
#endif
}
#endif
// used only to parse scheduler request messages
//
@ -285,7 +293,8 @@ void COPROC_CUDA::get(
COPROCS& coprocs,
bool use_all, // if false, use only those equivalent to most capable
vector<string>& descs,
vector<string>& warnings
vector<string>& warnings,
vector<int>& ignore_devs
) {
int count, retval;
char buf[256];
@ -474,12 +483,15 @@ void COPROC_CUDA::get(
return;
}
// identify the most capable instance
// identify the most capable non-ignored instance
//
COPROC_CUDA best;
bool first = true;
for (i=0; i<gpus.size(); i++) {
if (i==0) {
if (in_vector(gpus[i].device_num, ignore_devs)) continue;
if (first) {
best = gpus[i];
first = false;
} else if (cuda_compare(gpus[i], best, false) > 0) {
best = gpus[i];
}
@ -492,7 +504,9 @@ void COPROC_CUDA::get(
for (i=0; i<gpus.size(); i++) {
char buf2[256];
gpus[i].description(buf);
if (use_all || !cuda_compare(gpus[i], best, true)) {
if (in_vector(gpus[i].device_num, ignore_devs)) {
sprintf(buf2, "NVIDIA GPU %d (ignored by config): %s", gpus[i].device_num, buf);
} else if (use_all || !cuda_compare(gpus[i], best, true)) {
best.device_nums[best.count] = gpus[i].device_num;
best.count++;
sprintf(buf2, "NVIDIA GPU %d: %s", gpus[i].device_num, buf);
@ -502,9 +516,11 @@ void COPROC_CUDA::get(
descs.push_back(string(buf2));
}
COPROC_CUDA* ccp = new COPROC_CUDA;
*ccp = best;
coprocs.coprocs.push_back(ccp);
if (best.count) {
COPROC_CUDA* ccp = new COPROC_CUDA;
*ccp = best;
coprocs.coprocs.push_back(ccp);
}
}
bool COPROC_CUDA::is_usable() {
@ -758,7 +774,7 @@ int (*__calDeviceGetInfo)(CALdeviceinfo*, CALuint);
#endif
void COPROC_ATI::get(COPROCS& coprocs,
vector<string>& descs, vector<string>& warnings
vector<string>& descs, vector<string>& warnings, vector<int>& ignore_devs
) {
CALuint numDevices, cal_major, cal_minor, cal_imp;
CALdevice device;
@ -947,25 +963,33 @@ void COPROC_ATI::get(COPROCS& coprocs,
// same as for NVIDIA
COPROC_ATI best;
bool first = true;
for (unsigned int i=0; i<gpus.size(); i++) {
char buf[256], buf2[256];
if (i == 0) {
best = gpus[i];
} else if (gpus[i].peak_flops() > best.peak_flops()) {
best = gpus[i];
}
gpus[i].description(buf);
sprintf(buf2, "ATI GPU %d: %s", gpus[i].device_num, buf);
if (in_vector(gpus[i].device_num, ignore_devs)) {
sprintf(buf2, "ATI GPU %d (ignored by config): %s", gpus[i].device_num, buf);
} else {
if (first) {
best = gpus[i];
first = false;
} else if (gpus[i].peak_flops() > best.peak_flops()) {
best = gpus[i];
}
sprintf(buf2, "ATI GPU %d: %s", gpus[i].device_num, buf);
}
descs.push_back(buf2);
}
best.count = 0;
for (unsigned int i=0; i<gpus.size(); i++) {
best.device_nums[i] = i;
if (in_vector(gpus[i].device_num, ignore_devs)) continue;
best.device_nums[best.count] = i;
best.count++;
}
COPROC_ATI* ccp = new COPROC_ATI;
*ccp = best;
strcpy(ccp->type, "ATI");
ccp->count = numDevices;
coprocs.coprocs.push_back(ccp);
}

View File

@ -176,7 +176,9 @@ struct COPROCS {
#endif
void get(
bool use_all, std::vector<std::string> &descs,
std::vector<std::string> &warnings
std::vector<std::string> &warnings,
std::vector<int>& ignore_cuda_dev,
std::vector<int>& ignore_ati_dev
);
int parse(FILE*);
void summary_string(char*, int);
@ -249,7 +251,8 @@ struct COPROC_CUDA : public COPROC {
virtual ~COPROC_CUDA(){}
static void get(
COPROCS&, bool use_all,
std::vector<std::string>&, std::vector<std::string>&
std::vector<std::string>&, std::vector<std::string>&,
std::vector<int>& ignore_devs
);
void description(char*);
void clear();
@ -311,7 +314,8 @@ struct COPROC_ATI : public COPROC {
COPROC_ATI(): COPROC("ATI"){}
virtual ~COPROC_ATI(){}
static void get(COPROCS&,
std::vector<std::string>&, std::vector<std::string>&
std::vector<std::string>&, std::vector<std::string>&,
std::vector<int>& ignore_devs
);
void description(char*);
void clear();