Add a --gpu-map option which will allow arbitrarily mapping ADL devices to OpenCL devices for instances where association by enumeration alone fails.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
diff --git a/adl.c b/adl.c
index c79e2ec..b2c00fc 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 e565546..0cca83e 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 da9a597..98d9fc1 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 5ee7d8d..600bd85 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 8cddd51..81d535e 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;