diff options
Diffstat (limited to 'src/compute/skc/platforms/cl_12/runtime_cl.c')
-rw-r--r-- | src/compute/skc/platforms/cl_12/runtime_cl.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/src/compute/skc/platforms/cl_12/runtime_cl.c b/src/compute/skc/platforms/cl_12/runtime_cl.c new file mode 100644 index 0000000000..a745ed013e --- /dev/null +++ b/src/compute/skc/platforms/cl_12/runtime_cl.c @@ -0,0 +1,362 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can + * be found in the LICENSE file. + * + */ + +// +// +// + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +// +// +// + +#include "runtime_cl.h" +#include "common/cl/assert_cl.h" + +// +// +// + +static is_verbose = true; + +// +// FIXME -- all variable length device queries need to start querying +// the parameter's return size before getting its value +// +// FIXME -- this is now handled by the common/cl/find.* routine +// + +union skc_cl_device_version { + struct { + cl_uchar opencl_space[7]; // "OpenCL_" + cl_uchar major; + cl_uchar dot; + cl_uchar minor; +#if 1 // Intel NEO requires at least 16 bytes + cl_uchar space; + cl_uchar vendor[32]; +#endif + }; + struct { + cl_uchar aN[]; + }; +}; + +typedef cl_bitfield cl_diagnostic_verbose_level_intel; + +#define CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL 0x4106 +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL 0x2 +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL 0x1 +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL 0x4 + +static +void +CL_CALLBACK +skc_context_callback(char const * error, void const * info, size_t size, void * user) +{ + if (info != NULL ) + { + fprintf(stderr,"%s\n",error); + } +} + +// +// +// + +skc_err +skc_runtime_cl_create(struct skc_runtime_cl * const runtime_cl, + char const * const target_platform_substring, + char const * const target_device_substring, + cl_context_properties context_properties[]) +{ + skc_err err = SKC_ERR_SUCCESS; + + // + // search available devices for a match + // +#define PLATFORM_IDS_MAX 16 +#define DEVICE_IDS_MAX 16 +#define PLATFORM_NAME_SIZE_MAX 64 +#define DEVICE_NAME_SIZE_MAX 64 +#define DRIVER_VERSION_SIZE_MAX 64 + + cl_int cl_err; + + cl_platform_id platform_ids[PLATFORM_IDS_MAX]; + cl_device_id device_ids [PLATFORM_IDS_MAX][DEVICE_IDS_MAX]; + + cl_uint platform_count; + cl_uint device_count[PLATFORM_IDS_MAX]; + + cl_uint platform_idx = UINT32_MAX, device_idx = UINT32_MAX; + + bool match = false; // find _first_ match + + // + // get number of platforms + // + cl(GetPlatformIDs(PLATFORM_IDS_MAX,platform_ids,&platform_count)); + + // + // search platforms + // + for (cl_uint ii=0; ii<platform_count; ii++) + { + char platform_name[PLATFORM_NAME_SIZE_MAX]; + + cl(GetPlatformInfo(platform_ids[ii], + CL_PLATFORM_NAME, + sizeof(platform_name), + platform_name, + NULL)); + + if (!match && (strstr(platform_name,target_platform_substring) != NULL)) + { + platform_idx = ii; + } + + if (is_verbose) { + fprintf(stdout,"%2u: %s\n",ii,platform_name); + } + + cl_err = clGetDeviceIDs(platform_ids[ii], + CL_DEVICE_TYPE_ALL, + DEVICE_IDS_MAX, + device_ids[ii], + device_count+ii); + + if (cl_err != CL_DEVICE_NOT_FOUND) + cl_ok(cl_err); + + for (cl_uint jj=0; jj<device_count[ii]; jj++) + { + char device_name[DEVICE_NAME_SIZE_MAX]; + union skc_cl_device_version device_version; + cl_uint device_align_bits; + char driver_version[DRIVER_VERSION_SIZE_MAX]; + + cl(GetDeviceInfo(device_ids[ii][jj], + CL_DEVICE_NAME, + sizeof(device_name), + device_name, + NULL)); + + // FIXME -- some of these variable length parameters should + // use the "size the param before reading" idiom + cl(GetDeviceInfo(device_ids[ii][jj], + CL_DEVICE_VERSION, + sizeof(device_version), + device_version.aN, + NULL)); + + cl(GetDeviceInfo(device_ids[ii][jj], + CL_DEVICE_MEM_BASE_ADDR_ALIGN, + sizeof(device_align_bits), + &device_align_bits, + NULL)); + + cl_uint const base_align = device_align_bits / 8; // bytes + + cl(GetDeviceInfo(device_ids[ii][jj], + CL_DRIVER_VERSION, + sizeof(driver_version), + driver_version, + NULL)); + + if (!match && (platform_idx == ii) && (strstr(device_name,target_device_substring) != NULL)) + { + match = true; + device_idx = jj; + + runtime_cl->version.major = device_version.major - 48; + runtime_cl->version.minor = device_version.minor - 48; + runtime_cl->base_align = base_align; + + if (is_verbose) { + fprintf(stdout," >>>"); + } + } + else if (is_verbose) + { + fprintf(stdout," "); + } + + if (is_verbose) { + fprintf(stdout, + " %1u: %s [ %s ] [ %s ] [ %u ]\n", + jj, + device_name, + device_version.aN, + driver_version, + base_align); + } + } + } + + if (is_verbose) { + fprintf(stdout,"\n"); + } + + // + // get target platform and device + // + if (platform_idx >= platform_count) + { + fprintf(stderr,"no match for target platform substring %s\n",target_platform_substring); + exit(EXIT_FAILURE); + } + if (device_idx >= device_count[platform_idx]) + { + fprintf(stderr,"no match for target device substring %s\n",target_device_substring); + exit(EXIT_FAILURE); + } + + runtime_cl->platform_id = platform_ids[platform_idx]; + runtime_cl->device_id = device_ids [platform_idx][device_idx]; + + // + // create context + // + +#if 0 + cl_context_properties context_properties[] = + { + CL_CONTEXT_PLATFORM,(cl_context_properties)runtime_cl->platform_id, + 0 + }; +#else + context_properties[1] = (cl_context_properties)runtime_cl->platform_id; +#endif + + runtime_cl->context = clCreateContext(context_properties, + 1, + &runtime_cl->device_id, + skc_context_callback, + NULL, + &cl_err); + cl_ok(cl_err); + + // + // get device name, driver version, and unified memory flag + // + if (is_verbose) + { + char device_name[DEVICE_NAME_SIZE_MAX]; + char driver_version[DRIVER_VERSION_SIZE_MAX]; + cl_bool device_is_unified; + cl_device_svm_capabilities svm_caps; + size_t printf_buffer_size; + + cl(GetDeviceInfo(runtime_cl->device_id, + CL_DEVICE_NAME, + sizeof(device_name), + device_name, + NULL)); + + cl(GetDeviceInfo(runtime_cl->device_id, + CL_DRIVER_VERSION, + sizeof(driver_version), + driver_version, + NULL)); + + cl(GetDeviceInfo(runtime_cl->device_id, + CL_DEVICE_HOST_UNIFIED_MEMORY, + sizeof(device_is_unified), + &device_is_unified, + NULL)); + + cl(GetDeviceInfo(runtime_cl->device_id, + CL_DEVICE_SVM_CAPABILITIES, + sizeof(svm_caps), + &svm_caps, + 0)); + + cl(GetDeviceInfo(runtime_cl->device_id, + CL_DEVICE_PRINTF_BUFFER_SIZE, + sizeof(printf_buffer_size), + &printf_buffer_size, + NULL)); + + fprintf(stderr, + "CL_DEVICE_SVM_COARSE_GRAIN_BUFFER %c\n" + "CL_DEVICE_SVM_FINE_GRAIN_BUFFER %c\n" + "CL_DEVICE_SVM_FINE_GRAIN_SYSTEM %c\n" + "CL_DEVICE_SVM_ATOMICS %c\n" + "CL_DEVICE_PRINTF_BUFFER_SIZE %zu\n\n", + svm_caps & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER ? '*' : '-', + svm_caps & CL_DEVICE_SVM_FINE_GRAIN_BUFFER ? '*' : '-', + svm_caps & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM ? '*' : '-', + svm_caps & CL_DEVICE_SVM_ATOMICS ? '*' : '-', + printf_buffer_size); + } + + return err; +} + +// +// +// + +skc_err +skc_runtime_cl_dispose(struct skc_runtime_cl * const runtime_cl) +{ + // FIXME + printf("%s incomplete!\n",__func__); + + return SKC_ERR_SUCCESS; +} + +// +// +// + +cl_command_queue +skc_runtime_cl_create_cq(struct skc_runtime_cl * const runtime_cl, skc_cq_type_e const type) +{ + cl_command_queue cq; + + if (runtime_cl->version.major < 2) + { + // + // <= OpenCL 1.2 + // + cl_int cl_err; + + cq = clCreateCommandQueue(runtime_cl->context, + runtime_cl->device_id, + (cl_command_queue_properties)type, + &cl_err); cl_ok(cl_err); + } + else + { + // + // >= OpenCL 2.0 + // + cl_int cl_err; + cl_queue_properties const queue_properties[] = { + CL_QUEUE_PROPERTIES,(cl_queue_properties)type,0 + }; + + cq = clCreateCommandQueueWithProperties(runtime_cl->context, + runtime_cl->device_id, + queue_properties, + &cl_err); cl_ok(cl_err); + } + + return cq; +} + +// +// +// + |