blob: edb2594fba89e0e2d2db2b481e3b5a65cd1bfd05 [file] [log] [blame]
/*
* cl_kernel.cpp - CL kernel
*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author: Wind Yuan <feng.yuan@intel.com>
*/
#include "cl_kernel.h"
#include "cl_context.h"
#include "cl_device.h"
#define XCAM_CL_KERNEL_DEFAULT_WORK_DIM 2
#define XCAM_CL_KERNEL_DEFAULT_LOCAL_WORK_SIZE 1
namespace XCam {
CLKernel::CLKernel(SmartPtr<CLContext> &context, const char *name)
: _name (NULL)
, _kernel_id (NULL)
, _context (context)
, _work_dim (0)
{
XCAM_ASSERT (context.ptr ());
XCAM_ASSERT (name);
if (name)
_name = strdup (name);
set_default_work_size ();
}
CLKernel::~CLKernel ()
{
destroy ();
if (_name)
xcam_free (_name);
}
void
CLKernel::destroy ()
{
_context->destroy_kernel_id (_kernel_id);
}
XCamReturn
CLKernel::load_from_source (const char *source, size_t length)
{
cl_kernel new_kernel_id = NULL;
XCAM_ASSERT (source);
if (!source) {
XCAM_LOG_WARNING ("kernel:%s source empty", XCAM_STR (_name));
return XCAM_RETURN_ERROR_PARAM;
}
if (_kernel_id) {
XCAM_LOG_WARNING ("kernel:%s already build yet", XCAM_STR (_name));
return XCAM_RETURN_ERROR_PARAM;
}
XCAM_ASSERT (_context.ptr ());
if (length == 0)
length = strlen (source);
new_kernel_id =
_context->generate_kernel_id (
this,
(const uint8_t *)source, length,
CLContext::KERNEL_BUILD_SOURCE);
XCAM_FAIL_RETURN(
WARNING,
new_kernel_id != NULL,
XCAM_RETURN_ERROR_CL,
"cl kernel(%s) load from source failed", XCAM_STR (_name));
_kernel_id = new_kernel_id;
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
CLKernel::load_from_binary (const uint8_t *binary, size_t length)
{
cl_kernel new_kernel_id = NULL;
XCAM_ASSERT (binary);
if (!binary || !length) {
XCAM_LOG_WARNING ("kernel:%s binary empty", XCAM_STR (_name));
return XCAM_RETURN_ERROR_PARAM;
}
if (_kernel_id) {
XCAM_LOG_WARNING ("kernel:%s already build yet", XCAM_STR (_name));
return XCAM_RETURN_ERROR_PARAM;
}
XCAM_ASSERT (_context.ptr ());
new_kernel_id =
_context->generate_kernel_id (
this,
binary, length,
CLContext::KERNEL_BUILD_BINARY);
XCAM_FAIL_RETURN(
WARNING,
new_kernel_id != NULL,
XCAM_RETURN_ERROR_CL,
"cl kernel(%s) load from binary failed", XCAM_STR (_name));
_kernel_id = new_kernel_id;
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
CLKernel::set_argument (uint32_t arg_i, void *arg_addr, uint32_t arg_size)
{
cl_int error_code = clSetKernelArg (_kernel_id, arg_i, arg_size, arg_addr);
if (error_code != CL_SUCCESS) {
XCAM_LOG_DEBUG ("kernel(%s) set arg_i(%d) failed", _name, arg_i);
return XCAM_RETURN_ERROR_CL;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
CLKernel::set_work_size (uint32_t dim, size_t *global, size_t *local)
{
uint32_t i = 0;
uint32_t work_group_size = 1;
const CLDevieInfo &dev_info = CLDevice::instance ()->get_device_info ();
XCAM_FAIL_RETURN (
WARNING,
dim <= dev_info.max_work_item_dims,
XCAM_RETURN_ERROR_PARAM,
"kernel(%s) work dims(%d) greater than device max dims(%d)",
_name, dim, dev_info.max_work_item_dims);
for (i = 0; i < dim; ++i) {
work_group_size *= local [i];
XCAM_FAIL_RETURN (
WARNING,
local [i] <= dev_info.max_work_item_sizes [i],
XCAM_RETURN_ERROR_PARAM,
"kernel(%s) work item(%d) size:%d is greater than device max work item size(%d)",
_name, i, local [i], dev_info.max_work_item_sizes [i]);
}
XCAM_FAIL_RETURN (
WARNING,
work_group_size <= dev_info.max_work_group_size,
XCAM_RETURN_ERROR_PARAM,
"kernel(%s) work-group-size:%d is greater than device max work-group-size(%d)",
_name, work_group_size, dev_info.max_work_group_size);
_work_dim = dim;
for (i = 0; i < dim; ++i) {
_global_work_size [i] = global [i];
_local_work_size [i] = local [i];
}
return XCAM_RETURN_NO_ERROR;
}
void
CLKernel::set_default_work_size ()
{
_work_dim = XCAM_CL_KERNEL_DEFAULT_WORK_DIM;
for (uint32_t i = 0; i < _work_dim; ++i) {
//_global_work_size [i] = XCAM_CL_KERNEL_DEFAULT_GLOBAL_WORK_SIZE;
_local_work_size [i] = XCAM_CL_KERNEL_DEFAULT_LOCAL_WORK_SIZE;
}
}
XCamReturn
CLKernel::execute (
const cl_event *events_wait,
uint32_t num_of_events_wait,
cl_event *event_out)
{
XCAM_ASSERT (_context.ptr ());
return _context->execute_kernel (this, NULL, events_wait, num_of_events_wait, event_out);
}
};