opencl 核函数创建存储器对象以实现向量

__kernel
void vector_add(global const float *a,global const float *b,global float *result)
{
    int gid = get_global_id(0);
    result[gid] = a[gid] + b[gid];
}
复制代码
  接下来是分过程的各个阶段的主要函数。
  1) 寻找设备,创建上下文
/*
1.创建平台
2.创建设备
3.根据设备创建上下文
*/
cl_context CreateContext(cl_device_id *device)
{
    cl_int errNum;
    cl_uint numPlatforms;
    cl_platform_id firstPlatformId;
    cl_context context = NULL;
    errNum = clGetPlatformIDs(1, &firstPlatformId,&numPlatforms);
    if (errNum!= CL_SUCCESS || numPlatforms <=  0)
    {
        printf( "Failed to find any OpenCL  platforms." );
        return NULL;
    }
    errNum = clGetDeviceIDs(firstPlatformId, CL_DEVICE_TYPE_GPU,1,
                            device,NULL);
    if (errNum!= CL_SUCCESS)
    {
        printf( "There is no GPU,trying CPU……" );
        errNum = clGetDeviceIDs(firstPlatformId,
                                CL_DEVICE_TYPE_CPU, 1,device,NULL);
    }
    if (errNum!= CL_SUCCESS)
    {
        printf( "There is  NO GPU or CPU" );
        return NULL;
    }
    context = clCreateContext(NULL,1, device, NULL,NULL,& errNum);
    if (errNum!= CL_SUCCESS)
    {
        printf( " create context error\n" );
        return NULL;
    }
    return context;
}
复制代码
  2) 创建队列命令
/*
@在上下文可用的第一个设备中创建命令队列
*/
cl_command_queue CreateCommandQueue(cl_context  context,
                                    cl_device_id  device)
{
    cl_int errNum;
    cl_command_queue commandQueue = NULL;
    commandQueue = clCreateCommandQueue(context, device,0,NULL);
    if (commandQueue == NULL)
    {
        printf("Failed to create commandQueue  for device 0");
        return NULL;
    }
    return commandQueue;
}
#define _FILE_ "vecAdd.cl"
#define _LINE_ 20
const int ARRAY_SIZE = 10;
char *ReadKernelSourceFile(const char *filename, size_t *length)
{
    FILE *file = NULL;
    size_t sourceLength;
    char *sourceString;
    int ret;
    file = fopen(filename,"rb");
    if(file == NULL)
    {
        printf("%s at %d:Can't open %s\n",_FILE_, _LINE_ - 2,
               filename);
        return NULL;
    }
    fseek(file,0,SEEK_END);
    sourceLength = ftell(file);
    fseek(file,0,SEEK_SET);
    sourceString = (char *)malloc(sourceLength + 1);
    sourceString[0] = '\0';
    ret = fread(sourceString,sourceLength,1, file);
    if(ret == 0)
    {
        printf("%s at %d:Can't read source %s\n", _FILE_,
               _LINE_ - 2,filename);
        return NULL;
    }
    fclose(file);
    if(length!= 0)
    {
        *length = sourceLength;
    }
    sourceString[sourceLength] = '\0';
    return sourceString;
}
/*
@读取内核源码创建OpenCL程序
*/
cl_program CreateProgram(cl_context context,
                            cl_device_id device,
                            const char *fileName)
{
    cl_int errNum;
    cl_program program;
    size_t program_length;
    //从.cl文件中获取cl代码
    char *const source = ReadKernelSourceFile(fileName,
                                                &program_length);
    // 创建程序对象
    program = clCreateProgramWithSource(context, 1,
                                        (const  char **)&source,
                                        NULL, NULL);
    if (program == NULL)
    {
        printf("Failed to create CL program from  source." );
        return NULL;
    }
    // 编译程序对象
    errNum = clBuildProgram(program,0,NULL, NULL,NULL,NULL);
    if (errNum!= CL_SUCCESS)
    {
        char buildLog[16384];
        clGetProgramBuildInfo(program,device,
                                CL_PROGRAM_BUILD_LOG,
                                sizeof(buildLog),
                                buildLog,NULL);
        printf("Error in kernel:%s ",buildLog);
        clReleaseProgram(program);
        return NULL;
    }
    return program;
}


版权声明:本文为fuli99999原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。