Browse Source

Merge branch 'ckolivas-master' into merge-ckolivas-master

Znort 987 14 years ago
parent
commit
eed634a3ab
4 changed files with 220 additions and 255 deletions
  1. 75 75
      main.c
  2. 0 6
      miner.h
  3. 141 170
      ocl.c
  4. 4 4
      ocl.h

+ 75 - 75
main.c

@@ -217,6 +217,8 @@ int longpoll_thr_id;
 static int stage_thr_id;
 static int watchdog_thr_id;
 static int input_thr_id;
+static int gpur_thr_id;
+static int cpur_thr_id;
 static int total_threads;
 
 struct work_restart *work_restart = NULL;
@@ -3464,7 +3466,6 @@ static void *gpuminer_thread(void *userdata)
 	uint32_t *res, *blank_res;
 	double gpu_ms_average = 7;
 	int gpu = dev_from_id(thr_id);
-	struct cgpu_info *cgpu = mythr->cgpu;
 
 	size_t globalThreads[1];
 	size_t localThreads[1];
@@ -3476,7 +3477,7 @@ static void *gpuminer_thread(void *userdata)
 
 	struct work *work = make_work();
 	unsigned int threads;
-	unsigned const int vectors = cgpu->vwidth;
+	unsigned const int vectors = clState->preferred_vwidth;
 	unsigned int hashes;
 	unsigned int hashes_done = 0;
 
@@ -3513,7 +3514,7 @@ static void *gpuminer_thread(void *userdata)
 	}
 
 	gettimeofday(&tv_start, NULL);
-	localThreads[0] = cgpu->work_size;
+	localThreads[0] = clState->work_size;
 	set_threads_hashes(vectors, &threads, &hashes, &globalThreads[0],
 			   localThreads[0]);
 
@@ -3527,7 +3528,7 @@ static void *gpuminer_thread(void *userdata)
 	if (unlikely(status != CL_SUCCESS))
 		{ applog(LOG_ERR, "Error: clEnqueueWriteBuffer failed."); goto out; }
 
-	cgpu->status = LIFE_WELL;
+	mythr->cgpu->status = LIFE_WELL;
 	if (opt_debug)
 		applog(LOG_DEBUG, "Popping ping in gpuminer thread");
 
@@ -3654,7 +3655,7 @@ static void *gpuminer_thread(void *userdata)
 		}
 		if (unlikely(!gpu_devices[gpu])) {
 			applog(LOG_WARNING, "Thread %d being disabled", thr_id);
-			mythr->rolling = cgpu->rolling = 0;
+			mythr->rolling = mythr->cgpu->rolling = 0;
 			if (opt_debug)
 				applog(LOG_DEBUG, "Popping wakeup ping in gpuminer thread");
 
@@ -3839,6 +3840,7 @@ static void restart_longpoll(void)
 
 static void *reinit_cpu(void *userdata)
 {
+	pthread_detach(pthread_self());
 #if 0
 	struct cgpu_info *cgpu = (struct cgpu_info *)userdata;
 	int cpu = cgpu->cpu_gpu;
@@ -3870,16 +3872,34 @@ static void *reinit_cpu(void *userdata)
 }
 
 #ifdef HAVE_OPENCL
+/* We have only one thread that ever re-initialises GPUs, thus if any GPU
+ * init command fails due to a completely wedged GPU, the thread will never
+ * return, unable to harm other GPUs. If it does return, it means we only had
+ * a soft failure and then the reinit_gpu thread is ready to tackle another
+ * GPU */
 static void *reinit_gpu(void *userdata)
 {
-	struct cgpu_info *cgpu = (struct cgpu_info *)userdata;
-	int gpu = cgpu->cpu_gpu;
+	struct thr_info *mythr = userdata;
+	struct cgpu_info *cgpu;
 	struct thr_info *thr;
 	struct timeval now;
-	_clState *clState;
+	char name[256];
 	int thr_id;
+	int gpu;
+
+	pthread_detach(pthread_self());
+
+select_cgpu:
+	cgpu = tq_pop(mythr->q, NULL);
+	if (!cgpu)
+		goto out;
 
-	/* Send threads message to stop */
+	if (clDevicesNum() != nDevs) {
+		applog(LOG_WARNING, "Hardware not reporting same number of active devices, will not attempt to restart GPU");
+		goto out;
+	}
+
+	gpu = cgpu->cpu_gpu;
 	gpu_devices[gpu] = false;
 
 	for (thr_id = 0; thr_id < gpu_threads; thr_id ++) {
@@ -3889,9 +3909,16 @@ static void *reinit_gpu(void *userdata)
 		thr = &thr_info[thr_id];
 		thr->rolling = thr->cgpu->rolling = 0;
 		if (!pthread_cancel(*thr->pth)) {
-			applog(LOG_WARNING, "Thread still exists, killing it off");
+			applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id);
 		} else
-			applog(LOG_WARNING, "Thread no longer exists!");
+			applog(LOG_WARNING, "Thread %d no longer exists", thr_id);
+	}
+
+	for (thr_id = 0; thr_id < gpu_threads; thr_id ++) {
+		if (dev_from_id(thr_id) != gpu)
+			continue;
+
+		thr = &thr_info[thr_id];
 
 		/* Lose this ram cause we may get stuck here! */
 		//tq_freeze(thr->q);
@@ -3900,13 +3927,16 @@ static void *reinit_gpu(void *userdata)
 		if (!thr->q)
 			quit(1, "Failed to tq_new in reinit_gpu");
 
-		/* Create a new clstate */
-		applog(LOG_WARNING, "Attempting to create a new clState");
-		clState = initCQ(clStates[thr_id], gpu);
-
 		/* Lose this ram cause we may dereference in the dying thread! */
 		//free(clState);
-		applog(LOG_WARNING, "Command successful, attempting to create new thread");
+
+		applog(LOG_INFO, "Reinit GPU thread %d", thr_id);
+		clStates[thr_id] = initCl(gpu, name, sizeof(name));
+		if (!clStates[thr_id]) {
+			applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id);
+			goto out;
+		}
+		applog(LOG_INFO, "initCl() finished. Found %s", name);
 
 		if (unlikely(thr_info_create(thr, NULL, gpuminer_thread, thr))) {
 			applog(LOG_ERR, "thread %d create failed", thr_id);
@@ -3918,70 +3948,31 @@ static void *reinit_gpu(void *userdata)
 	gettimeofday(&now, NULL);
 	get_datestamp(cgpu->init, &now);
 
-	/* Try to re-enable it */
 	gpu_devices[gpu] = true;
-	for (thr_id = 0; thr_id < gpu_threads; thr_id ++) {
-		thr = &thr_info[thr_id];
-		if (dev_from_id(thr_id) == gpu)
-			tq_push(thr->q, &ping);
-	}
-
-	return NULL;
-}
-
-static void *ping_gputhread(void *userdata)
-{
-	struct cgpu_info *cgpu = (struct cgpu_info *)userdata;
-	int gpu = cgpu->cpu_gpu;
-	struct thr_info *thr;
-	_clState *clState;
-	int thr_id;
-
 	for (thr_id = 0; thr_id < gpu_threads; thr_id ++) {
 		if (dev_from_id(thr_id) != gpu)
 			continue;
 
 		thr = &thr_info[thr_id];
-		clState = clStates[thr_id];
-		tq_push(thr->q, &ping);
-		applog(LOG_WARNING, "Attempting to flush command queue of thread %d", thr_id);
-		clFlush(clState->commandQueue);
-		clFinish(clState->commandQueue);
 		tq_push(thr->q, &ping);
 	}
 
+	goto select_cgpu;
+out:
 	return NULL;
 }
-
-static void ping_gpu(struct cgpu_info *cgpu)
-{
-	pthread_t ping_thread;
-
-	if (unlikely(pthread_create(&ping_thread, NULL, ping_gputhread, (void *)cgpu)))
-		applog(LOG_ERR, "Failed to create ping thread");
-}
 #else
 static void *reinit_gpu(void *userdata)
 {
 }
-
-static void ping_gpu(struct cgpu_info *cgpu)
-{
-}
 #endif
 
 static void reinit_device(struct cgpu_info *cgpu)
 {
-	pthread_t resus_thread;
-	void *reinit;
-
 	if (cgpu->is_gpu)
-		reinit = reinit_gpu;
+		tq_push(thr_info[gpur_thr_id].q, cgpu);
 	else
-		reinit = reinit_cpu;
-
-	if (unlikely(pthread_create(&resus_thread, NULL, reinit, (void *)cgpu)))
-		applog(LOG_ERR, "Failed to create reinit thread");
+		tq_push(thr_info[cpur_thr_id].q, cgpu);
 }
 
 /* Determine which are the first threads belonging to a device and if they're
@@ -4080,7 +4071,7 @@ static void *watchdog_thread(void *userdata)
 				gpus[gpu].status = LIFE_SICK;
 				applog(LOG_ERR, "Thread %d idle for more than 60 seconds, GPU %d declared SICK!", i, gpu);
 				/* Sent it a ping, it might respond */
-				ping_gpu(thr->cgpu);
+				tq_push(thr->q, &ping);
 			} else if (now.tv_sec - thr->last.tv_sec > 300 && gpus[i].status == LIFE_SICK) {
 				gpus[gpu].status = LIFE_DEAD;
 				applog(LOG_ERR, "Thread %d idle for more than 5 minutes, GPU %d declared DEAD!", i, gpu);
@@ -4340,7 +4331,7 @@ out:
 
 int main (int argc, char *argv[])
 {
-	unsigned int i, j = 0, x, y, pools_active = 0;
+	unsigned int i, x, y, pools_active = 0;
 	struct sigaction handler;
 	struct thr_info *thr;
 	char name[256];
@@ -4568,7 +4559,7 @@ int main (int argc, char *argv[])
 
 	mining_threads = opt_n_threads + gpu_threads;
 
-	total_threads = mining_threads + 5;
+	total_threads = mining_threads + 7;
 	work_restart = calloc(total_threads, sizeof(*work_restart));
 	if (!work_restart)
 		quit(1, "Failed to calloc work_restart");
@@ -4649,14 +4640,9 @@ int main (int argc, char *argv[])
 		quit(0, "No pools active! Exiting.");
 
 #ifdef HAVE_OPENCL
-	i = 0;
-
-	if (nDevs > 0)
-		preinit_devices();
-
 	/* start GPU mining threads */
-	for (j = 0; j < nDevs * opt_g_threads; j++) {
-		int gpu = j % nDevs;
+	for (i = 0; i < nDevs * opt_g_threads; i++) {
+		int gpu = i % nDevs;
 		struct cgpu_info *cgpu;
 		struct timeval now;
 
@@ -4665,8 +4651,7 @@ int main (int argc, char *argv[])
 
 		thr = &thr_info[i];
 		thr->id = i;
-		cgpu = &gpus[gpu];
-		thr->cgpu = cgpu;
+		cgpu = thr->cgpu = &gpus[gpu];
 
 		thr->q = tq_new();
 		if (!thr->q)
@@ -4682,11 +4667,10 @@ int main (int argc, char *argv[])
 		}
 
 		applog(LOG_INFO, "Init GPU thread %i", i);
-		clStates[i] = initCl(cgpu, name, sizeof(name));
+		clStates[i] = initCl(gpu, name, sizeof(name));
 		if (!clStates[i]) {
 			applog(LOG_ERR, "Failed to init GPU thread %d", i);
 			gpu_devices[i] = false;
-			strcat(cgpu->init, "Never");
 			continue;
 		}
 		applog(LOG_INFO, "initCl() finished. Found %s", name);
@@ -4695,8 +4679,6 @@ int main (int argc, char *argv[])
 
 		if (unlikely(thr_info_create(thr, NULL, gpuminer_thread, thr)))
 			quit(1, "thread %d create failed", i);
-
-		i++;
 	}
 
 	applog(LOG_INFO, "%d gpu miner threads started", gpu_threads);
@@ -4742,6 +4724,24 @@ int main (int argc, char *argv[])
 		quit(1, "input thread create failed");
 	pthread_detach(*thr->pth);
 
+	/* Create reinit cpu thread */
+	cpur_thr_id = mining_threads + 5;
+	thr = &thr_info[cpur_thr_id];
+	thr->q = tq_new();
+	if (!thr->q)
+		quit(1, "tq_new failed for cpur_thr_id");
+	if (thr_info_create(thr, NULL, reinit_cpu, thr))
+		quit(1, "reinit_cpu thread create failed");
+
+	/* Create reinit gpu thread */
+	gpur_thr_id = mining_threads + 6;
+	thr = &thr_info[gpur_thr_id];
+	thr->q = tq_new();
+	if (!thr->q)
+		quit(1, "tq_new failed for gpur_thr_id");
+	if (thr_info_create(thr, NULL, reinit_gpu, thr))
+		quit(1, "reinit_gpu thread create failed");
+
 	/* main loop - simply wait for workio thread to exit */
 	pthread_join(*thr_info[work_thr_id].pth, NULL);
 	applog(LOG_INFO, "workio thread dead, exiting.");

+ 0 - 6
miner.h

@@ -152,12 +152,6 @@ struct cgpu_info {
 	double efficiency;
 	double utility;
 	enum alive status;
-
-	int hasBitAlign;
-	unsigned int vwidth;
-	size_t max_work_size;
-	size_t work_size;
-
 	char init[40];
 };
 

+ 141 - 170
ocl.c

@@ -52,8 +52,6 @@ char *file_contents(const char *filename, int *length)
 	return (char*)buffer;
 }
 
-static cl_uint numDevices;
-
 int clDevicesNum() {
 	cl_int status = 0;
 
@@ -113,95 +111,6 @@ int clDevicesNum() {
 	return numDevices;
 }
 
-static cl_platform_id platform = NULL;
-static cl_device_id *devices;
-
-int preinit_devices(void)
-{
-	cl_int status;
-	cl_uint numPlatforms;
-	int i;
-
-	status = clGetPlatformIDs(0, NULL, &numPlatforms);
-	if (status != CL_SUCCESS)
-	{
-		applog(LOG_ERR, "Error: Getting Platforms. (clGetPlatformsIDs)");
-		return -1;
-	}
-
-	if (numPlatforms > 0)
-	{
-		cl_platform_id* platforms = (cl_platform_id *)malloc(numPlatforms*sizeof(cl_platform_id));
-		status = clGetPlatformIDs(numPlatforms, platforms, NULL);
-		if (status != CL_SUCCESS)
-		{
-			applog(LOG_ERR, "Error: Getting Platform Ids. (clGetPlatformsIDs)");
-			return -1;
-		}
-
-		for(i = 0; i < numPlatforms; ++i)
-		{
-			char pbuff[100];
-			status = clGetPlatformInfo( platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);
-			if (status != CL_SUCCESS)
-			{
-				applog(LOG_ERR, "Error: Getting Platform Info. (clGetPlatformInfo)");
-				free(platforms);
-				return -1;
-			}
-			platform = platforms[i];
-			if (!strcmp(pbuff, "Advanced Micro Devices, Inc."))
-			{
-				break;
-			}
-		}
-		free(platforms);
-	}
-
-	if (platform == NULL) {
-		perror("NULL platform found!\n");
-		return -1;
-	}
-
-	status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
-	if (status != CL_SUCCESS)
-	{
-		applog(LOG_ERR, "Error: Getting Device IDs (num)");
-		return -1;
-	}
-
-	if (numDevices > 0 ) {
-		devices = (cl_device_id *)malloc(numDevices*sizeof(cl_device_id));
-
-		/* Now, get the device list data */
-
-		status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
-		if (status != CL_SUCCESS)
-		{
-			applog(LOG_ERR, "Error: Getting Device IDs (list)");
-			return -1;
-		}
-
-		applog(LOG_INFO, "List of devices:");
-
-		unsigned int i;
-		for(i=0; i<numDevices; i++) {
-			char pbuff[100];
-			status = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL);
-			if (status != CL_SUCCESS)
-			{
-				applog(LOG_ERR, "Error: Getting Device Info");
-				return -1;
-			}
-
-			applog(LOG_INFO, "\t%i\t%s", i, pbuff);
-		}
-
-	} else return -1;
-
-	return 0;
-}
-
 static int advance(char **area, unsigned *remaining, const char *marker)
 {
 	char *find = memmem(*area, *remaining, marker, strlen(marker));
@@ -264,70 +173,111 @@ void patch_opcodes(char *w, unsigned remaining)
 	}
 }
 
-_clState *initCQ(_clState *clState, unsigned int gpu)
+_clState *initCl(unsigned int gpu, char *name, size_t nameSize)
 {
+	int patchbfi = 0;
 	cl_int status = 0;
-	cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 };
+	unsigned int i;
 
-	clState->context = clCreateContextFromType(cps, CL_DEVICE_TYPE_GPU, NULL, NULL, &status);
+	_clState *clState = calloc(1, sizeof(_clState));
+
+	cl_uint numPlatforms;
+	cl_platform_id platform = NULL;
+	status = clGetPlatformIDs(0, NULL, &numPlatforms);
 	if (status != CL_SUCCESS)
 	{
-		applog(LOG_ERR, "Error: Creating Context. (clCreateContextFromType)");
+		applog(LOG_ERR, "Error: Getting Platforms. (clGetPlatformsIDs)");
 		return NULL;
 	}
 
-	/* create a cl program executable for the device specified */
-	status = clBuildProgram(clState->program, 1, &devices[gpu], NULL, NULL, NULL);
-	if (status != CL_SUCCESS)
+	if (numPlatforms > 0)
 	{
-		applog(LOG_ERR, "Error: Building Program (clBuildProgram)");
-		size_t logSize;
-		status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);
+		cl_platform_id* platforms = (cl_platform_id *)malloc(numPlatforms*sizeof(cl_platform_id));
+		status = clGetPlatformIDs(numPlatforms, platforms, NULL);
+		if (status != CL_SUCCESS)
+		{
+			applog(LOG_ERR, "Error: Getting Platform Ids. (clGetPlatformsIDs)");
+			return NULL;
+		}
 
-		char *log = malloc(logSize);
-		status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL);
-		applog(LOG_INFO, "%s", log);
-		return NULL;
+		for(i = 0; i < numPlatforms; ++i)
+		{
+			char pbuff[100];
+			status = clGetPlatformInfo( platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);
+			if (status != CL_SUCCESS)
+			{
+				applog(LOG_ERR, "Error: Getting Platform Info. (clGetPlatformInfo)");
+				free(platforms);
+				return NULL;
+			}
+			platform = platforms[i];
+			if (!strcmp(pbuff, "Advanced Micro Devices, Inc."))
+			{
+				break;
+			}
+		}
+		free(platforms);
 	}
 
-	/* get a kernel object handle for a kernel with the given name */
-	clState->kernel = clCreateKernel(clState->program, "search", &status);
-	if (status != CL_SUCCESS)
-	{
-		applog(LOG_ERR, "Error: Creating Kernel from program. (clCreateKernel)");
+	if (platform == NULL) {
+		perror("NULL platform found!\n");
 		return NULL;
 	}
 
-	/////////////////////////////////////////////////////////////////
-	// Create an OpenCL command queue
-	/////////////////////////////////////////////////////////////////
-	clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu],
-						     CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &status);
-	if (status != CL_SUCCESS) /* Try again without OOE enable */
-		clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu], 0 , &status);
+	size_t nDevices;
+	cl_uint numDevices;
+	status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
 	if (status != CL_SUCCESS)
 	{
-		applog(LOG_ERR, "Creating Command Queue. (clCreateCommandQueue)");
+		applog(LOG_ERR, "Error: Getting Device IDs (num)");
 		return NULL;
 	}
 
-	clState->outputBuffer = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, BUFFERSIZE, NULL, &status);
-	if (status != CL_SUCCESS) {
-		applog(LOG_ERR, "Error: clCreateBuffer (outputBuffer)");
-		return NULL;
-	}
+	cl_device_id *devices;
+	if (numDevices > 0 ) {
+		devices = (cl_device_id *)malloc(numDevices*sizeof(cl_device_id));
 
-	return clState;
-}
+		/* Now, get the device list data */
 
-_clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize)
-{
-	unsigned int gpu = cgpu->cpu_gpu;
-	int patchbfi = 0;
-	cl_int status = 0;
-	size_t nDevices;
+		status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
+		if (status != CL_SUCCESS)
+		{
+			applog(LOG_ERR, "Error: Getting Device IDs (list)");
+			return NULL;
+		}
 
-	_clState *clState = calloc(1, sizeof(_clState));
+		applog(LOG_INFO, "List of devices:");
+
+		unsigned int i;
+		for(i=0; i<numDevices; i++) {
+			char pbuff[100];
+			status = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL);
+			if (status != CL_SUCCESS)
+			{
+				applog(LOG_ERR, "Error: Getting Device Info");
+				return NULL;
+			}
+
+			applog(LOG_INFO, "\t%i\t%s", i, pbuff);
+		}
+
+		if (gpu < numDevices) {
+			char pbuff[100];
+			status = clGetDeviceInfo(devices[gpu], CL_DEVICE_NAME, sizeof(pbuff), pbuff, &nDevices);
+			if (status != CL_SUCCESS)
+			{
+				applog(LOG_ERR, "Error: Getting Device Info");
+				return NULL;
+			}
+
+			applog(LOG_INFO, "Selected %i: %s", gpu, pbuff);
+			strncpy(name, pbuff, nameSize);
+		} else {
+			applog(LOG_ERR, "Invalid GPU %i", gpu);
+			return NULL;
+		}
+
+	} else return NULL;
 
 	cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 };
 
@@ -338,22 +288,6 @@ _clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize)
 		return NULL;
 	}
 
-	if (gpu < numDevices) {
-		char pbuff[100];
-		status = clGetDeviceInfo(devices[gpu], CL_DEVICE_NAME, sizeof(pbuff), pbuff, &nDevices);
-		if (status != CL_SUCCESS)
-		{
-			applog(LOG_ERR, "Error: Getting Device Info");
-			return NULL;
-		}
-
-		applog(LOG_INFO, "Selected %i: %s", gpu, pbuff);
-		strncpy(name, pbuff, nameSize);
-	} else {
-		applog(LOG_ERR, "Invalid GPU %i", gpu);
-		return NULL;
-	}
-
 	/* Check for BFI INT support. Hopefully people don't mix devices with
 	 * and without it! */
 	char * extensions = malloc(1024);
@@ -367,7 +301,7 @@ _clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize)
 	}
 	find = strstr(extensions, camo);
 	if (find)
-		cgpu->hasBitAlign = patchbfi = 1;
+		clState->hasBitAlign = patchbfi = 1;
 
 	status = clGetDeviceInfo(devices[gpu], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), (void *)&clState->preferred_vwidth, NULL);
 	if (status != CL_SUCCESS) {
@@ -377,27 +311,26 @@ _clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize)
 	if (opt_debug)
 		applog(LOG_DEBUG, "Preferred vector width reported %d", clState->preferred_vwidth);
 
-	status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), (void *)&cgpu->max_work_size, NULL);
+	status = clGetDeviceInfo(devices[gpu], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), (void *)&clState->max_work_size, NULL);
 	if (status != CL_SUCCESS) {
 		applog(LOG_ERR, "Error: Failed to clGetDeviceInfo when trying to get CL_DEVICE_MAX_WORK_GROUP_SIZE");
 		return NULL;
 	}
 	if (opt_debug)
-		applog(LOG_DEBUG, "Max work group size reported %d", cgpu->max_work_size);
+		applog(LOG_DEBUG, "Max work group size reported %d", clState->max_work_size);
 
 	/* For some reason 2 vectors is still better even if the card says
 	 * otherwise, and many cards lie about their max so use 256 as max
 	 * unless explicitly set on the command line */
-	cgpu->vwidth = clState->preferred_vwidth;
 	if (clState->preferred_vwidth > 1)
-		cgpu->vwidth = 2;
+		clState->preferred_vwidth = 2;
 	if (opt_vectors)
-		cgpu->vwidth = opt_vectors;
-	if (opt_worksize && opt_worksize <= cgpu->max_work_size)
-		cgpu->work_size = opt_worksize;
+		clState->preferred_vwidth = opt_vectors;
+	if (opt_worksize && opt_worksize <= clState->max_work_size)
+		clState->work_size = opt_worksize;
 	else
-		cgpu->work_size = (cgpu->max_work_size <= 256 ? cgpu->max_work_size : 256) /
-				cgpu->vwidth;
+		clState->work_size = (clState->max_work_size <= 256 ? clState->max_work_size : 256) /
+				clState->preferred_vwidth;
 
 	/* Create binary filename based on parameters passed to opencl
 	 * compiler to ensure we only load a binary that matches what would
@@ -409,7 +342,7 @@ _clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize)
 	char filename[16];
 
 	if (chosen_kernel == KL_NONE) {
-		if (cgpu->hasBitAlign)
+		if (clState->hasBitAlign)
 			chosen_kernel = KL_PHATK;
 		else
 			chosen_kernel = KL_POCLBM;
@@ -452,14 +385,14 @@ _clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize)
 	}
 
 	strcat(binaryfilename, name);
-	if (cgpu->hasBitAlign)
+	if (clState->hasBitAlign)
 		strcat(binaryfilename, "bitalign");
 
 	strcat(binaryfilename, "v");
-	sprintf(numbuf, "%d", cgpu->vwidth);
+	sprintf(numbuf, "%d", clState->preferred_vwidth);
 	strcat(binaryfilename, numbuf);
 	strcat(binaryfilename, "w");
-	sprintf(numbuf, "%d", (int)cgpu->work_size);
+	sprintf(numbuf, "%d", (int)clState->work_size);
 	strcat(binaryfilename, numbuf);
 	strcat(binaryfilename, "long");
 	sprintf(numbuf, "%d", (int)sizeof(long));
@@ -515,7 +448,7 @@ build:
 	memcpy(source, rawsource, pl);
 
 	/* Patch the source file with the preferred_vwidth */
-	if (cgpu->vwidth > 1) {
+	if (clState->preferred_vwidth > 1) {
 		char *find = strstr(source, "VECTORSX");
 
 		if (unlikely(!find)) {
@@ -523,7 +456,7 @@ build:
 			return NULL;
 		}
 		find += 7; // "VECTORS"
-		if (cgpu->vwidth == 2)
+		if (clState->preferred_vwidth == 2)
 			strncpy(find, "2", 1);
 		else
 			strncpy(find, "4", 1);
@@ -532,7 +465,7 @@ build:
 	}
 
 	/* Patch the source file defining BITALIGN */
-	if (cgpu->hasBitAlign) {
+	if (clState->hasBitAlign) {
 		char *find = strstr(source, "BITALIGNX");
 
 		if (unlikely(!find)) {
@@ -690,13 +623,51 @@ built:
 	free(binaries);
 	free(binary_sizes);
 
-	/* We throw everything out now and create the real context we're using in initCQ */
-	clReleaseContext(clState->context);
-
 	applog(LOG_INFO, "Initialising kernel %s with%s BFI_INT patching, %d vectors and worksize %d",
-	       filename, patchbfi ? "" : "out", cgpu->vwidth, cgpu->work_size);
+	       filename, patchbfi ? "" : "out", clState->preferred_vwidth, clState->work_size);
+
+	/* create a cl program executable for all the devices specified */
+	status = clBuildProgram(clState->program, 1, &devices[gpu], NULL, NULL, NULL);
+	if (status != CL_SUCCESS)
+	{
+		applog(LOG_ERR, "Error: Building Program (clBuildProgram)");
+		size_t logSize;
+		status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);
+
+		char *log = malloc(logSize);
+		status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL);
+		applog(LOG_INFO, "%s", log);
+		return NULL;
+	}
+
+	/* get a kernel object handle for a kernel with the given name */
+	clState->kernel = clCreateKernel(clState->program, "search", &status);
+	if (status != CL_SUCCESS)
+	{
+		applog(LOG_ERR, "Error: Creating Kernel from program. (clCreateKernel)");
+		return NULL;
+	}
+
+	/////////////////////////////////////////////////////////////////
+	// Create an OpenCL command queue
+	/////////////////////////////////////////////////////////////////
+	clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu],
+						     CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &status);
+	if (status != CL_SUCCESS) /* Try again without OOE enable */
+		clState->commandQueue = clCreateCommandQueue(clState->context, devices[gpu], 0 , &status);
+	if (status != CL_SUCCESS)
+	{
+		applog(LOG_ERR, "Creating Command Queue. (clCreateCommandQueue)");
+		return NULL;
+	}
 
-	return initCQ(clState, gpu);
+	clState->outputBuffer = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, BUFFERSIZE, NULL, &status);
+	if (status != CL_SUCCESS) {
+		applog(LOG_ERR, "Error: clCreateBuffer (outputBuffer)");
+		return NULL;
+	}
+
+	return clState;
 }
 #endif /* HAVE_OPENCL */
 

+ 4 - 4
ocl.h

@@ -7,7 +7,6 @@
 #else
 #include <CL/cl.h>
 #endif
-#include "miner.h"
 
 typedef struct {
 	cl_context context;
@@ -15,13 +14,14 @@ typedef struct {
 	cl_command_queue commandQueue;
 	cl_program program;
 	cl_mem outputBuffer;
+	int hasBitAlign;
 	cl_uint preferred_vwidth;
+	size_t max_work_size;
+	size_t work_size;
 } _clState;
 
 extern char *file_contents(const char *filename, int *length);
 extern int clDevicesNum();
-extern int preinit_devices(void);
-extern _clState *initCQ(_clState *clState, unsigned int gpu);
-extern _clState *initCl(struct cgpu_info *cgpu, char *name, size_t nameSize);
+extern _clState *initCl(unsigned int gpu, char *name, size_t nameSize);
 #endif /* HAVE_OPENCL */
 #endif /* __OCL_H__ */