Commit d6ae8065 authored by Thomas White's avatar Thomas White
Browse files

Handle multiple GPUs

parent 322bcc8d
......@@ -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];
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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) ) {
......
......@@ -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 {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment