lib: Add boinc_getopencl_ids() to be called by OpenCL project applications

svn path=/trunk/boinc/; revision=24091
This commit is contained in:
Charlie Fenton 2011-08-31 11:10:22 +00:00
parent 97f5146f2a
commit 69debb0743
3 changed files with 200 additions and 0 deletions

View File

@ -5345,3 +5345,11 @@ Charlie 31 Aug 2011
lib/
coproc.cpp, .h
gui_rpc_client_ops.cpp
Charlie 31 Aug 2011
- lib: Add OPENCL_REFERENCE boinc_getopencl_ids(int argc, char** argv)
to be called by OpenCL project applications to get the platform ID
and device ID of the GPU assigned to the task by the scheduler.
lib/
coproc.cpp, .h

View File

@ -29,14 +29,26 @@
#include <cstdlib>
#endif
#ifdef _WIN32
#include "win_util.h"
#else
#ifdef __APPLE__
// Suppress obsolete warning when building for OS 10.3.9
#define DLOPEN_NO_WARN
#include <mach-o/dyld.h>
#endif
#include "config.h"
#include <dlfcn.h>
#include <setjmp.h>
#include <signal.h>
#endif
#include "error_numbers.h"
#include "filesys.h"
#include "parse.h"
#include "util.h"
#include "str_replace.h"
#include "coproc.h"
@ -657,3 +669,175 @@ void COPROC_ATI::description(char* buf) {
name, version, attribs.localRAM/1024.*1024., peak_flops/1.e9
);
}
#ifndef __WXWINDOWS__ /* Exclude from Manager */
#ifdef _WIN32
static HMODULE opencl_lib = NULL;
typedef cl_int (__stdcall *CL_PLATFORMIDS) (cl_uint, cl_platform_id*, cl_uint*);
typedef cl_int (__stdcall *CL_DEVICEIDS)(cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*);
typedef cl_int (__stdcall *CL_INFO) (cl_device_id, cl_device_info, size_t, void*, size_t*);
static CL_PLATFORMIDS __clGetPlatformIDs = NULL;
static CL_DEVICEIDS __clGetDeviceIDs = NULL;
static CL_INFO __clGetDeviceInfo = NULL;
#else
static jmp_buf resume;
static void segv_handler(int) {
longjmp(resume, 1);
}
static void* opencl_lib = NULL;
static cl_int (*__clGetPlatformIDs)(cl_uint /* num_entries */,
cl_platform_id * /* platforms */,
cl_uint * /* num_platforms */);
static cl_int (*__clGetDeviceIDs)(cl_platform_id /* platform */,
cl_device_type /* device_type */,
cl_uint /* num_entries */,
cl_device_id * /* devices */,
cl_uint * /* num_devices */);
static cl_int (*__clGetDeviceInfo)(cl_device_id /* device */,
cl_device_info /* param_name */,
size_t /* param_value_size */,
void * /* param_value */,
size_t * /* param_value_size_ret */);
#endif
void boinc_getopencl_ids(char *type, int device_num, OPENCL_REFERENCE *ref) {
cl_int errnum;
cl_platform_id platforms[MAX_OPENCL_PLATFORMS];
cl_uint num_platforms, platform_index, num_devices;
cl_device_id devices[MAX_COPROC_INSTANCES];
char vendor[256]; // Device vendor (NVIDIA, ATI, AMD, etc.)
#ifdef _WIN32
opencl_lib = LoadLibrary("OpenCL.dll");
if (!opencl_lib) {
ref->retval = ERR_NOT_IMPLEMENTED;
return;
}
__clGetPlatformIDs = (CL_PLATFORMIDS)GetProcAddress( opencl_lib, "clGetPlatformIDs" );
__clGetDeviceIDs = (CL_DEVICEIDS)GetProcAddress( opencl_lib, "clGetDeviceIDs" );
__clGetDeviceInfo = (CL_INFO)GetProcAddress( opencl_lib, "clGetDeviceInfo" );
#else
#ifdef __APPLE__
opencl_lib = dlopen("/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL", RTLD_NOW);
#else
//TODO: Is this correct?
opencl_lib = dlopen("libOpenCL.so", RTLD_NOW);
#endif
if (!opencl_lib) {
ref->retval = ERR_NOT_IMPLEMENTED;
return;
}
__clGetPlatformIDs = (cl_int(*)(cl_uint, cl_platform_id*, cl_uint*)) dlsym( opencl_lib, "clGetPlatformIDs" );
__clGetDeviceIDs = (cl_int(*)(cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*)) dlsym( opencl_lib, "clGetDeviceIDs" );
__clGetDeviceInfo = (cl_int(*)(cl_device_id, cl_device_info, size_t, void*, size_t*)) dlsym( opencl_lib, "clGetDeviceInfo" );
#endif
if ((!__clGetPlatformIDs) || (!__clGetDeviceIDs) || (!__clGetDeviceInfo)) {
ref->retval = ERR_NOT_IMPLEMENTED;
goto bail;
}
errnum = (*__clGetPlatformIDs)(MAX_OPENCL_PLATFORMS, platforms, &num_platforms);
if (num_platforms == 0) errnum = CL_DEVICE_NOT_FOUND;
if (errnum != CL_SUCCESS) {
ref->retval = errnum;
goto bail;
}
for (platform_index=0; platform_index<num_platforms; ++platform_index) {
errnum = (*__clGetDeviceIDs)(
platforms[platform_index], CL_DEVICE_TYPE_GPU, MAX_COPROC_INSTANCES, devices, &num_devices
);
if (num_devices > (cl_uint)(device_num + 1)) continue;
cl_device_id device_id = devices[device_num];
errnum = (*__clGetDeviceInfo)(device_id, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL);
if ((errnum != CL_SUCCESS) || (vendor[0] == 0)) continue;
if ((strstr(vendor, "AMD")) ||
(strstr(vendor, "Advanced Micro Devices, Inc."))
) {
strcpy(vendor, GPU_TYPE_ATI);
}
if (!strcmp(vendor, type)) {
ref->device_id = device_id;
ref->platform_id = platforms[platform_index];
break;
}
}
bail:
#ifndef _WIN32
dlclose(opencl_lib);
#endif
if ((ref->retval == CL_SUCCESS) && (ref->device_id == NULL)) {
ref->retval = CL_DEVICE_NOT_FOUND;
}
}
OPENCL_REFERENCE boinc_getopencl_ids(int argc, char** argv) {
OPENCL_REFERENCE ref;
char type[256];
int device_num;
memset(&ref, 0, sizeof(struct OPENCL_REFERENCE));
type[0] = '\0';
device_num = -1;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--gpu_type")) {
strlcpy(type, argv[++i], sizeof(type));
}
if (!strcmp(argv[i], "--device")) {
device_num = atoi(argv[++i]);
}
}
if (type[0] == '\0'){
ref.retval = CL_INVALID_DEVICE_TYPE;
return ref;
}
if (device_num < 0) {
ref.retval = CL_INVALID_DEVICE;
return ref;
}
#ifdef _WIN32
try {
boinc_getopencl_ids(type, device_num, &ref);
}
catch (...) {
ref.retval = ERR_SIGNAL_CATCH;
}
#else
void (*old_sig)(int) = signal(SIGSEGV, segv_handler);
if (setjmp(resume)) {
ref.retval = ERR_SIGNAL_CATCH;
} else {
boinc_getopencl_ids(type, device_num, &ref);
}
signal(SIGSEGV, old_sig);
#endif
if ((ref.retval == CL_SUCCESS) && (ref.device_id == NULL)) {
ref.retval = CL_DEVICE_NOT_FOUND;
}
return ref;
}
#endif // __WXWINDOWS

View File

@ -85,6 +85,12 @@
#define GPU_TYPE_ATI "ATI"
#define GPU_TYPE_AMD GPU_TYPE_ATI
struct OPENCL_REFERENCE {
cl_device_id device_id;
cl_platform_id platform_id;
cl_int retval;
};
// represents a requirement for a coproc.
// This is a parsed version of the <coproc> elements in an <app_version>
// (used in client only)
@ -405,4 +411,6 @@ struct COPROCS {
}
};
OPENCL_REFERENCE boinc_getopencl_ids(int argc, char** argv);
#endif