mirror of https://github.com/BOINC/boinc.git
OpenCL: Add a second API for boinc_get_opencl_ids() which is compatible with older clients (before BOINC 7.0.12)
This commit is contained in:
parent
5df6bb88ff
commit
b98fee99b3
|
@ -19,7 +19,7 @@
|
||||||
//
|
//
|
||||||
// To get the cl_device_id and cl_platform_id for the OpenCL GPU
|
// To get the cl_device_id and cl_platform_id for the OpenCL GPU
|
||||||
// assigned to your application call this function:
|
// assigned to your application call this function:
|
||||||
// int boinc_get_opencl_ids(int argc, char** argv, cl_device_id*, cl_platform_id*);
|
// int boinc_get_opencl_ids(int argc, char** argv, char *type, cl_device_id* device, cl_platform_id* platform);
|
||||||
//
|
//
|
||||||
// To use this function, link your application with libboinc_opencl.a
|
// To use this function, link your application with libboinc_opencl.a
|
||||||
//
|
//
|
||||||
|
@ -37,17 +37,58 @@
|
||||||
|
|
||||||
#include "boinc_opencl.h"
|
#include "boinc_opencl.h"
|
||||||
|
|
||||||
|
// A few complicating factors:
|
||||||
|
// Windows & Linux have a separate OpenCL platform for each vendor
|
||||||
|
// (NVIDIA, AMD, Intel).
|
||||||
|
// Mac has only one platform (Apple) which reports GPUs from all vendors.
|
||||||
|
//
|
||||||
|
// In all systems, opencl_device_indexes start at 0 for each platform
|
||||||
|
// and device_nums start at 0 for each vendor.
|
||||||
|
//
|
||||||
|
// On Macs, OpenCL does not always recognize all GPUs detected by CUDA,
|
||||||
|
// so a device_num may not correspond to its opencl_device_index even
|
||||||
|
// if all GPUs are from NVIDIA.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
int get_vendor(cl_device_id device_id, char* vendor) {
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
retval = clGetDeviceInfo(
|
||||||
|
device_id, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL
|
||||||
|
);
|
||||||
|
if ((retval != CL_SUCCESS) || (strlen(vendor)==0)) return retval;
|
||||||
|
|
||||||
|
if ((strstr(vendor, "AMD")) ||
|
||||||
|
(strstr(vendor, "Advanced Micro Devices, Inc."))
|
||||||
|
) {
|
||||||
|
strcpy(vendor, GPU_TYPE_ATI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasestr(vendor, "nvidia")) {
|
||||||
|
strcpy(vendor, GPU_TYPE_NVIDIA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strlen(vendor)) return CL_INVALID_DEVICE_TYPE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns an OpenCL error num or zero
|
// returns an OpenCL error num or zero
|
||||||
//
|
//
|
||||||
int boinc_get_opencl_ids_aux(
|
int boinc_get_opencl_ids_aux(
|
||||||
char *type, int device_num, cl_device_id* device, cl_platform_id* platform
|
char* type, int opencl_device_index, int device_num, cl_device_id* device, cl_platform_id* platform
|
||||||
) {
|
) {
|
||||||
cl_platform_id platforms[MAX_OPENCL_PLATFORMS];
|
cl_platform_id platforms[MAX_OPENCL_PLATFORMS];
|
||||||
cl_uint num_platforms, platform_index, num_devices;
|
cl_uint num_platforms, platform_index, num_devices;
|
||||||
cl_device_id devices[MAX_COPROC_INSTANCES];
|
cl_device_id devices[MAX_COPROC_INSTANCES];
|
||||||
char vendor[256]; // Device vendor (NVIDIA, ATI, AMD, etc.)
|
char vendor[256]; // Device vendor (NVIDIA, ATI, AMD, etc.)
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
bool found = false;
|
cl_device_id device_id;
|
||||||
|
int device_num_for_type = -1;
|
||||||
|
int device_index;
|
||||||
|
|
||||||
|
if ((!type) || (!strlen(type))) return CL_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
retval = clGetPlatformIDs(MAX_OPENCL_PLATFORMS, platforms, &num_platforms);
|
retval = clGetPlatformIDs(MAX_OPENCL_PLATFORMS, platforms, &num_platforms);
|
||||||
if (num_platforms == 0) return CL_DEVICE_NOT_FOUND;
|
if (num_platforms == 0) return CL_DEVICE_NOT_FOUND;
|
||||||
|
@ -60,36 +101,112 @@ int boinc_get_opencl_ids_aux(
|
||||||
);
|
);
|
||||||
if (retval != CL_SUCCESS) continue;
|
if (retval != CL_SUCCESS) continue;
|
||||||
|
|
||||||
if (device_num >= (int)num_devices) continue;
|
// Use gpu_opencl_dev_index if available
|
||||||
|
if (opencl_device_index >= 0) {
|
||||||
cl_device_id device_id = devices[device_num];
|
if (opencl_device_index < (int)num_devices) {
|
||||||
|
device_id = devices[opencl_device_index];
|
||||||
retval = clGetDeviceInfo(
|
retval = get_vendor(device_id, vendor);
|
||||||
device_id, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL
|
if (retval != CL_SUCCESS) continue;
|
||||||
);
|
|
||||||
if ((retval != CL_SUCCESS) || (strlen(vendor)==0)) continue;
|
|
||||||
|
|
||||||
if ((strstr(vendor, "AMD")) ||
|
if (!strcmp(vendor, type)) {
|
||||||
(strstr(vendor, "Advanced Micro Devices, Inc."))
|
*device = device_id;
|
||||||
) {
|
*platform = platforms[platform_index];
|
||||||
strcpy(vendor, GPU_TYPE_ATI);
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasestr(vendor, "nvidia")) {
|
// Older versions of init_data.xml don't have gpu_opencl_dev_index field
|
||||||
strcpy(vendor, GPU_TYPE_NVIDIA);
|
// NOTE: This may return the wrong device on older versions of BOINC if
|
||||||
}
|
// OpenCL does not recognize all GPUs detected by CUDA
|
||||||
if (!strcmp(vendor, type)) {
|
for (device_index=0; device_index<(int)num_devices; ++device_index) {
|
||||||
*device = device_id;
|
device_id = devices[device_index];
|
||||||
*platform = platforms[platform_index];
|
|
||||||
found = true;
|
retval = get_vendor(device_id, vendor);
|
||||||
break;
|
if (retval != CL_SUCCESS) continue;
|
||||||
|
|
||||||
|
if (!strcmp(vendor, type)) {
|
||||||
|
if(++device_num_for_type == device_num) {
|
||||||
|
*device = device_id;
|
||||||
|
*platform = platforms[platform_index];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) return CL_DEVICE_NOT_FOUND;
|
return CL_DEVICE_NOT_FOUND;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This version is compatible with older clients.
|
||||||
|
// Usage:
|
||||||
|
// Pass the argc and argv received from the BOINC client
|
||||||
|
// type: may be NULL, empty string, "NVIDIA", "nvidia", "ATI", "AMD",
|
||||||
|
// "Advanced Micro Devices, Inc.", "intel_gpu" or "INTEL_GPU"
|
||||||
|
// (if NULL or empty string then it will fail on older clients.)
|
||||||
|
//
|
||||||
|
// returns
|
||||||
|
// - 0 if success
|
||||||
|
// - ERR_FOPEN if init_data.xml missing
|
||||||
|
// - ERR_XML_PARSE if can't parse init_data.xml
|
||||||
|
// - ERR_NOT_FOUND if missing <gpu_type> or <gpu_device_num> fields
|
||||||
|
// - an OpenCL error number if OpenCL error
|
||||||
|
//
|
||||||
|
int boinc_get_opencl_ids(int argc, char** argv, char* type, cl_device_id* device, cl_platform_id* platform){
|
||||||
|
int retval;
|
||||||
|
APP_INIT_DATA aid;
|
||||||
|
char *gpu_type;
|
||||||
|
int gpu_device_num = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
retval = boinc_parse_init_data_file();
|
||||||
|
if (retval) return retval;
|
||||||
|
boinc_get_init_data(aid);
|
||||||
|
|
||||||
|
if (strlen(aid.gpu_type)) {
|
||||||
|
gpu_type = aid.gpu_type;
|
||||||
|
} else {
|
||||||
|
gpu_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!gpu_type) || !strlen(gpu_type)) {
|
||||||
|
fprintf(stderr, "GPU type not found in %s\n", INIT_DATA_FILE);
|
||||||
|
return ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aid.gpu_opencl_dev_index < 0) {
|
||||||
|
// Older versions of init_data.xml don't have gpu_opencl_dev_index field
|
||||||
|
gpu_device_num = aid.gpu_device_num;
|
||||||
|
if (gpu_device_num < 0) {
|
||||||
|
// Even older versions of init_data.xml don't have gpu_device_num field
|
||||||
|
for (i=1; i<argc; i++) {
|
||||||
|
if ((!strcmp(argv[i], "--device")) || (!strcmp(argv[i], "-device"))) {
|
||||||
|
gpu_device_num = atoi(argv[++i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((aid.gpu_opencl_dev_index < 0) && (gpu_device_num < 0)) {
|
||||||
|
fprintf(stderr, "GPU device # not found in %s\n", INIT_DATA_FILE);
|
||||||
|
return ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
retval = boinc_get_opencl_ids_aux(
|
||||||
|
gpu_type, aid.gpu_opencl_dev_index, gpu_device_num, device, platform
|
||||||
|
);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Deprecated: use the version above instead
|
||||||
|
//
|
||||||
// returns
|
// returns
|
||||||
// - 0 if success
|
// - 0 if success
|
||||||
// - ERR_FOPEN if init_data.xml missing
|
// - ERR_FOPEN if init_data.xml missing
|
||||||
|
@ -100,7 +217,6 @@ int boinc_get_opencl_ids_aux(
|
||||||
int boinc_get_opencl_ids(cl_device_id* device, cl_platform_id* platform) {
|
int boinc_get_opencl_ids(cl_device_id* device, cl_platform_id* platform) {
|
||||||
int retval;
|
int retval;
|
||||||
APP_INIT_DATA aid;
|
APP_INIT_DATA aid;
|
||||||
int opencl_device_index;
|
|
||||||
|
|
||||||
retval = boinc_parse_init_data_file();
|
retval = boinc_parse_init_data_file();
|
||||||
if (retval) return retval;
|
if (retval) return retval;
|
||||||
|
@ -111,19 +227,13 @@ int boinc_get_opencl_ids(cl_device_id* device, cl_platform_id* platform) {
|
||||||
return ERR_NOT_FOUND;
|
return ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
opencl_device_index = aid.gpu_opencl_dev_index;
|
if ((aid.gpu_opencl_dev_index < 0) && (aid.gpu_device_num < 0)) {
|
||||||
if (opencl_device_index < 0) {
|
|
||||||
// Older versions of init_data.xml don't have gpu_opencl_dev_index field
|
|
||||||
opencl_device_index = aid.gpu_device_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opencl_device_index < 0) {
|
|
||||||
fprintf(stderr, "GPU device # not found in %s\n", INIT_DATA_FILE);
|
fprintf(stderr, "GPU device # not found in %s\n", INIT_DATA_FILE);
|
||||||
return ERR_NOT_FOUND;
|
return ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = boinc_get_opencl_ids_aux(
|
retval = boinc_get_opencl_ids_aux(
|
||||||
aid.gpu_type, opencl_device_index, device, platform
|
aid.gpu_type, aid.gpu_opencl_dev_index, aid.gpu_device_num, device, platform
|
||||||
);
|
);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -25,4 +25,4 @@
|
||||||
|
|
||||||
#include "cl_boinc.h"
|
#include "cl_boinc.h"
|
||||||
|
|
||||||
int boinc_get_opencl_ids(cl_device_id*, cl_platform_id*);
|
int boinc_get_opencl_ids(int argc, char** argv, char *type, cl_device_id* device, cl_platform_id* platform);int boinc_get_opencl_ids(cl_device_id* device, cl_platform_id* platform);
|
||||||
|
|
|
@ -7228,3 +7228,10 @@ David 2 Dec 2012
|
||||||
html/inc/
|
html/inc/
|
||||||
result.inc
|
result.inc
|
||||||
util.inc
|
util.inc
|
||||||
|
|
||||||
|
Charlie 4 Dec 2012
|
||||||
|
- OpenCL: Add a second API for boinc_get_opencl_ids() which is
|
||||||
|
compatible with older clients (before BOINC 7.0.12).
|
||||||
|
|
||||||
|
api/
|
||||||
|
boinc_opencl.cpp,h
|
||||||
|
|
Loading…
Reference in New Issue