opencl 封装简单api

这是cl代码

kernel.c

cpp 复制代码
__kernel void add_one(__global float *output,__global  float* pnum) 
{
    int x=get_global_id(0);
    output[x]+=pnum[0];
}

c代码

cpp 复制代码
#include <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<stdarg.h>

typedef struct {
    cl_platform_id platform_id;
    cl_device_id device_id;
    cl_context context;
    cl_command_queue command_queue;
    cl_program program;
    cl_kernel kernel;
    cl_mem mem_objects[10]; // 假设最多有10个内存对象
    int mem_count;
} OpenCLContext;

// 初始化OpenCL上下文
void cl_init(OpenCLContext *ctx) {
    cl_int err;
    ctx->mem_count = 0;

    // 获取平台ID
    clGetPlatformIDs(1, &ctx->platform_id, NULL);

    // 获取设备ID
    clGetDeviceIDs(ctx->platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &ctx->device_id, NULL);

    // 创建上下文
    ctx->context = clCreateContext(NULL, 1, &ctx->device_id, NULL, NULL, &err);
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to create OpenCL context\n");
        exit(EXIT_FAILURE);
    }

    // 创建命令队列
    ctx->command_queue = clCreateCommandQueue(ctx->context, ctx->device_id, 0, &err);
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to create OpenCL command queue\n");
        exit(EXIT_FAILURE);
    }
    //ctx->command_queue=1;
}

// 加载OpenCL程序
void cl_load(OpenCLContext *ctx, const char *source,char*funcname) {
    cl_int err;

    // 创建程序
    ctx->program = clCreateProgramWithSource(ctx->context, 1, (const char **)&source, NULL, &err);
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to create OpenCL program\n");
        exit(EXIT_FAILURE);
    }

    // 构建程序
    err = clBuildProgram(ctx->program, 1, &ctx->device_id, NULL, NULL, NULL);
    if (err != CL_SUCCESS) {
        char build_log[1024];
        clGetProgramBuildInfo(ctx->program, ctx->device_id, CL_PROGRAM_BUILD_LOG, sizeof(build_log), build_log, NULL);
        fprintf(stderr, "Failed to build OpenCL program:\n%s\n", build_log);
        exit(EXIT_FAILURE);
    }

    // 创建内核
    ctx->kernel = clCreateKernel(ctx->program, funcname, &err); // 假设内核名为my_kernel
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to create OpenCL kernel\n");
        exit(EXIT_FAILURE);
    }
}

// 分配OpenCL内存
cl_mem cl_malloc(OpenCLContext *ctx, size_t size) {
    cl_int err;
    cl_mem mem = clCreateBuffer(ctx->context, CL_MEM_READ_WRITE, size, NULL, &err);
    if (err == CL_SUCCESS && ctx->mem_count < 10) {
        ctx->mem_objects[ctx->mem_count++] = mem;
    } else {
        fprintf(stderr, "Failed to allocate OpenCL memory\n");
        exit(EXIT_FAILURE);
    }
    return mem;
}

// 向OpenCL内存写入数据
void cl_write(OpenCLContext *ctx, cl_mem mem, const void *data, size_t size) {
    cl_int err;
    err = clEnqueueWriteBuffer(ctx->command_queue, mem, CL_TRUE, 0, size, data, 0, NULL, NULL);
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to write to OpenCL memory\n");
        exit(EXIT_FAILURE);
    }
}

// 从OpenCL内存读取数据
void cl_read(OpenCLContext *ctx, cl_mem mem, void *data, size_t size) {
    cl_int err;
    err = clEnqueueReadBuffer(ctx->command_queue, mem, CL_TRUE, 0, size, data, 0, NULL, NULL);
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to read from OpenCL memory\n");
        exit(EXIT_FAILURE);
    }
}

// 执行OpenCL内核
void cl_exec(OpenCLContext *ctx, size_t global_work_size, size_t local_work_size, int num_args, ...) {
    va_list args;
    cl_int err;

    va_start(args, num_args);
    for (int i = 0; i < num_args; i++) {
        cl_mem mem = va_arg(args, cl_mem);
        err = clSetKernelArg(ctx->kernel, i, sizeof(cl_mem), (void *)&mem);
        if (err != CL_SUCCESS) {
            fprintf(stderr, "Failed to set OpenCL kernel argument\n");
            exit(EXIT_FAILURE);
        }
    }
    va_end(args);

    err = clEnqueueNDRangeKernel(ctx->command_queue, ctx->kernel, 1, NULL, &global_work_size, &local_work_size, 0, NULL, NULL);
    if (err != CL_SUCCESS) {
        fprintf(stderr, "Failed to execute OpenCL kernel\n");
        exit(EXIT_FAILURE);
    }

    // 等待命令队列完成(可选,取决于是否需要同步)
    clFinish(ctx->command_queue);
}

// 释放OpenCL资源
void cl_free(OpenCLContext *ctx) {
    for (int i = 0; i < ctx->mem_count; i++) {
        clReleaseMemObject(ctx->mem_objects[i]);
    }
    clReleaseKernel(ctx->kernel);
    clReleaseProgram(ctx->program);
    clReleaseCommandQueue(ctx->command_queue);
    clReleaseContext(ctx->context);
}

int main() {
    OpenCLContext ctx;
    //cl_int err;

    // 初始化OpenCL上下文
    cl_init(&ctx);

    char code[512];
    memset(&code,0,sizeof(code));

    // OpenCL内核源代码(这里应该是一个完整的内核函数定义)
    const char *kernel_source = &code;
    FILE*f=fopen("kernel.cl","rb");
    fread(code,sizeof(code),1,f);
    fclose(f);

    // 加载OpenCL程序
    cl_load(&ctx, kernel_source,"add_one");

    // 分配OpenCL内存
    float data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    cl_mem buffer = cl_malloc(&ctx, sizeof(data));

    cl_mem buf2=cl_malloc(&ctx,sizeof(float));
    float f2=1;

    // 向OpenCL内存写入数据
    cl_write(&ctx, buffer, data, sizeof(data));


    cl_write(&ctx,buf2,&f2,sizeof(float));
    // 执行OpenCL内核
    size_t global_work_size = 10;
    size_t local_work_size = 1;
    cl_exec(&ctx, global_work_size, local_work_size, 2, buffer,buf2);

    // 从OpenCL内存读取数据
    float result[10];
    cl_read(&ctx, buffer, result, sizeof(result));

    // 打印结果
    for (int i = 0; i < 10; i++) {
        printf("%f\n", result[i]); // 应该打印出2, 4, 6, 8, 10, 12, 14, 16, 18, 20
    }
    puts("-----------------");
  

    //cl_write(&ctx, buffer, data, sizeof(data));
    f2=2;
    cl_write(&ctx,buf2,&f2,sizeof(float));
     // 执行OpenCL内核
    cl_exec(&ctx, global_work_size, local_work_size, 2, buffer,buf2);

    // 从OpenCL内存读取数据
    cl_read(&ctx, buffer, result, sizeof(result));

    // 打印结果
    for (int i = 0; i < 10; i++) {
        printf("%f\n", result[i]); // 应该打印出2, 4, 6, 8, 10, 12, 14, 16, 18, 20
    }
    puts("-----------------");

    // 释放OpenCL资源
    cl_free(&ctx);

    return 0;
}
相关推荐
我不是迈巴赫几秒前
使用tiptap快速搭建markdown/富文本编辑器
前端·javascript
竺梓君13 分钟前
同学,你真的了解spa吗
前端·javascript·vue.js
wordbaby13 分钟前
通过共享 Promise 解决前端重复请求
前端·promise
wordbaby13 分钟前
前端请求处理增加版
前端·javascript
爱的叹息14 分钟前
Java 集合框架中 `List` 接口及其子类的详细介绍,并用 UML 图表展示层次结构关系,用表格对比各个类的差异。
java·list·uml
慢知行14 分钟前
优化前端图标:SVG Sprite与Vite插件的探索之旅
前端·vue.js·vite
frontendMomo14 分钟前
从0到1搭建 react 组件库- Form 篇
前端·javascript
我不是迈巴赫16 分钟前
只用过传统搜索方式?来试试url持久化搜索
前端·javascript
逆袭的小黄鸭16 分钟前
仿 ElementPlus 组件库(一)—— 初始化项目与 Button 组件实现
前端·vue.js
webgzh90724718917 分钟前
前端多语言加载优化
前端