Commit 93efb726bbf17901b945f2486cde5a9a7b01a87b

ckolivas 2012-02-22T19:38:01

Allow multiple different kernels to be chosen per device.

diff --git a/cgminer.c b/cgminer.c
index b5965a0..a57c25d 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -201,8 +201,6 @@ static bool config_loaded = false;
 	static char *opt_stderr_cmd = NULL;
 #endif // defined(unix)
 
-enum cl_kernels chosen_kernel;
-
 bool ping = true;
 
 struct sigaction termhandler, inthandler;
@@ -711,8 +709,8 @@ static struct opt_table opt_config_table[] = {
 		     opt_set_charp, opt_show_charp, &opt_kernel_path,
 	             "Specify a path to where the kernel .cl files are"),
 	OPT_WITH_ARG("--kernel|-k",
-		     opt_set_charp, NULL, &opt_kernel,
-		     "Select kernel to use (diablo, poclbm, phatk or diakgcn - default: auto)"),
+		     set_kernel, NULL, NULL,
+		     "Override kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated"),
 #endif
 	OPT_WITHOUT_ARG("--load-balance",
 		     set_loadbalance, &pool_strategy,
diff --git a/device-gpu.c b/device-gpu.c
index 9948bc2..6bc355b 100644
--- a/device-gpu.c
+++ b/device-gpu.c
@@ -41,7 +41,6 @@ extern int opt_g_threads;
 extern bool ping;
 extern bool opt_loginput;
 extern char *opt_kernel_path;
-extern char *opt_kernel;
 extern int gpur_thr_id;
 extern bool opt_noadl;
 extern bool have_opencl;
@@ -123,6 +122,47 @@ char *set_worksize(char *arg)
 	return NULL;
 }
 
+static enum cl_kernels select_kernel(char *arg)
+{
+	if (!strcmp(arg, "diablo"))
+		return KL_DIABLO;
+	if (!strcmp(arg, "diakgcn"))
+		return KL_DIAKGCN;
+	if (!strcmp(arg, "poclbm"))
+		return KL_POCLBM;
+	if (!strcmp(arg, "phatk"))
+		return KL_PHATK;
+	return KL_NONE;
+}
+
+char *set_kernel(char *arg)
+{
+	enum cl_kernels kern;
+	int i, device = 0;
+	char *nextptr;
+
+	nextptr = strtok(arg, ",");
+	if (nextptr == NULL)
+		return "Invalid parameters for set kernel";
+	kern = select_kernel(nextptr);
+	if (kern == KL_NONE)
+		return "Invalid parameter to set_kernel";
+	gpus[device++].kernel = kern;
+
+	while ((nextptr = strtok(NULL, ",")) != NULL) {
+		kern = select_kernel(nextptr);
+		if (kern == KL_NONE)
+			return "Invalid parameter to set_kernel";
+
+		gpus[device++].kernel = kern;
+	}
+	if (device == 1) {
+		for (i = device; i < MAX_GPUDEVICES; i++)
+			gpus[i].kernel = gpus[0].kernel;
+	}
+
+	return NULL;
+}
 #endif
 
 #ifdef HAVE_ADL
@@ -1054,23 +1094,6 @@ static void opencl_detect()
 	if (!nDevs)
 		return;
 
-	if (opt_kernel) {
-		if (strcmp(opt_kernel, "poclbm") &&
-		    strcmp(opt_kernel, "phatk") &&
-		    strcmp(opt_kernel, "diakgcn") &&
-		    strcmp(opt_kernel, "diablo"))
-			quit(1, "Invalid kernel name specified - must be diablo, poclbm, phatk or diakgcn");
-		if (!strcmp(opt_kernel, "diakgcn"))
-			chosen_kernel = KL_DIAKGCN;
-		else if (!strcmp(opt_kernel, "poclbm"))
-			chosen_kernel = KL_POCLBM;
-		else if (!strcmp(opt_kernel, "diablo"))
-			chosen_kernel = KL_DIABLO;
-		else
-			chosen_kernel = KL_PHATK;
-	} else
-		chosen_kernel = KL_NONE;
-
 	for (i = 0; i < nDevs; ++i) {
 		struct cgpu_info *cgpu;
 
diff --git a/device-gpu.h b/device-gpu.h
index 2c8d1e3..5ee7d8d 100644
--- a/device-gpu.h
+++ b/device-gpu.h
@@ -17,6 +17,7 @@ extern char *set_temp_target(char *arg);
 extern char *set_intensity(char *arg);
 extern char *set_vector(char *arg);
 extern char *set_worksize(char *arg);
+extern char *set_kernel(char *arg);
 void manage_gpu(void);
 extern void pause_dynamic_threads(int gpu);
 
diff --git a/miner.h b/miner.h
index a8fad8c..a08789c 100644
--- a/miner.h
+++ b/miner.h
@@ -213,6 +213,14 @@ enum dev_enable {
 	DEV_RECOVER,
 };
 
+enum cl_kernels {
+	KL_NONE,
+	KL_POCLBM,
+	KL_PHATK,
+	KL_DIAKGCN,
+	KL_DIABLO,
+};
+
 struct cgpu_info {
 	int cgminer_id;
 	struct device_api *api;
@@ -243,6 +251,7 @@ struct cgpu_info {
 	bool dynamic;
 	cl_uint vwidth;
 	size_t work_size;
+	enum cl_kernels kernel;
 
 	float temp;
 	int cutofftemp;
@@ -587,14 +596,6 @@ struct work {
 	UT_hash_handle hh;
 };
 
-enum cl_kernels {
-	KL_NONE,
-	KL_POCLBM,
-	KL_PHATK,
-	KL_DIAKGCN,
-	KL_DIABLO,
-};
-
 extern void get_datestamp(char *, struct timeval *);
 bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
 extern void tailsprintf(char *f, const char *fmt, ...);
@@ -614,7 +615,6 @@ extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime);
 extern void tq_freeze(struct thread_q *tq);
 extern void tq_thaw(struct thread_q *tq);
 extern bool successful_connect;
-extern enum cl_kernels chosen_kernel;
 extern void adl(void);
 
 #endif /* __MINER_H__ */
diff --git a/ocl.c b/ocl.c
index 2c9ae84..a9d048d 100644
--- a/ocl.c
+++ b/ocl.c
@@ -364,7 +364,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
 	char filename[255];
 	char numbuf[10];
 
-	if (chosen_kernel == KL_NONE) {
+	if (gpus[gpu].kernel == KL_NONE) {
 		/* If no binary is available, and we have a card that suffers with diablo
 		 * on SDK2.6, use the poclbm kernel instead if one has not been
 		 * selected. */
@@ -380,7 +380,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
 			clState->chosen_kernel = KL_DIABLO;
 		}
 	} else
-		clState->chosen_kernel = chosen_kernel;
+		clState->chosen_kernel = gpus[gpu].kernel;
 
 	switch (clState->chosen_kernel) {
 		case KL_POCLBM: