Browse Source

opencl: Simplify kernel-specific data handling

Luke Dashjr 11 years ago
parent
commit
a9f278b67a
14 changed files with 139 additions and 114 deletions
  1. 2 0
      driver-cpu.c
  2. 19 70
      driver-opencl.c
  3. 18 4
      driver-opencl.h
  4. 52 0
      miner.c
  5. 8 2
      miner.h
  6. 31 13
      ocl.c
  7. 2 18
      ocl.h
  8. 1 1
      opencl/diablo.cl
  9. 1 1
      opencl/diakgcn.cl
  10. 1 1
      opencl/phatk.cl
  11. 1 1
      opencl/poclbm.cl
  12. 1 1
      opencl/psw.cl
  13. 1 1
      opencl/scrypt.cl
  14. 1 1
      opencl/zuikkis.cl

+ 2 - 0
driver-cpu.c

@@ -786,6 +786,8 @@ CPUSearch:
 				func = sha256_funcs[opt_algo];
 				break;
 #endif
+			case POW_ALGORITHM_COUNT:
+				break;
 		}
 		if (unlikely(!func))
 			applogr(0, LOG_ERR, "%"PRIpreprv": Unknown mining algorithm", thr->cgpu->proc_repr);

+ 19 - 70
driver-opencl.c

@@ -403,27 +403,17 @@ bool _set_kernel(struct cgpu_info * const cgpu, const char *_val)
 	
 	int dummy_srclen;
 	enum cl_kernels interface;
-	char *src = opencl_kernel_source(filename, &dummy_srclen, &interface);
+	struct mining_algorithm *malgo;
+	char *src = opencl_kernel_source(filename, &dummy_srclen, &interface, &malgo);
 	if (!src)
 		return false;
 	free(src);
-	
-	char **kfp =
-#ifdef USE_SHA256D
-		&data->kernel_file_sha256d;
-#else
-		NULL;
-#endif
-#ifdef USE_SCRYPT
-	if (interface == KL_SCRYPT)
-		kfp = &data->kernel_file_scrypt;
-#endif
-#ifndef USE_SHA256D
-	if (!kfp)
+	if (!malgo)
 		return false;
-#endif
-	free(*kfp);
-	*kfp = strdup(_val);
+	
+	struct opencl_kernel_info * const kernelinfo = &data->kernelinfo[malgo->algo];
+	free(kernelinfo->file);
+	kernelinfo->file = strdup(_val);
 	
 	return true;
 }
@@ -1684,61 +1674,16 @@ const struct opencl_kernel_info *opencl_scanhash_get_kernel(struct cgpu_info * c
 {
 	struct opencl_device_data * const data = cgpu->device_data;
 	struct opencl_kernel_info *kernelinfo = NULL;
-	char *kernel_file;
-	switch (malgo->algo)
+	kernelinfo = &data->kernelinfo[malgo->algo];
+	if (!kernelinfo->file)
 	{
-#ifdef USE_SHA256D
-		case POW_SHA256D:
-			kernelinfo = &clState->kernel_sha256d;
-			if (!data->kernel_file_sha256d)
-			{
-				const char * const vbuff = clState->platform_ver_str;
-				if (clState->is_mesa)
-				{
-					applog(LOG_INFO, "Selecting phatk kernel for Mesa");
-					data->kernel_file_sha256d = strdup("phatk");
-				}
-				else  /* Detect all 2.6 SDKs not with Tahiti and use diablo kernel */
-				if (!strstr(cgpu->name, "Tahiti") &&
-				   (strstr(vbuff, "844.4") ||  // Linux 64 bit ATI 2.6 SDK
-				    strstr(vbuff, "851.4") ||  // Windows 64 bit ""
-				    strstr(vbuff, "831.4") ||
-				    strstr(vbuff, "898.1") ||  // 12.2 driver SDK 
-				    strstr(vbuff, "923.1") ||  // 12.4
-				    strstr(vbuff, "938.2") ||  // SDK 2.7
-				    strstr(vbuff, "1113.2")))  // SDK 2.8
-				{
-					applog(LOG_INFO, "Selecting diablo kernel");
-					data->kernel_file_sha256d = strdup("diablo");
-				}
-				else  /* Detect all 7970s, older ATI and NVIDIA and use poclbm */
-				if (strstr(cgpu->name, "Tahiti") || !clState->hasBitAlign)
-				{
-					applog(LOG_INFO, "Selecting poclbm kernel");
-					data->kernel_file_sha256d = strdup("poclbm");
-				}
-				else  /* Use phatk for the rest R5xxx R6xxx */
-				{
-					applog(LOG_INFO, "Selecting phatk kernel");
-					data->kernel_file_sha256d = strdup("phatk");
-				}
-			}
-			kernel_file = data->kernel_file_sha256d;
-			break;
-#endif
-#ifdef USE_SCRYPT
-		case POW_SCRYPT:
-			kernelinfo = &clState->kernel_scrypt;
-			BFGINIT(data->kernel_file_scrypt, strdup("scrypt"));
-			kernel_file = data->kernel_file_scrypt;
-			break;
-#endif
+		kernelinfo->file = malgo->opencl_get_default_kernel_file(malgo, cgpu, clState);
+		if (!kernelinfo->file)
+			applogr(NULL, LOG_ERR, "%s: Unsupported mining algorithm", cgpu->dev_repr);
 	}
-	if (!kernelinfo)
-		applogr(NULL, LOG_ERR, "%s: Unsupported mining algorithm", cgpu->dev_repr);
 	if (!kernelinfo->loaded)
 	{
-		if (!opencl_load_kernel(cgpu, clState, cgpu->name, kernelinfo, kernel_file, malgo))
+		if (!opencl_load_kernel(cgpu, clState, cgpu->name, kernelinfo, kernelinfo->file, malgo))
 			applogr(NULL, LOG_ERR, "%s: Failed to load kernel", cgpu->dev_repr);
 		
 		kernelinfo->queue_kernel_parameters = kernel_interfaces[kernelinfo->interface].queue_kernel_parameters_func;
@@ -1874,11 +1819,15 @@ void opencl_clean_kernel_info(struct opencl_kernel_info * const kinfo)
 
 static void opencl_thread_shutdown(struct thr_info *thr)
 {
+	struct cgpu_info * const cgpu = thr->cgpu;
+	struct opencl_device_data * const data = cgpu->device_data;
 	const int thr_id = thr->id;
 	_clState *clState = clStates[thr_id];
 
-	opencl_clean_kernel_info(&clState->kernel_sha256d);
-	opencl_clean_kernel_info(&clState->kernel_scrypt);
+	for (unsigned i = 0; i < (unsigned)POW_ALGORITHM_COUNT; ++i)
+	{
+		opencl_clean_kernel_info(&data->kernelinfo[i]);
+	}
 	clReleaseCommandQueue(clState->commandQueue);
 	clReleaseContext(clState->context);
 }

+ 18 - 4
driver-opencl.h

@@ -21,6 +21,22 @@ enum opencl_binary_usage {
 
 static const float intensity_not_set = FLT_MAX;
 
+struct opencl_kernel_info;
+struct _clState;
+
+typedef cl_int (*queue_kernel_parameters_func_t)(const struct opencl_kernel_info *, struct _clState *, struct work *, cl_uint);
+
+struct opencl_kernel_info {
+	char *file;
+	bool loaded;
+	cl_program program;
+	cl_kernel kernel;
+	bool goffset;
+	enum cl_kernels interface;
+	size_t wsize;
+	queue_kernel_parameters_func_t queue_kernel_parameters;
+};
+
 struct opencl_device_data {
 	bool mapped;
 	int virtual_gpu;
@@ -32,14 +48,12 @@ struct opencl_device_data {
 	
 	cl_uint vwidth;
 	size_t work_size;
-#ifdef USE_SHA256D
-	char *kernel_file_sha256d;
-#endif
 	cl_ulong max_alloc;
 	
+	struct opencl_kernel_info kernelinfo[POW_ALGORITHM_COUNT];
+	
 	enum opencl_binary_usage opt_opencl_binaries;
 #ifdef USE_SCRYPT
-	char *kernel_file_scrypt;
 	int lookup_gap;
 	size_t thread_concurrency;
 	size_t shaders;

+ 52 - 0
miner.c

@@ -1049,6 +1049,50 @@ unsigned long opencl_intensity_to_oclthreads_sha256d(float intensity)
 #endif
 
 #ifdef USE_SHA256D
+#ifdef USE_OPENCL
+
+#include "ocl.h"
+
+static
+char *opencl_get_default_kernel_file_sha256d(const struct mining_algorithm * const malgo, struct cgpu_info * const cgpu, struct _clState * const clState)
+{
+	const char * const vbuff = clState->platform_ver_str;
+	
+	if (clState->is_mesa)
+	{
+		applog(LOG_INFO, "Selecting phatk kernel for Mesa");
+		return strdup("phatk");
+	}
+	
+	/* Detect all 2.6 SDKs not with Tahiti and use diablo kernel */
+	if (!strstr(cgpu->name, "Tahiti") &&
+	   (strstr(vbuff, "844.4") ||  // Linux 64 bit ATI 2.6 SDK
+	    strstr(vbuff, "851.4") ||  // Windows 64 bit ""
+	    strstr(vbuff, "831.4") ||
+	    strstr(vbuff, "898.1") ||  // 12.2 driver SDK
+	    strstr(vbuff, "923.1") ||  // 12.4
+	    strstr(vbuff, "938.2") ||  // SDK 2.7
+	    strstr(vbuff, "1113.2")))  // SDK 2.8
+	{
+		applog(LOG_INFO, "Selecting diablo kernel");
+		return strdup("diablo");
+	}
+	
+	/* Detect all 7970s, older ATI and NVIDIA and use poclbm */
+	if (strstr(cgpu->name, "Tahiti") || !clState->hasBitAlign)
+	{
+		applog(LOG_INFO, "Selecting poclbm kernel");
+		return strdup("poclbm");
+	}
+	
+	/* Use phatk for the rest R5xxx R6xxx */
+	{
+		applog(LOG_INFO, "Selecting phatk kernel");
+		return strdup("phatk");
+	}
+}
+#endif  /* USE_OPENCL */
+
 static struct mining_algorithm malgo_sha256d = {
 	.name = "SHA256d",
 	.aliases = "SHA256d|SHA256|SHA2",
@@ -1066,6 +1110,7 @@ static struct mining_algorithm malgo_sha256d = {
 	.opencl_intensity_to_oclthreads = opencl_intensity_to_oclthreads_sha256d,
 	.opencl_min_oclthreads =       0x20,  // intensity -10
 	.opencl_max_oclthreads = 0x20000000,  // intensity  14
+	.opencl_get_default_kernel_file = opencl_get_default_kernel_file_sha256d,
 #endif
 };
 #endif
@@ -1084,6 +1129,12 @@ unsigned long opencl_intensity_to_oclthreads_scrypt(float intensity)
 {
 	return pow(2, intensity);
 }
+
+static
+char *opencl_get_default_kernel_file_scrypt(const struct mining_algorithm * const malgo, struct cgpu_info * const cgpu, struct _clState * const clState)
+{
+	return strdup("scrypt");
+}
 #endif
 
 static struct mining_algorithm malgo_scrypt = {
@@ -1101,6 +1152,7 @@ static struct mining_algorithm malgo_scrypt = {
 	.opencl_intensity_to_oclthreads = opencl_intensity_to_oclthreads_scrypt,
 	.opencl_min_oclthreads =      0x100,  // intensity   8
 	.opencl_max_oclthreads = 0x20000000,  // intensity  31
+	.opencl_get_default_kernel_file = opencl_get_default_kernel_file_scrypt,
 #endif
 };
 

+ 8 - 2
miner.h

@@ -278,11 +278,12 @@ struct gpu_adl {
 
 enum pow_algorithm {
 #ifdef USE_SHA256D
-	POW_SHA256D = 1,
+	POW_SHA256D,
 #endif
 #ifdef USE_SCRYPT
-	POW_SCRYPT  = 2,
+	POW_SCRYPT,
 #endif
+	POW_ALGORITHM_COUNT,
 };
 
 struct api_data;
@@ -1123,6 +1124,10 @@ struct blockchain_info {
 	char currentblk_first_seen_time_str[0x20];  // was global blocktime
 };
 
+struct _clState;
+struct cgpu_info;
+struct mining_algorithm;
+
 struct mining_algorithm {
 	const char *name;
 	const char *aliases;
@@ -1146,6 +1151,7 @@ struct mining_algorithm {
 	unsigned long (*opencl_intensity_to_oclthreads)(float intensity);
 	unsigned long opencl_min_oclthreads;
 	unsigned long opencl_max_oclthreads;
+	char *(*opencl_get_default_kernel_file)(const struct mining_algorithm *, struct cgpu_info *, struct _clState *);
 #endif
 };
 

+ 31 - 13
ocl.c

@@ -258,24 +258,42 @@ char *file_contents(const char *filename, int *length)
 	return (char*)buffer;
 }
 
-char *opencl_kernel_source(const char * const filename, int * const out_sourcelen, enum cl_kernels * const out_kinterface)
+static
+void extract_word(char * const buf, const size_t bufsz, const char ** const endptr, const char *s)
+{
+	const char *q;
+	for ( ; s[0] && isspace(s[0]); ++s)
+		if (s[0] == '\n' || s[0] == '\r')
+			break;
+	for (q = s; q[0] && !isspace(q[0]); ++q)
+	{}  // Find end of string
+	size_t len = q - s;
+	if (len >= bufsz)
+		len = bufsz - 1;
+	memcpy(buf, s, len);
+	buf[len] = '\0';
+	if (endptr)
+		*endptr = q;
+}
+
+char *opencl_kernel_source(const char * const filename, int * const out_sourcelen, enum cl_kernels * const out_kinterface, struct mining_algorithm ** const out_malgo)
 {
 	char *source = file_contents(filename, out_sourcelen);
 	if (!source)
 		return NULL;
-	char *s = strstr(source, "kernel-interface:"), *q;
+	char *s = strstr(source, "kernel-interface:");
 	if (s)
 	{
-		for (s = &s[17]; s[0] && isspace(s[0]); ++s)
-			if (s[0] == '\n' || s[0] == '\r')
-				break;
-		for (q = s; q[0] && !isspace(q[0]); ++q)
-		{}  // Find end of string
-		const size_t kinamelen = q - s;
-		char kiname[kinamelen + 1];
-		memcpy(kiname, s, kinamelen);
-		kiname[kinamelen] = '\0';
-		*out_kinterface = select_kernel(kiname);
+		const char *q;
+		char buf[0x20];
+		extract_word(buf, sizeof(buf), &q, &s[17]);
+		*out_kinterface = select_kernel(buf);
+		
+		if (out_malgo && (q[0] == '\t' || q[0] == ' '))
+		{
+			extract_word(buf, sizeof(buf), &q, q);
+			*out_malgo = mining_algorithm_by_alias(buf);
+		}
 	}
 	else
 		*out_kinterface = KL_NONE;
@@ -718,7 +736,7 @@ bool opencl_load_kernel(struct cgpu_info * const cgpu, _clState * const clState,
 	snprintf(filename, sizeof(filename), "%s.cl", kernel_file);
 	snprintf(binaryfilename, sizeof(filename), "%s", kernel_file);
 	int pl;
-	char *source = opencl_kernel_source(filename, &pl, &kernelinfo->interface);
+	char *source = opencl_kernel_source(filename, &pl, &kernelinfo->interface, NULL);
 	if (!source)
 		return false;
 	{

+ 2 - 18
ocl.h

@@ -1,8 +1,6 @@
 #ifndef BFG_OCL_H
 #define BFG_OCL_H
 
-#include "config.h"
-
 #include <stdbool.h>
 #include <stdio.h>
 
@@ -10,21 +8,10 @@
 
 #include "miner.h"
 
+struct mining_algorithm;
 struct opencl_kernel_info;
 typedef struct _clState _clState;
 
-typedef cl_int (*queue_kernel_parameters_func_t)(const struct opencl_kernel_info *, _clState *, struct work *, cl_uint);
-
-struct opencl_kernel_info {
-	bool loaded;
-	cl_program program;
-	cl_kernel kernel;
-	bool goffset;
-	enum cl_kernels interface;
-	size_t wsize;
-	queue_kernel_parameters_func_t queue_kernel_parameters;
-};
-
 struct _clState {
 	cl_device_id devid;
 	char *platform_ver_str;
@@ -33,9 +20,6 @@ struct _clState {
 	cl_context context;
 	cl_command_queue commandQueue;
 	
-	struct opencl_kernel_info kernel_sha256d;
-	struct opencl_kernel_info kernel_scrypt;
-	
 	cl_mem outputBuffer;
 #ifdef USE_SCRYPT
 	cl_mem CLbuffer0;
@@ -53,7 +37,7 @@ struct _clState {
 
 extern FILE *opencl_open_kernel(const char *filename);
 extern char *file_contents(const char *filename, int *length);
-extern char *opencl_kernel_source(const char *filename, int *out_sourcelen, enum cl_kernels *out_kinterface);
+extern char *opencl_kernel_source(const char *filename, int *out_sourcelen, enum cl_kernels *out_kinterface, struct mining_algorithm **);
 extern int clDevicesNum(void);
 extern _clState *opencl_create_clState(unsigned int gpu, char *name, size_t nameSize);
 extern bool opencl_load_kernel(struct cgpu_info *, _clState *clState, const char *name, struct opencl_kernel_info *, const char *kernel_file, const struct mining_algorithm *);

+ 1 - 1
opencl/diablo.cl

@@ -17,7 +17,7 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-// kernel-interface: diablo
+// kernel-interface: diablo SHA256d
 
 #ifdef VECTORS4
 	typedef uint4 z;

+ 1 - 1
opencl/diakgcn.cl

@@ -3,7 +3,7 @@
 // Parts and / or ideas for this kernel are based upon the public-domain poclbm project, the phatk kernel by Phateus and the DiabloMiner kernel by DiabloD3.
 // The kernel was rewritten by me (Diapolo) and is still public-domain!
 
-// kernel-interface: diakgcn
+// kernel-interface: diakgcn SHA256d
 
 #ifdef VECTORS4
 	typedef uint4 u;

+ 1 - 1
opencl/phatk.cl

@@ -2,7 +2,7 @@
 // I have therefore decided to keep it public-domain.
 // Modified version copyright 2011-2012 Con Kolivas
 
-// kernel-interface: phatk
+// kernel-interface: phatk SHA256d
 
 #ifdef VECTORS4
 	typedef uint4 u;

+ 1 - 1
opencl/poclbm.cl

@@ -5,7 +5,7 @@
 // This file is taken and modified from the public-domain poclbm project, and
 // we have therefore decided to keep it public-domain in Phoenix.
 
-// kernel-interface: poclbm
+// kernel-interface: poclbm SHA256d
 
 #ifdef VECTORS4
 	typedef uint4 u;

+ 1 - 1
opencl/psw.cl

@@ -29,7 +29,7 @@
  * online backup system.
  */
 
-// kernel-interface: scrypt
+// kernel-interface: scrypt scrypt
 
 __constant uint ES[2] = { 0x00FF00FF, 0xFF00FF00 };
 __constant uint K[] = {

+ 1 - 1
opencl/scrypt.cl

@@ -31,7 +31,7 @@
  * online backup system.
  */
 
-// kernel-interface: scrypt
+// kernel-interface: scrypt scrypt
 
 __constant uint ES[2] = { 0x00FF00FF, 0xFF00FF00 };
 __constant uint K[] = {

+ 1 - 1
opencl/zuikkis.cl

@@ -28,7 +28,7 @@
  * online backup system.
  */
 
-// kernel-interface: scrypt
+// kernel-interface: scrypt scrypt
 
 __constant uint ES[2] = { 0x00FF00FF, 0xFF00FF00 };
 __constant uint K[] = {