openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
11 KiB

6 years ago
#include <string.h>
5 years ago
#include <assert.h>
6 years ago
#include <inttypes.h>
#include <sys/stat.h>
#include <memory>
#include <vector>
5 years ago
#include "util.h"
#include "utilpp.h"
6 years ago
#include "clutil.h"
#ifdef CLU_NO_SRC
#include "clcache_bins.h"
#else
#endif
void clu_init(void) {
#ifndef CLU_NO_SRC
mkdir("/tmp/clcache", 0777);
#endif
}
namespace {
// helper functions
6 years ago
std::string get_platform_info(cl_platform_id platform, cl_platform_info param_name) {
6 years ago
size_t size = 0;
CL_CHECK(clGetPlatformInfo(platform, param_name, 0, NULL, &size));
std::string ret;
ret.resize(size, '\0');
CL_CHECK(clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, &ret[0], NULL));
return ret;
6 years ago
}
void cl_print_info(cl_platform_id platform, cl_device_id device) {
std::string info = get_platform_info(platform, CL_PLATFORM_VENDOR);
printf("vendor: '%s'\n", info.c_str());
6 years ago
info = get_platform_info(platform, CL_PLATFORM_VERSION);
printf("platform version: '%s'\n", info.c_str());
6 years ago
info = get_platform_info(platform, CL_PLATFORM_PROFILE);
printf("profile: '%s'\n", info.c_str());
6 years ago
info = get_platform_info(platform, CL_PLATFORM_EXTENSIONS);
printf("extensions: '%s'\n", info.c_str());
6 years ago
char str[4096] = {};
6 years ago
clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(str), str, NULL);
printf("name: '%s'\n", str);
clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(str), str, NULL);
printf("device version: '%s'\n", str);
size_t sz;
clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(sz), &sz, NULL);
printf("max work group size: %zu\n", sz);
6 years ago
cl_device_type type;
clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(type), &type, NULL);
printf("type = 0x%04x = ", (unsigned int)type);
switch (type) {
case CL_DEVICE_TYPE_CPU:
printf("CL_DEVICE_TYPE_CPU\n");
break;
case CL_DEVICE_TYPE_GPU:
printf("CL_DEVICE_TYPE_GPU\n");
break;
case CL_DEVICE_TYPE_ACCELERATOR:
printf("CL_DEVICE_TYPE_ACCELERATOR\n");
break;
default:
printf("Other...\n");
break;
6 years ago
}
}
void cl_print_build_errors(cl_program program, cl_device_id device) {
cl_build_status status;
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_STATUS,
sizeof(cl_build_status), &status, NULL);
6 years ago
size_t log_size;
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
6 years ago
std::unique_ptr<char[]> log = std::make_unique<char[]>(log_size + 1);
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size + 1, &log[0], NULL);
printf("build failed; status=%d, log:\n%s\n", status, log);
6 years ago
}
#ifndef CLU_NO_CACHE
cl_program cached_program_from_hash(cl_context ctx, cl_device_id device_id, uint64_t hash) {
6 years ago
char cache_path[1024];
snprintf(cache_path, sizeof(cache_path), "/tmp/clcache/%016" PRIx64 ".clb", hash);
size_t bin_size;
uint8_t* bin = (uint8_t*)read_file(cache_path, &bin_size);
if (!bin) return NULL;
6 years ago
cl_program prg = CL_CHECK_ERR(clCreateProgramWithBinary(ctx, 1, &device_id, &bin_size, (const uint8_t**)&bin, NULL, &err));
6 years ago
free(bin);
CL_CHECK(clBuildProgram(prg, 1, &device_id, NULL, NULL, NULL));
6 years ago
return prg;
}
std::vector<uint8_t> get_program_binary(cl_program prg) {
6 years ago
cl_uint num_devices;
CL_CHECK(clGetProgramInfo(prg, CL_PROGRAM_NUM_DEVICES, sizeof(num_devices), &num_devices, NULL));
6 years ago
assert(num_devices == 1);
size_t binary_size = 0;
CL_CHECK(clGetProgramInfo(prg, CL_PROGRAM_BINARY_SIZES, sizeof(binary_size), &binary_size, NULL));
6 years ago
assert(binary_size > 0);
std::vector<uint8_t> binary_buf(binary_size);
uint8_t* bufs[] = {&binary_buf[0]};
CL_CHECK(clGetProgramInfo(prg, CL_PROGRAM_BINARIES, sizeof(bufs), &bufs, NULL));
6 years ago
return binary_buf;
}
#endif
} // namespace
cl_device_id cl_get_device_id(cl_device_type device_type) {
bool opencl_platform_found = false;
cl_device_id device_id = NULL;
cl_uint num_platforms = 0;
CL_CHECK(clGetPlatformIDs(0, NULL, &num_platforms));
std::unique_ptr<cl_platform_id[]> platform_ids = std::make_unique<cl_platform_id[]>(num_platforms);
CL_CHECK(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
char cBuffer[1024];
for (size_t i = 0; i < num_platforms; i++) {
std::string platform_name = get_platform_info(platform_ids[i], CL_PLATFORM_NAME);
printf("platform[%zu] CL_PLATFORM_NAME: %s\n", i, platform_name.c_str());
cl_uint num_devices;
int err = clGetDeviceIDs(platform_ids[i], device_type, 0, NULL, &num_devices);
if (err != 0 || !num_devices) {
continue;
}
// Get first device
CL_CHECK(clGetDeviceIDs(platform_ids[i], device_type, 1, &device_id, NULL));
cl_print_info(platform_ids[i], device_id);
opencl_platform_found = true;
break;
}
if (!opencl_platform_found) {
printf("No valid openCL platform found\n");
assert(opencl_platform_found);
}
return device_id;
}
6 years ago
5 years ago
cl_program cl_program_from_string(cl_context ctx, cl_device_id device_id,
const char* src, const char* args,
const char* file, int line, const char* function) {
cl_program prg = NULL;
#ifndef CLU_NO_CACHE
6 years ago
cl_platform_id platform;
CL_CHECK(clGetDeviceInfo(device_id, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL));
std::string platform_version = get_platform_info(platform, CL_PLATFORM_VERSION);
6 years ago
std::string hash_buf = util::string_format("%s%c%s%c%s", platform_version.c_str(), 1, src, 1, args);
size_t hash = std::hash<std::string>{}(hash_buf);
prg = cached_program_from_hash(ctx, device_id, hash);
6 years ago
#endif
if (prg == NULL) {
prg = CL_CHECK_ERR(clCreateProgramWithSource(ctx, 1, (const char**)&src, NULL, &err));
6 years ago
int err = clBuildProgram(prg, 1, &device_id, args, NULL, NULL);
6 years ago
if (err != 0) {
cl_print_build_errors(prg, device_id);
}
assert(err == 0);
#ifndef CLU_NO_CACHE
// write program binary to cache
std::vector<uint8_t> binary_buf = get_program_binary(prg);
6 years ago
char cache_path[1024];
snprintf(cache_path, sizeof(cache_path), "/tmp/clcache/%016" PRIx64 ".clb", hash);
write_file(cache_path, binary_buf.data(), binary_buf.size());
6 years ago
#endif
}
return prg;
}
5 years ago
cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args, const char* file, int line, const char* function) {
std::string src_buf = util::read_file(path);
5 years ago
return cl_program_from_string(ctx, device_id, &src_buf[0], args, file, line, function);
6 years ago
}
/*
* Given a cl code and return a string represenation
*/
const char* cl_get_error_string(int err) {
switch (err) {
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 -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";
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";
case -69: return "CL_INVALID_PIPE_SIZE";
case -70: return "CL_INVALID_DEVICE_QUEUE";
case -71: return "CL_INVALID_SPEC_ID";
case -72: return "CL_MAX_SIZE_RESTRICTION_EXCEEDED";
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";
case -1006: return "CL_INVALID_D3D11_DEVICE_KHR";
case -1007: return "CL_INVALID_D3D11_RESOURCE_KHR";
case -1008: return "CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR";
case -1009: return "CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR";
case -1010: return "CL_INVALID_DX9_MEDIA_ADAPTER_KHR";
case -1011: return "CL_INVALID_DX9_MEDIA_SURFACE_KHR";
case -1012: return "CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR";
case -1013: return "CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR";
case -1093: return "CL_INVALID_EGL_OBJECT_KHR";
case -1092: return "CL_EGL_RESOURCE_NOT_ACQUIRED_KHR";
case -1001: return "CL_PLATFORM_NOT_FOUND_KHR";
case -1057: return "CL_DEVICE_PARTITION_FAILED_EXT";
case -1058: return "CL_INVALID_PARTITION_COUNT_EXT";
case -1059: return "CL_INVALID_PARTITION_NAME_EXT";
case -1094: return "CL_INVALID_ACCELERATOR_INTEL";
case -1095: return "CL_INVALID_ACCELERATOR_TYPE_INTEL";
case -1096: return "CL_INVALID_ACCELERATOR_DESCRIPTOR_INTEL";
case -1097: return "CL_ACCELERATOR_TYPE_NOT_SUPPORTED_INTEL";
case -1000: return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR";
case -1098: return "CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL";
case -1099: return "CL_INVALID_VA_API_MEDIA_SURFACE_INTEL";
case -1100: return "CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL";
case -1101: return "CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL";
default: return "CL_UNKNOWN_ERROR";
}
}