瀏覽代碼

Allow applications to run the OpenCL drivers themselves.

 * gcc-plugin/src/starpu.c: move the inclusion of starpu.h so that gcc does not complain about the use of a "poisoned" malloc.
 * include/starpu.h: add an opencl_id field to the "id" union inside the starpu_driver structure.
 * src/core/workers.c: adapt starpu_launch_drivers()
 * src/drivers/opencl/driver_opencl.c: add _starpu_run_opencl()
Cyril Roelandt 13 年之前
父節點
當前提交
d07c947598
共有 4 個文件被更改,包括 81 次插入7 次删除
  1. 3 1
      gcc-plugin/src/starpu.c
  2. 7 0
      include/starpu.h
  3. 32 6
      src/core/workers.c
  4. 39 0
      src/drivers/opencl/driver_opencl.c

+ 3 - 1
gcc-plugin/src/starpu.c

@@ -18,6 +18,9 @@
 #define _GNU_SOURCE 1
 
 #include <starpu-gcc-config.h>
+/* We must include starpu.h here, otherwise gcc will complain about a poisoned
+   malloc in xmmintrin.h. */
+#include <starpu.h>  /* for `STARPU_CPU' & co.  */
 
 /* #define ENABLE_TREE_CHECKING 1 */
 
@@ -57,7 +60,6 @@
    disclaimer.  */
 #define STARPU_DONT_INCLUDE_CUDA_HEADERS
 
-#include <starpu.h>  /* for `STARPU_CPU' & co.  */
 
 
 /* GCC 4.7 requires compilation with `g++', and C++ lacks a number of GNU C

+ 7 - 0
include/starpu.h

@@ -51,6 +51,10 @@ extern "C"
 {
 #endif
 
+#if defined(STARPU_USE_OPENCL) && !defined(__CUDACC__)
+#include <starpu_opencl.h>
+#endif
+
 enum starpu_archtype
 {
 	STARPU_CPU_WORKER,    /* CPU core */
@@ -65,6 +69,9 @@ struct starpu_driver
 	union
 	{
 		unsigned cuda_id;
+#if defined(STARPU_USE_OPENCL) && !defined(__CUDACC__)
+		cl_device_id opencl_id;
+#endif
 		/*
 		 * TODO: handle CPUs and OpenCL devices :
 		 * 1) Add a member to this union.

+ 32 - 6
src/core/workers.c

@@ -232,6 +232,12 @@ static unsigned _starpu_may_launch_driver(struct starpu_conf *conf,
 			if (d->id.cuda_id == conf->not_launched_drivers[i].id.cuda_id)
 				return 0;
 			break;
+#ifdef STARPU_USE_OPENCL
+		case STARPU_OPENCL_WORKER:
+			if (d->id.opencl_id == conf->not_launched_drivers[i].id.opencl_id)
+				return 0;
+			break;
+#endif
 		default:
 			STARPU_ABORT();
 		}
@@ -306,6 +312,9 @@ static void _starpu_launch_drivers(struct _starpu_machine_config *config)
 #endif
 #ifdef STARPU_USE_OPENCL
 			case STARPU_OPENCL_WORKER:
+				starpu_opencl_get_device(workerarg->devid, &driver.id.opencl_id);
+				if (!_starpu_may_launch_driver(config->conf, &driver))
+					break;
 				workerarg->set = NULL;
 				workerarg->worker_is_initialized = 0;
 				pthread_create(&workerarg->worker_thread,
@@ -375,12 +384,17 @@ static void _starpu_launch_drivers(struct _starpu_machine_config *config)
 				_STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
 				cuda++;
 				break;
+#ifdef STARPU_USE_OPENCL
 			case STARPU_OPENCL_WORKER:
+				starpu_opencl_get_device(workerarg->devid, &driver.id.opencl_id);
+				if (!_starpu_may_launch_driver(config->conf, &driver))
+					break;
 				_STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
 				while (!workerarg->worker_is_initialized)
 					_STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
 				_STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
 				break;
+#endif
 #ifdef STARPU_USE_GORDON
 			case STARPU_GORDON_WORKER:
 				/* the initialization of Gordon worker is
@@ -963,7 +977,12 @@ starpu_set_end_of_submissions(void)
 	config->running = 0;
 }
 
+#ifdef STARPU_USE_CUDA
 extern int _starpu_run_cuda(struct starpu_driver *);
+#endif
+#ifdef STARPU_USE_OPENCL
+extern int _starpu_run_opencl(struct starpu_driver *);
+#endif
 
 int
 starpu_run_driver(struct starpu_driver *d)
@@ -971,12 +990,19 @@ starpu_run_driver(struct starpu_driver *d)
 	if (!d)
 		return -EINVAL;
 
+	switch (d->type)
+	{
 #ifdef STARPU_USE_CUDA
-	if (d->type != STARPU_CUDA_WORKER)
-		return -EINVAL;
-
-	return _starpu_run_cuda(d);
-#else
-	return -ENODEV;
+	case STARPU_CUDA_WORKER:
+		return _starpu_run_cuda(d);
 #endif
+#ifdef STARPU_USE_OPENCL
+	case STARPU_OPENCL_WORKER:
+		return _starpu_run_opencl(d);
+#endif
+	case STARPU_CPU_WORKER:    /* Not supported yet */
+	case STARPU_GORDON_WORKER: /* Not supported yet */
+	default:
+		return -EINVAL;
+	}
 }

+ 39 - 0
src/drivers/opencl/driver_opencl.c

@@ -592,3 +592,42 @@ static int _starpu_opencl_execute_job(struct _starpu_job *j, struct _starpu_work
 
 	return EXIT_SUCCESS;
 }
+
+int _starpu_run_opencl(struct starpu_driver *d)
+{
+	STARPU_ASSERT(d && d->type == STARPU_OPENCL_WORKER);
+
+	int nworkers;
+	int workers[STARPU_MAXOPENCLDEVS];
+	nworkers = starpu_worker_get_ids_by_type(STARPU_OPENCL_WORKER, workers, STARPU_MAXOPENCLDEVS);
+	if (nworkers == 0)
+		return -ENODEV;
+
+	int i;
+	for (i = 0; i < nworkers; i++)
+	{
+		cl_device_id device;
+		int devid = starpu_worker_get_devid(workers[i]);
+		starpu_opencl_get_device(devid, &device);
+		if (device == d->id.opencl_id)
+			break;
+	}
+
+	if (i == nworkers)
+		return -ENODEV;
+
+	struct _starpu_worker *workerarg = _starpu_get_worker_struct(i);
+	_STARPU_DEBUG("Running OpenCL %d from the application\n", workerarg->devid);
+
+	workerarg->set = NULL;
+	workerarg->worker_is_initialized = 0;
+
+	/* Let's go ! */
+	_starpu_opencl_worker(workerarg);
+
+	/* XXX: Should we wait for the driver to be ready, as it is done when
+	 * launching it the usual way ? Cf. the end of _starpu_launch_drivers()
+	 */
+
+	return 0;
+}