例程介绍
介绍如何利用edmamgr的api在OpenCL kernel上实现数据在DSP内存中的转移。
例程源码
Host端源码
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include "ocl_util.h"
#include "kernel.dsp_h"
#ifdef _TI_RTOS
#include "../rtos_main.c"
#endif
using namespace cl;
using namespace std;
const int num_chunks = 1024;
const int chunk_size = 1024;
const int bytes = num_chunks * chunk_size;
cl_uchar src [bytes];
cl_uchar dst [bytes];
#ifdef _TI_RTOS
void ocl_main(UArg arg0, UArg arg1)
{
// int argc = (int) arg0;
// char **argv = (char **) arg1;
#else
#define RETURN(x) return x
int main(int argc, char *argv[])
{
#endif
int bufsize = sizeof(src);
for (int i=0; i < bytes; ++i) { src[i] = 0xAB; dst[i] = 0; }
try
{
Context context(CL_DEVICE_TYPE_ACCELERATOR);
std::vector<Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
Buffer bufSrc (context, CL_MEM_READ_ONLY, bufsize);
Buffer bufDst (context, CL_MEM_WRITE_ONLY, bufsize);
Program::Binaries binary(1, std::make_pair(kernel_dsp_bin, sizeof(kernel_dsp_bin)));
Program program = Program(context, devices, binary);
program.build(devices);
Kernel kernel(program, "oclEcpy");
kernel.setArg(0, bufSrc);
kernel.setArg(1, bufDst);
kernel.setArg(2, chunk_size);
CommandQueue Q(context, devices[0]);
Q.enqueueWriteBuffer(bufSrc, CL_TRUE, 0, bufsize, src);
Q.enqueueNDRangeKernel(kernel,NullRange,NDRange(num_chunks),NDRange(1));
Q.enqueueReadBuffer (bufDst, CL_TRUE, 0, bufsize, dst);
}
catch (Error& err)
{
cerr << "ERROR: " << err.what() << "(" << err.err() << ", "
<< ocl_decode_error(err.err()) << ")" << endl;
}
for (int i=0; i < bytes; ++i)
if (dst[i] != 0x000000AB)
{ cout << "Failed at Element " << i << endl; RETURN(-1); }
cout << "Success!" << endl;
RETURN(0);
}
OpenCL设备源码
#include "dsp_edmamgr.h"
kernel void oclEcpy(global const char* src, global char* dst, int size)
{
int offset = get_group_id(0) * size;
EdmaMgr_Handle ev = __ocl_EdmaMgr_alloc_intrakernel(1); //初始化edma manager
if (!ev) { printf("Failed to alloc edma handle.\n"); return; }
EdmaMgr_copy1D1D(ev, (void*)(src+offset), (void*)(dst+offset), size); //传输一维数据
EdmaMgr_wait(ev); //等待edma操作完成
EdmaMgr_free(ev);
}