pull/2744/head
deanlee 5 years ago
parent edf9a7c5ed
commit 94c395af58
  1. 69
      selfdrive/common/clutil.cc
  2. 4
      selfdrive/common/clutil.h

@ -1,10 +1,10 @@
#include <string.h>
#include <assert.h> #include <assert.h>
#include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "util.h" #include "common/util.h"
#include "utilpp.h" #include "utilpp.h"
#include "clutil.h" #include "clutil.h"
#ifdef CLU_NO_SRC #ifdef CLU_NO_SRC
@ -17,15 +17,14 @@ void clu_init(void) {
mkdir("/tmp/clcache", 0777); mkdir("/tmp/clcache", 0777);
#endif #endif
} }
namespace { namespace { // helper functions
// helper functions
std::string get_platform_info(cl_platform_id platform, cl_platform_info param_name) { std::string get_platform_info(cl_platform_id platform, cl_platform_info param_name) {
size_t size = 0; size_t size = 0;
CL_CHECK(clGetPlatformInfo(platform, param_name, 0, NULL, &size)); CL_CHECK(clGetPlatformInfo(platform, param_name, 0, NULL, &size));
std::string ret; std::string ret;
ret.resize(size, '\0'); ret.resize(size, '\0');
CL_CHECK(clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, &ret[0], NULL)); CL_CHECK(clGetPlatformInfo(platform, param_name, size, &ret[0], NULL));
return ret; return ret;
} }
void cl_print_info(cl_platform_id platform, cl_device_id device) { void cl_print_info(cl_platform_id platform, cl_device_id device) {
@ -81,20 +80,16 @@ void cl_print_build_errors(cl_program program, cl_device_id device) {
std::unique_ptr<char[]> log = std::make_unique<char[]>(log_size + 1); 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); clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size + 1, &log[0], NULL);
printf("build failed; status=%d, log:\n%s\n", status, log); printf("build failed; status=%d, log:\n%s\n", status, &log[0]);
} }
#ifndef CLU_NO_CACHE #ifndef CLU_NO_CACHE
cl_program cached_program_from_hash(cl_context ctx, cl_device_id device_id, uint64_t hash) { cl_program load_cached_program(cl_context ctx, cl_device_id device_id, std::string cache_file) {
char cache_path[1024];
snprintf(cache_path, sizeof(cache_path), "/tmp/clcache/%016" PRIx64 ".clb", hash);
size_t bin_size; size_t bin_size;
uint8_t* bin = (uint8_t*)read_file(cache_path, &bin_size); uint8_t* bin = (uint8_t*)read_file(cache_file.c_str(), &bin_size);
if (!bin) return NULL; if (!bin) return NULL;
cl_program prg = CL_CHECK_ERR(clCreateProgramWithBinary(ctx, 1, &device_id, &bin_size, (const uint8_t**)&bin, NULL, &err)); cl_program prg = CL_CHECK_ERR(clCreateProgramWithBinary(ctx, 1, &device_id, &bin_size, (const uint8_t**)&bin, NULL, &err));
free(bin); free(bin);
CL_CHECK(clBuildProgram(prg, 1, &device_id, NULL, NULL, NULL)); CL_CHECK(clBuildProgram(prg, 1, &device_id, NULL, NULL, NULL));
@ -102,7 +97,7 @@ cl_program cached_program_from_hash(cl_context ctx, cl_device_id device_id, uint
} }
std::vector<uint8_t> get_program_binary(cl_program prg) { std::vector<uint8_t> get_program_binary(cl_program prg) {
cl_uint num_devices; cl_uint num_devices = 0;
CL_CHECK(clGetProgramInfo(prg, CL_PROGRAM_NUM_DEVICES, sizeof(num_devices), &num_devices, NULL)); CL_CHECK(clGetProgramInfo(prg, CL_PROGRAM_NUM_DEVICES, sizeof(num_devices), &num_devices, NULL));
assert(num_devices == 1); assert(num_devices == 1);
@ -116,20 +111,25 @@ std::vector<uint8_t> get_program_binary(cl_program prg) {
return binary_buf; return binary_buf;
} }
std::string get_cached_path(cl_device_id device_id, const char* src, const char* args,
const char* file, int line, const char* function) {
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);
std::string hash_buf = util::string_format("%s%s%d%s%s", platform_version.c_str(), file, line, function, src, args);
const size_t hash = std::hash<std::string>{}(hash_buf);
return util::string_format("/tmp/clcache/%016" PRIx64 ".clb", hash);
}
#endif #endif
} // namespace } // namespace
cl_device_id cl_get_device_id(cl_device_type device_type) { 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_uint num_platforms = 0;
CL_CHECK(clGetPlatformIDs(0, NULL, &num_platforms)); CL_CHECK(clGetPlatformIDs(0, NULL, &num_platforms));
std::unique_ptr<cl_platform_id[]> platform_ids = std::make_unique<cl_platform_id[]>(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)); CL_CHECK(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
char cBuffer[1024];
for (size_t i = 0; i < num_platforms; i++) { for (size_t i = 0; i < num_platforms; i++) {
std::string platform_name = get_platform_info(platform_ids[i], CL_PLATFORM_NAME); 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()); printf("platform[%zu] CL_PLATFORM_NAME: %s\n", i, platform_name.c_str());
@ -140,31 +140,23 @@ cl_device_id cl_get_device_id(cl_device_type device_type) {
continue; continue;
} }
// Get first device // Get first device
cl_device_id device_id = NULL;
CL_CHECK(clGetDeviceIDs(platform_ids[i], device_type, 1, &device_id, NULL)); CL_CHECK(clGetDeviceIDs(platform_ids[i], device_type, 1, &device_id, NULL));
cl_print_info(platform_ids[i], device_id); cl_print_info(platform_ids[i], device_id);
opencl_platform_found = true; return device_id;
break;
} }
if (!opencl_platform_found) {
printf("No valid openCL platform found\n"); printf("No valid openCL platform found\n");
assert(opencl_platform_found); assert(0);
} return nullptr;
return device_id;
} }
cl_program cl_program_from_string(cl_context ctx, cl_device_id device_id, cl_program cl_program_from_string(cl_context ctx, cl_device_id device_id, const char* src, const char* args,
const char* src, const char* args,
const char* file, int line, const char* function) { const char* file, int line, const char* function) {
cl_program prg = NULL; cl_program prg = NULL;
#ifndef CLU_NO_CACHE #ifndef CLU_NO_CACHE
cl_platform_id platform; std::string cache_path = get_cached_path(device_id, src, args, file, line, function);
CL_CHECK(clGetDeviceInfo(device_id, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL)); prg = load_cached_program(ctx, device_id, cache_path);
std::string platform_version = get_platform_info(platform, CL_PLATFORM_VERSION);
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);
#endif #endif
if (prg == NULL) { if (prg == NULL) {
prg = CL_CHECK_ERR(clCreateProgramWithSource(ctx, 1, (const char**)&src, NULL, &err)); prg = CL_CHECK_ERR(clCreateProgramWithSource(ctx, 1, (const char**)&src, NULL, &err));
@ -178,22 +170,19 @@ cl_program cl_program_from_string(cl_context ctx, cl_device_id device_id,
#ifndef CLU_NO_CACHE #ifndef CLU_NO_CACHE
// write program binary to cache // write program binary to cache
std::vector<uint8_t> binary_buf = get_program_binary(prg); std::vector<uint8_t> binary_buf = get_program_binary(prg);
char cache_path[1024]; write_file(cache_path.c_str(), binary_buf.data(), binary_buf.size());
snprintf(cache_path, sizeof(cache_path), "/tmp/clcache/%016" PRIx64 ".clb", hash);
write_file(cache_path, binary_buf.data(), binary_buf.size());
#endif #endif
} }
return prg; return prg;
} }
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) { 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); std::string src_buf = util::read_file(path);
return cl_program_from_string(ctx, device_id, &src_buf[0], args, file, line, function); return cl_program_from_string(ctx, device_id, &src_buf[0], args, file, line, function);
} }
/* // Given a cl code and return a string represenation
* Given a cl code and return a string represenation
*/
const char* cl_get_error_string(int err) { const char* cl_get_error_string(int err) {
switch (err) { switch (err) {
case 0: return "CL_SUCCESS"; case 0: return "CL_SUCCESS";

@ -28,10 +28,8 @@ extern "C" {
}) })
void clu_init(void); void clu_init(void);
cl_device_id cl_get_device_id(cl_device_type device_type); cl_device_id cl_get_device_id(cl_device_type device_type);
cl_program cl_program_from_string(cl_context ctx, cl_device_id device_id, cl_program cl_program_from_string(cl_context ctx, cl_device_id device_id, const char* src, const char* args,
const char* src, const char* args,
const char* file, int line, const char* function); const char* file, int line, const char* function);
cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args, 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); const char* file, int line, const char* function);

Loading…
Cancel
Save