From 71383294df4b7f49b1fe02f8d322901dfed7a114 Mon Sep 17 00:00:00 2001 From: Yifan Zhao <yifanz16@illinois.edu> Date: Thu, 23 Jan 2020 18:46:26 -0600 Subject: [PATCH] Look for device by name in opencl --- hpvm/projects/hpvm-rt/hpvm-rt.cpp | 221 ++++++++++++++++++++++++++++-- 1 file changed, 208 insertions(+), 13 deletions(-) diff --git a/hpvm/projects/hpvm-rt/hpvm-rt.cpp b/hpvm/projects/hpvm-rt/hpvm-rt.cpp index cb3206ef50..266d6296dc 100644 --- a/hpvm/projects/hpvm-rt/hpvm-rt.cpp +++ b/hpvm/projects/hpvm-rt/hpvm-rt.cpp @@ -1,4 +1,5 @@ #include <CL/cl.h> +#include <algorithm> #include <cassert> #include <cstdio> #include <cstdlib> @@ -24,8 +25,6 @@ #define BILLION 1000000000LL -using namespace std; - typedef struct { pthread_t threadID; std::vector<pthread_t> *threads; @@ -60,10 +59,152 @@ pthread_mutex_t ocl_mtx; #define NUM_TESTS 1 hpvm_TimerSet kernel_timer; +static const char *getErrorString(cl_int error) { + switch (error) { + // run-time and JIT compiler errors + case 0: + return "CL_SUCCESS"; + case -1: + return "CL_DEVICE_NOT_FOUND"; + case -2: + return "CL_DEVICE_NOT_AVAILABLE"; + case -3: + return "CL_COMPILER_NOT_AVAILABLE"; + case -4: + return "CL_MEM_OBJECT_ALLOCATION_FAILURE"; + case -5: + return "CL_OUT_OF_RESOURCES"; + case -6: + return "CL_OUT_OF_HOST_MEMORY"; + case -7: + return "CL_PROFILING_INFO_NOT_AVAILABLE"; + case -8: + return "CL_MEM_COPY_OVERLAP"; + case -9: + return "CL_IMAGE_FORMAT_MISMATCH"; + case -10: + return "CL_IMAGE_FORMAT_NOT_SUPPORTED"; + case -11: + return "CL_BUILD_PROGRAM_FAILURE"; + case -12: + return "CL_MAP_FAILURE"; + case -13: + return "CL_MISALIGNED_SUB_BUFFER_OFFSET"; + case -14: + return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"; + case -15: + return "CL_COMPILE_PROGRAM_FAILURE"; + case -16: + return "CL_LINKER_NOT_AVAILABLE"; + case -17: + return "CL_LINK_PROGRAM_FAILURE"; + case -18: + return "CL_DEVICE_PARTITION_FAILED"; + case -19: + return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"; + + // compile-time errors + case -30: + return "CL_INVALID_VALUE"; + case -31: + return "CL_INVALID_DEVICE_TYPE"; + case -32: + return "CL_INVALID_PLATFORM"; + case -33: + return "CL_INVALID_DEVICE"; + case -34: + return "CL_INVALID_CONTEXT"; + case -35: + return "CL_INVALID_QUEUE_PROPERTIES"; + case -36: + return "CL_INVALID_COMMAND_QUEUE"; + case -37: + return "CL_INVALID_HOST_PTR"; + case -38: + return "CL_INVALID_MEM_OBJECT"; + case -39: + return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; + case -40: + return "CL_INVALID_IMAGE_SIZE"; + case -41: + return "CL_INVALID_SAMPLER"; + case -42: + return "CL_INVALID_BINARY"; + case -43: + return "CL_INVALID_BUILD_OPTIONS"; + case -44: + return "CL_INVALID_PROGRAM"; + case -45: + return "CL_INVALID_PROGRAM_EXECUTABLE"; + case -46: + return "CL_INVALID_KERNEL_NAME"; + case -47: + return "CL_INVALID_KERNEL_DEFINITION"; + case -48: + return "CL_INVALID_KERNEL"; + case -49: + return "CL_INVALID_ARG_INDEX"; + case -50: + return "CL_INVALID_ARG_VALUE"; + case -51: + return "CL_INVALID_ARG_SIZE"; + case -52: + return "CL_INVALID_KERNEL_ARGS"; + case -53: + return "CL_INVALID_WORK_DIMENSION"; + case -54: + return "CL_INVALID_WORK_GROUP_SIZE"; + case -55: + return "CL_INVALID_WORK_ITEM_SIZE"; + case -56: + return "CL_INVALID_GLOBAL_OFFSET"; + case -57: + return "CL_INVALID_EVENT_WAIT_LIST"; + case -58: + return "CL_INVALID_EVENT"; + case -59: + return "CL_INVALID_OPERATION"; + case -60: + return "CL_INVALID_GL_OBJECT"; + case -61: + return "CL_INVALID_BUFFER_SIZE"; + case -62: + return "CL_INVALID_MIP_LEVEL"; + case -63: + return "CL_INVALID_GLOBAL_WORK_SIZE"; + case -64: + return "CL_INVALID_PROPERTY"; + case -65: + return "CL_INVALID_IMAGE_DESCRIPTOR"; + case -66: + return "CL_INVALID_COMPILER_OPTIONS"; + case -67: + return "CL_INVALID_LINKER_OPTIONS"; + case -68: + return "CL_INVALID_DEVICE_PARTITION_COUNT"; + + // extension errors + case -1000: + return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR"; + case -1001: + return "CL_PLATFORM_NOT_FOUND_KHR"; + case -1002: + return "CL_INVALID_D3D10_DEVICE_KHR"; + case -1003: + return "CL_INVALID_D3D10_RESOURCE_KHR"; + case -1004: + return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR"; + case -1005: + return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR"; + default: + return "Unknown OpenCL error"; + } +} + static inline void checkErr(cl_int err, cl_int success, const char *name) { if (err != success) { cout << "ERROR: " << name << flush << "\n"; - cout << "ErrorCode: " << err << flush << "\n"; + cout << "ErrorCode: " << getErrorString(err) << flush << "\n"; exit(EXIT_FAILURE); } } @@ -1210,6 +1351,61 @@ void llvm_hpvm_x86_wait(void *graphID) { DEBUG(cout << "\t... pthread Done!\n"); } +// Returns the platform name. +std::string getPlatformName(cl_platform_id pid) { + cl_int status; + + size_t sz; + status = clGetPlatformInfo(pid, CL_PLATFORM_NAME, 0, NULL, &sz); + checkErr(status, CL_SUCCESS, "Query for platform name size failed"); + + char *name = new char[sz]; + status = clGetPlatformInfo(pid, CL_PLATFORM_NAME, sz, name, NULL); + checkErr(status, CL_SUCCESS, "Query for platform name failed"); + + const auto &tmp = std::string(name, name + sz); + delete[] name; + return tmp; +} + +// Searches all platforms for the first platform whose name +// contains the search string (case-insensitive). +cl_platform_id findPlatform(const char *platform_name_search) { + cl_int status; + + std::string search = platform_name_search; + std::transform(search.begin(), search.end(), search.begin(), ::tolower); + + // Get number of platforms. + cl_uint num_platforms; + status = clGetPlatformIDs(0, NULL, &num_platforms); + checkErr(status, CL_SUCCESS, "Query for number of platforms failed"); + + // Get a list of all platform ids. + cl_platform_id *pids = + (cl_platform_id *)malloc(sizeof(cl_platform_id) * num_platforms); + status = clGetPlatformIDs(num_platforms, pids, NULL); + checkErr(status, CL_SUCCESS, "Query for all platform ids failed"); + + // For each platform, get name and compare against the search string. + for (unsigned i = 0; i < num_platforms; ++i) { + std::string name = getPlatformName(pids[i]); + + // Convert to lower case. + std::transform(name.begin(), name.end(), name.begin(), ::tolower); + + if (name.find(search) != std::string::npos) { + // Found! + free(pids); + return pids[i]; + } + } + + free(pids); + // No platform found. + assert(false && "No matching platform found!"); +} + void *llvm_hpvm_ocl_initContext(enum hpvm::Target T) { pthread_mutex_lock(&ocl_mtx); DEBUG(std::string Target = T == hpvm::GPU_TARGET ? "GPU" : "SPIR"); @@ -1240,20 +1436,19 @@ void *llvm_hpvm_ocl_initContext(enum hpvm::Target T) { NULL); DEBUG(cout << "\tEXTENSIONS = " << buffer << flush << "\n"); } - // set platform property - just pick the first one - // cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, - //(long) platforms[0], - // 0}; - // globalOCLContext = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, - // NULL, NULL, &errcode); - // assert(numPlatforms >= 2 && "Expecting two OpenCL platforms"); - // Choose second one which is X86 AVX - cl_context_properties properties[] = { - CL_CONTEXT_PLATFORM, (long)platforms[T == hpvm::GPU_TARGET ? 0 : 1], 0}; + cl_platform_id platformId; + if (T == hpvm::GPU_TARGET) { + platformId = findPlatform("nvidia"); + } else { + platformId = findPlatform("intel"); + } + cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (long)platformId, + 0}; globalOCLContext = clCreateContextFromType( properties, T == hpvm::GPU_TARGET ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, NULL, NULL, &errcode); + checkErr(errcode, CL_SUCCESS, "Failure to create context"); // get the list of OCL devices associated with context size_t dataBytes; errcode = clGetContextInfo(globalOCLContext, CL_CONTEXT_DEVICES, 0, NULL, -- GitLab