mirror of https://github.com/BOINC/boinc.git
- 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:
parent
f4a2c9cc0d
commit
4bf2ef5198
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
10
lib/coproc.h
10
lib/coproc.h
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue