blob: a745ed013e03ecc07b4ca51935efe29be3ce66b4 [file] [log] [blame]
/*
* 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;
}
//
//
//