- move boinc_get_opencl_ids() from lib/ to api/.

lib/ is for code that's used by >1 part of BOINC


svn path=/trunk/boinc/; revision=24093
This commit is contained in:
David Anderson 2011-08-31 15:54:41 +00:00
parent f5a28b279d
commit f1040e87ec
6 changed files with 247 additions and 183 deletions

View File

@ -8,8 +8,9 @@ if ENABLE_LIBRARIES
# stuff linked into both main app and graphics app
api_files= \
boinc_api.cpp \
reduce_main.cpp \
graphics2_util.cpp
boinc_opencl.cpp \
graphics2_util.cpp \
reduce_main.cpp
# stuff linked into graphics app
graphics2_files = \

208
api/boinc_opencl.cpp Normal file
View File

@ -0,0 +1,208 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2011 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
// BOINC API for OpenCL
#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 "str_replace.h"
#include "coproc.h"
#include "boinc_opencl.h"
#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_get_opencl_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_get_opencl_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_get_opencl_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_get_opencl_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;
}

26
api/boinc_opencl.h Normal file
View File

@ -0,0 +1,26 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2011 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
// BOINC API for OpenCL apps
struct OPENCL_REFERENCE {
cl_device_id device_id;
cl_platform_id platform_id;
cl_int retval;
};
OPENCL_REFERENCE boinc_get_opencl_ids(int argc, char** argv);

View File

@ -5353,3 +5353,13 @@ Charlie 31 Aug 2011
lib/
coproc.cpp, .h
David 31 Aug 2011
- move boinc_get_opencl_ids() from lib/ to api/.
lib/ is for code that's used by >1 part of BOINC
lib/
coproc.cpp,h
api/
boinc_opencl.cpp,h (new)
Makefile.am

View File

@ -669,175 +669,3 @@ 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_get_opencl_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_get_opencl_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_get_opencl_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_get_opencl_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

@ -83,13 +83,6 @@
#define GPU_TYPE_NVIDIA "NVIDIA"
#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>
@ -411,6 +404,4 @@ struct COPROCS {
}
};
OPENCL_REFERENCE boinc_get_opencl_ids(int argc, char** argv);
#endif