// 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 . // BOINC API for OpenCL // The BOINC client calls the project application with the arguments: // --gpu_type TYPE --device N // where TYPE is ATI or NVIDIA, and N is the GPU number of that type // For example, for ATI GPU number 0, the arguments will be: // --gpu_type ATI --device 0 // // To get the cl_device_id and cl_platform_id for the OpenCL GPU // asigned to your application call this function: // int boinc_get_opencl_ids(int argc, char** argv, cl_device_id*, cl_platform_id*); // // NOTE: You should compile and link this function as part of your // application; it is not included in the standard BOINC libraries. // #ifdef _WIN32 #include "win_util.h" #else #ifdef __APPLE__ // Suppress obsolete warning when building for OS 10.3.9 #define DLOPEN_NO_WARN #include #endif #include "config.h" #include #include #include #endif #include #include "error_numbers.h" #include "boinc_api.h" #include "coproc.h" #include "boinc_opencl.h" #ifndef _WIN32 static jmp_buf resume; static void segv_handler(int) { longjmp(resume, 1); } #endif int boinc_get_opencl_ids_aux( char *type, int device_num, cl_device_id* device, cl_platform_id* platform ) { 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.) int retval = 0; retval = clGetPlatformIDs(MAX_OPENCL_PLATFORMS, platforms, &num_platforms); if (num_platforms == 0) return CL_DEVICE_NOT_FOUND; if (retval) return retval; for (platform_index=0; platform_index (cl_uint)(device_num + 1)) continue; cl_device_id device_id = devices[device_num]; retval = clGetDeviceInfo(device_id, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL); if (retval || strlen(vendor)==0) continue; if ((strstr(vendor, "AMD")) || (strstr(vendor, "Advanced Micro Devices, Inc.")) ) { strcpy(vendor, GPU_TYPE_ATI); } if (!strcmp(vendor, type)) { *device = device_id; *platform = platforms[platform_index]; break; } } if (device == NULL) return CL_DEVICE_NOT_FOUND; return 0; } int boinc_get_opencl_ids(cl_device_id* device, cl_platform_id* platform) { int retval=0; APP_INIT_DATA aid; boinc_parse_init_data_file(); boinc_get_init_data(aid); if (!strlen(aid.gpu_type)) { return CL_INVALID_DEVICE_TYPE; } if (aid.gpu_device_num < 0) { return CL_INVALID_DEVICE; } #ifdef _WIN32 try { retval = boinc_get_opencl_ids_aux( aid.gpu_type, aid.gpu_device_num, device, platform ); } catch (...) { return ERR_SIGNAL_CATCH; } #else void (*old_sig)(int) = signal(SIGSEGV, segv_handler); if (setjmp(resume)) { return ERR_SIGNAL_CATCH; } else { retval = boinc_get_opencl_ids_aux( aid.gpu_type, aid.gpu_device_num, device, platform ); } signal(SIGSEGV, old_sig); #endif return retval; }