In the Vitis software platform, two types of arguments can be set for kernel objects:
- Scalar arguments are used for small data transfer, such as constant or configuration type data. These are write-only arguments from the host application perspective, meaning they are inputs to the kernel.
- Memory buffer arguments are used for large data transfer. The value is a pointer to a memory object created with the context associated with the program and kernel objects. These can be inputs to, or outputs from the kernel.
Kernel arguments can be set using the
clSetKernelArg
command, as
shown in the following example for setting kernel arguments for two scalar and two
buffer arguments.
// Create memory buffers
cl_mem dev_buf1 = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, size, &host_mem_ptr1, NULL);
cl_mem dev_buf2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, size, &host_mem_ptr2, NULL);
int err = 0;
// Setup scalar arguments
cl_uint scalar_arg_image_width = 3840;
err |= clSetKernelArg(kernel, 0, sizeof(cl_uint), &scalar_arg_image_width);
cl_uint scalar_arg_image_height = 2160;
err |= clSetKernelArg(kernel, 1, sizeof(cl_uint), &scalar_arg_image_height);
// Setup buffer arguments
err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &dev_buf1);
err |= clSetKernelArg(kernel, 3, sizeof(cl_mem), &dev_buf2);
clEnqueueMigrateMemObjects
) on
any buffer. For all kernel buffer arguments you must allocate the buffer on the
device global memories. However, sometimes the content of the buffer is not required
before the start of the kernel execution. For example, the output buffer content will
only be populated during the kernel execution, and hence it is not important prior to
kernel execution. In this case, you should specify clEnqueueMigrateMemObject
with the CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED
flag so that migration of the
buffer will not involve the DMA operation between the host and the device, thus
improving performance.