aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/compute/skc/platforms/cl_12/runtime_cl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compute/skc/platforms/cl_12/runtime_cl.c')
-rw-r--r--src/compute/skc/platforms/cl_12/runtime_cl.c362
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;
+}
+
+//
+//
+//
+