From f5f089f5b4f8831dccc6e8e32e7e2866ce8b306e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 23 Apr 2012 17:40:47 +1000 Subject: [PATCH] Add a --gpu-map option which will allow arbitrarily mapping ADL devices to OpenCL devices for instances where association by enumeration alone fails. --- adl.c | 18 +++++++++++++----- cgminer.c | 3 +++ driver-opencl.c | 30 ++++++++++++++++++++++++++++++ driver-opencl.h | 1 + miner.h | 2 ++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/adl.c b/adl.c index c79e2eca..b2c00fc8 100644 --- a/adl.c +++ b/adl.c @@ -268,12 +268,11 @@ void init_adl(int nDevs) * one. Now since there's no way of correlating the * opencl enumerated devices and the ADL enumerated * ones, we have to assume they're in the same order.*/ - if (++devices > nDevs) { + if (++devices > nDevs && devs_match) { applog(LOG_ERR, "ADL found more devices than opencl!"); applog(LOG_ERR, "There is possibly at least one GPU that doesn't support OpenCL"); + applog(LOG_ERR, "Use the gpu map feature to reliably map OpenCL to ADL"); devs_match = false; - devices = nDevs; - break; } last_adapter = lpAdapterID; @@ -286,16 +285,25 @@ void init_adl(int nDevs) if (devices < nDevs) { applog(LOG_ERR, "ADL found less devices than opencl!"); applog(LOG_ERR, "There is possibly more than one display attached to a GPU"); + applog(LOG_ERR, "Use the gpu map feature to reliably map OpenCL to ADL"); devs_match = false; } - for (i = 0; i < nDevs; i++) { + for (i = 0; i < devices; i++) { vadapters[i].virtual_gpu = i; vadapters[i].id = adapters[i].id; } + /* Apply manually provided OpenCL to ADL mapping, if any */ + for (i = 0; i < nDevs; i++) { + if (gpus[i].mapped) { + vadapters[gpus[i].virtual_adl].virtual_gpu = i; + applog(LOG_INFO, "Mapping OpenCL device %d to ADL device %d", i, gpus[i].virtual_adl); + } + } + if (!devs_match) { - applog(LOG_ERR, "WARNING: Number of OpenCL and ADL devices does not match!"); + applog(LOG_ERR, "WARNING: Number of OpenCL and ADL devices did not match!"); applog(LOG_ERR, "Hardware monitoring may NOT match up with devices!"); } else if (opt_reorder) { /* Windows has some kind of random ordering for bus number IDs and diff --git a/cgminer.c b/cgminer.c index e5655463..0cca83ec 100644 --- a/cgminer.c +++ b/cgminer.c @@ -714,6 +714,9 @@ static struct opt_table opt_config_table[] = { OPT_WITH_ARG("--gpu-fan", set_gpu_fan, NULL, NULL, "GPU fan percentage range - one value, range and/or comma separated list (e.g. 0-85,85,65)"), + OPT_WITH_ARG("--gpu-map", + set_gpu_map, NULL, NULL, + "Map OpenCL to ADL device order manually, paired CSV (e.g. 1:0,2:1 maps OpenCL 1 to ADL 0, 2 to 1)"), OPT_WITH_ARG("--gpu-memclock", set_gpu_memclock, NULL, NULL, "Set the GPU memory (over)clock in Mhz - one value for all or separate by commas for per card"), diff --git a/driver-opencl.c b/driver-opencl.c index da9a597c..98d9fc14 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -171,6 +171,36 @@ char *set_kernel(char *arg) #endif #ifdef HAVE_ADL +/* This function allows us to map an adl device to an opencl device for when + * simple enumeration has failed to match them. */ +char *set_gpu_map(char *arg) +{ + int val1 = 0, val2 = 0; + char *nextptr; + + nextptr = strtok(arg, ","); + if (nextptr == NULL) + return "Invalid parameters for set gpu map"; + if (sscanf(arg, "%d:%d", &val1, &val2) != 2) + return "Invalid description for map pair"; + if (val1 < 0 || val1 > MAX_GPUDEVICES || val2 < 0 || val2 > MAX_GPUDEVICES) + return "Invalid value passed to set_gpu_map"; + + gpus[val1].virtual_adl = val2; + gpus[val1].mapped = true; + + while ((nextptr = strtok(NULL, ",")) != NULL) { + if (sscanf(nextptr, "%d:%d", &val1, &val2) != 2) + return "Invalid description for map pair"; + if (val1 < 0 || val1 > MAX_GPUDEVICES || val2 < 0 || val2 > MAX_GPUDEVICES) + return "Invalid value passed to set_gpu_map"; + gpus[val1].virtual_adl = val2; + gpus[val1].mapped = true; + } + + return NULL; +} + void get_intrange(char *arg, int *val1, int *val2) { if (sscanf(arg, "%d-%d", val1, val2) == 1) { diff --git a/driver-opencl.h b/driver-opencl.h index 5ee7d8df..600bd854 100644 --- a/driver-opencl.h +++ b/driver-opencl.h @@ -6,6 +6,7 @@ extern char *print_ndevs_and_exit(int *ndevs); extern void *reinit_gpu(void *userdata); +extern char *set_gpu_map(char *arg); extern char *set_gpu_engine(char *arg); extern char *set_gpu_fan(char *arg); extern char *set_gpu_memclock(char *arg); diff --git a/miner.h b/miner.h index 8cddd513..81d535ee 100644 --- a/miner.h +++ b/miner.h @@ -282,7 +282,9 @@ struct cgpu_info { unsigned int max_hashes; + bool mapped; int virtual_gpu; + int virtual_adl; int intensity; bool dynamic; char *kname;