aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2010-11-18 11:04:05 +0100
committerThomas White <taw@physics.org>2012-02-22 15:27:06 +0100
commitd6ae8065f7c422300dba3b6256f4ace53b39a092 (patch)
tree25ffd2c30e20d002c9b92c1910f60427471010d6
parent322bcc8d927078b1d672faf94c507c44f8104b1a (diff)
Handle multiple GPUs
-rw-r--r--src/cl-utils.c77
-rw-r--r--src/cl-utils.h2
-rw-r--r--src/diffraction-gpu.c8
-rw-r--r--src/diffraction-gpu.h4
-rw-r--r--src/indexamajig.c2
-rw-r--r--src/pattern_sim.c8
6 files changed, 87 insertions, 14 deletions
diff --git a/src/cl-utils.c b/src/cl-utils.c
index a7d23371..1b7b9811 100644
--- a/src/cl-utils.c
+++ b/src/cl-utils.c
@@ -48,18 +48,87 @@ const char *clError(cl_int err)
}
-cl_device_id get_first_dev(cl_context ctx)
+static char *get_device_string(cl_device_id dev, cl_device_info info)
{
- cl_device_id dev;
+ int r;
+ size_t size;
+ char *val;
+
+ r = clGetDeviceInfo(dev, info, 0, NULL, &size);
+ if ( r != CL_SUCCESS ) {
+ ERROR("Couldn't get device vendor size: %s\n",
+ clError(r));
+ return NULL;
+ }
+ val = malloc(size);
+ r = clGetDeviceInfo(dev, info, size, val, NULL);
+ if ( r != CL_SUCCESS ) {
+ ERROR("Couldn't get dev vendor: %s\n", clError(r));
+ return NULL;
+ }
+
+ return val;
+}
+
+
+cl_device_id get_cl_dev(cl_context ctx, int n)
+{
+ cl_device_id *dev;
cl_int r;
+ size_t size;
+ int i, num_devs;
- r = clGetContextInfo(ctx, CL_CONTEXT_DEVICES, sizeof(dev), &dev, NULL);
+ /* Get the required size of the array */
+ r = clGetContextInfo(ctx, CL_CONTEXT_DEVICES, 0, NULL, &size);
+ if ( r != CL_SUCCESS ) {
+ ERROR("Couldn't get array size for devices: %s\n", clError(r));
+ return 0;
+ }
+
+ dev = malloc(size);
+ r = clGetContextInfo(ctx, CL_CONTEXT_DEVICES, size, dev, NULL);
if ( r != CL_SUCCESS ) {
ERROR("Couldn't get device: %s\n", clError(r));
return 0;
}
+ num_devs = size/sizeof(cl_device_id);
+
+ if ( n >= num_devs ) {
+ ERROR("Device ID out of range\n");
+ return 0;
+ }
+
+ if ( n < 0 ) {
+
+ STATUS("Available devices:\n");
+ for ( i=0; i<num_devs; i++ ) {
+
+ char *vendor;
+ char *name;
+
+ vendor = get_device_string(dev[i], CL_DEVICE_VENDOR);
+ name = get_device_string(dev[i], CL_DEVICE_NAME);
+
+ STATUS("Device %i: %s %s\n", i, vendor, name);
+
+ }
+ n = 0;
+
+ STATUS("Using device 0. Use --gpu-dev to choose another.\n");
+
+ } else {
+
+ char *vendor;
+ char *name;
+
+ vendor = get_device_string(dev[n], CL_DEVICE_VENDOR);
+ name = get_device_string(dev[n], CL_DEVICE_NAME);
+
+ STATUS("Using device %i: %s %s\n", n, vendor, name);
+
+ }
- return dev;
+ return dev[n];
}
diff --git a/src/cl-utils.h b/src/cl-utils.h
index 1725ea1e..790a149a 100644
--- a/src/cl-utils.h
+++ b/src/cl-utils.h
@@ -18,7 +18,7 @@
extern const char *clError(cl_int err);
-extern cl_device_id get_first_dev(cl_context ctx);
+extern cl_device_id get_cl_dev(cl_context ctx, int n);
extern cl_program load_program(const char *filename, cl_context ctx,
cl_device_id dev, cl_int *err);
diff --git a/src/diffraction-gpu.c b/src/diffraction-gpu.c
index c210cab9..324cc4cd 100644
--- a/src/diffraction-gpu.c
+++ b/src/diffraction-gpu.c
@@ -330,7 +330,7 @@ void get_diffraction_gpu(struct gpu_context *gctx, struct image *image,
/* Setup the OpenCL stuff, create buffers, load the structure factor table */
struct gpu_context *setup_gpu(int no_sfac, struct image *image,
- const double *intensities)
+ const double *intensities, int dev_num)
{
struct gpu_context *gctx;
cl_uint nplat;
@@ -343,7 +343,7 @@ struct gpu_context *setup_gpu(int no_sfac, struct image *image,
size_t maxwgsize;
int i;
- STATUS("Setting up GPU..."); fflush(stderr);
+ STATUS("Setting up GPU...\n");
err = clGetPlatformIDs(8, platforms, &nplat);
if ( err != CL_SUCCESS ) {
@@ -367,7 +367,7 @@ struct gpu_context *setup_gpu(int no_sfac, struct image *image,
return NULL;
}
- dev = get_first_dev(gctx->ctx);
+ dev = get_cl_dev(gctx->ctx, dev_num);
gctx->cq = clCreateCommandQueue(gctx->ctx, dev, 0, &err);
if ( err != CL_SUCCESS ) {
@@ -431,8 +431,6 @@ struct gpu_context *setup_gpu(int no_sfac, struct image *image,
return NULL;
}
- STATUS("done\n");
-
gctx->max_sinc_lut = 0;
gctx->sinc_lut_ptrs = NULL;
gctx->sinc_luts = NULL;
diff --git a/src/diffraction-gpu.h b/src/diffraction-gpu.h
index 2438e8f1..4a5815bf 100644
--- a/src/diffraction-gpu.h
+++ b/src/diffraction-gpu.h
@@ -26,7 +26,7 @@ struct gpu_context;
extern void get_diffraction_gpu(struct gpu_context *gctx, struct image *image,
int na, int nb, int nc, UnitCell *ucell);
extern struct gpu_context *setup_gpu(int no_sfac, struct image *image,
- const double *intensities);
+ const double *intensities, int dev_num);
extern void cleanup_gpu(struct gpu_context *gctx);
#else
@@ -39,7 +39,7 @@ static void get_diffraction_gpu(struct gpu_context *gctx, struct image *image,
}
static struct gpu_context *setup_gpu(int no_sfac, struct image *image,
- const double *intensities)
+ const double *intensities, int dev_num)
{
return NULL;
}
diff --git a/src/indexamajig.c b/src/indexamajig.c
index 799750f3..1a27d607 100644
--- a/src/indexamajig.c
+++ b/src/indexamajig.c
@@ -276,7 +276,7 @@ static void simulate_and_write(struct image *simage, struct gpu_context **gctx,
{
/* Set up GPU if necessary */
if ( (gctx != NULL) && (*gctx == NULL) ) {
- *gctx = setup_gpu(0, simage, intensities);
+ *gctx = setup_gpu(0, simage, intensities, 0);
}
if ( (gctx != NULL) && (*gctx != NULL) ) {
diff --git a/src/pattern_sim.c b/src/pattern_sim.c
index 3c1afe07..3deaa742 100644
--- a/src/pattern_sim.c
+++ b/src/pattern_sim.c
@@ -203,6 +203,7 @@ int main(int argc, char *argv[])
int done = 0;
UnitCell *input_cell;
struct quaternion orientation;
+ int gpu_dev = -1;
/* Long options */
const struct option longopts[] = {
@@ -223,6 +224,7 @@ int main(int argc, char *argv[])
{"geometry", 1, NULL, 'g'},
{"beam", 1, NULL, 'b'},
{"really-random", 0, &config_random, 1},
+ {"gpu-dev", 1, NULL, 2},
{0, 0, NULL, 0}
};
@@ -271,6 +273,10 @@ int main(int argc, char *argv[])
beamfile = strdup(optarg);
break;
+ case 2 :
+ gpu_dev = atoi(optarg);
+ break;
+
case 0 :
break;
@@ -446,7 +452,7 @@ int main(int argc, char *argv[])
if ( config_gpu ) {
if ( gctx == NULL ) {
gctx = setup_gpu(config_nosfac, &image,
- intensities);
+ intensities, gpu_dev);
}
get_diffraction_gpu(gctx, &image, na, nb, nc, cell);
} else {