(四) opencl测试

1、在gpu编写opencl代码

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.h>
#endif
using namespace std;
#define KERNEL(...)#__VA_ARGS__
const char *kernelSourceCode = KERNEL(__kernel void hellocl(__global uint *buffer)
{
    size_t gidx = get_global_id(0);
    size_t gidy = get_global_id(1);
    size_t lidx = get_local_id(0);
    buffer[gidx + 4 * gidy] = (1 << gidx) | (0x10 << gidy);
});
 
int main(int argc, char const *argv[])
{
    printf("hello OpenCL\n");
    cl_int status = 0;
    size_t deviceListSize;
 
    // 当前服务器上配置的仅有NVIDIA Tesla C2050 的GPU
    cl_platform_id platform = NULL;
    status = clGetPlatformIDs(1, &platform, NULL);
 
    if (status != CL_SUCCESS) {
        printf("ERROR: Getting Platforms.(clGetPlatformIDs)\n");
        return EXIT_FAILURE;
    }
 
    // 如果我们能找到相应平台,就使用它,否则返回NULL
    cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM,(cl_context_properties)platform,0};
    cl_context_properties *cprops = (NULL == platform) ? NULL : cps;
 
    // 生成 context
    cl_context context = clCreateContextFromType(cprops,CL_DEVICE_TYPE_GPU,NULL,NULL,&status);
    if (status != CL_SUCCESS) {
        printf("Error: Creating Context.(clCreateContexFromType)\n");
        return EXIT_FAILURE;
    }
 
    // 寻找OpenCL设备
 
    // 首先得到设备列表的长度
    status = clGetContextInfo(context,CL_CONTEXT_DEVICES,0,NULL,&deviceListSize);
    if (status != CL_SUCCESS) {
        printf("Error: Getting Context Info device list size, clGetContextInfo)\n");
        return EXIT_FAILURE;
    }
    cl_device_id *devices = (cl_device_id *)malloc(deviceListSize);
    if (devices == 0) {
        printf("Error: No devices found.\n");
        return EXIT_FAILURE;
    }
 
    // 现在得到设备列表
    status = clGetContextInfo(context,CL_CONTEXT_DEVICES,deviceListSize,devices,NULL);
    if (status != CL_SUCCESS) {
        printf("Error: Getting Context Info (device list, clGetContextInfo)\n");
        return EXIT_FAILURE;
    }
 
    // 装载内核程序,编译CL program ,生成CL内核实例
    size_t sourceSize[] = {strlen(kernelSourceCode)};
    cl_program program = clCreateProgramWithSource(context,1,&kernelSourceCode,sourceSize,&status);
    if (status != CL_SUCCESS) {
        printf("Error: Loading Binary into cl_program (clCreateProgramWithBinary)\n");
        return EXIT_FAILURE;
    }
 
    // 为指定的设备编译CL program.
    status = clBuildProgram(program, 1, devices, NULL, NULL, NULL);
    if (status != CL_SUCCESS) {
        printf("Error: Building Program (clBuildingProgram)\n");
        return EXIT_FAILURE;
    }
 
    // 得到指定名字的内核实例的句柄
    cl_kernel kernel = clCreateKernel(program, "hellocl", &status);
    if (status != CL_SUCCESS) {
        printf("Error: Creating Kernel from program.(clCreateKernel)\n");
        return EXIT_FAILURE;
    }
 
    // 创建 OpenCL buffer 对象
    unsigned int *outbuffer = new unsigned int [4 * 4];
    memset(outbuffer, 0, 4 * 4 * 4);
    cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, 4 * 4 * 4, NULL, &status);
 
    if (status != CL_SUCCESS) {
        printf("Error: Create Buffer, outputBuffer. (clCreateBuffer)\n");
        return EXIT_FAILURE;
    }
 
 
    //  为内核程序设置参数
    status = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&outputBuffer);
    if (status != CL_SUCCESS) {
        printf("Error: Setting kernel argument. (clSetKernelArg)\n");
        return EXIT_FAILURE;
    }
 
    // 创建一个OpenCL command queue
    cl_command_queue commandQueue = clCreateCommandQueue(context,devices[0],0,&status);
    if (status != CL_SUCCESS) {
        printf("Error: Create Command Queue. (clCreateCommandQueue)\n");
        return EXIT_FAILURE;
    }
 
 
    // 将一个kernel 放入 command queue
    size_t globalThreads[] = {4, 4};
    size_t localThreads[] = {2, 2};
    status = clEnqueueNDRangeKernel(commandQueue, kernel,2, NULL, globalThreads,localThreads, 0,NULL, NULL);
    if (status != CL_SUCCESS) {
        printf("Error: Enqueueing kernel\n");
        return EXIT_FAILURE;
    }
 
    // 确认 command queue 中所有命令都执行完毕
    status = clFinish(commandQueue);
    if (status != CL_SUCCESS) {
        printf("Error: Finish command queue\n");
        return EXIT_FAILURE;
    }
 
    // 将内存对象中的结果读回Host
    status = clEnqueueReadBuffer(commandQueue,outputBuffer, CL_TRUE, 0,4 * 4 * 4, outbuffer, 0, NULL, NULL);
    if (status != CL_SUCCESS) {
        printf("Error: Read buffer queue\n");
        return EXIT_FAILURE;
    }
 
    // Host端打印结果
    printf("out:\n");
    for (int i = 0; i < 16; ++i) {
        printf("%x ", outbuffer[i]);
        if ((i + 1) % 4 == 0)
            printf("\n");
    }
 
    // 资源回收
    status = clReleaseKernel(kernel);
    status = clReleaseProgram(program);
    status = clReleaseMemObject(outputBuffer);
    status = clReleaseCommandQueue(commandQueue);
    status = clReleaseContext(context);
 
    free(devices);
    delete outbuffer;
    return 0;
}

2、使用交叉编译工具进行编译

cmake_minimum_required(VERSION 3.5.1)
project(cl_test)
SET(CMAKE_BUILD_TYPE "Release")

# SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(tools /gzy_mnt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu)
set(CMAKE_C_COMPILER ${tools}/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/aarch64-linux-gnu-g++)

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/)


include_directories("/gzy_mnt/SDK/include/CL/")
# file(GLOB CL_LIB_DIRS "/gzy_mnt/SDK/aarch64-linux-gnu-7.4.1/lib64/*")

add_executable(${CMAKE_PROJECT_NAME} cl-test.cpp)

target_link_libraries (
        ${CMAKE_PROJECT_NAME}   
        # /gzy_mnt/SDK/aarch64-linux-gnu-7.4.1/lib64/libEGL.so.1.4.0
        # /gzy_mnt/SDK/aarch64-linux-gnu-7.4.1/lib64/libGLESv1_CM.so.1.1.0
        # /gzy_mnt/SDK/aarch64-linux-gnu-7.4.1/lib64/libGLESv2.so.2.1.0
        /gzy_mnt/SDK/aarch64-linux-gnu-7.4.1/lib64/libmali.so.0
        /gzy_mnt/SDK/aarch64-linux-gnu-7.4.1/lib64/libOpenCL.so.2
)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
test_conversions是OpenCL CTS(兼容性测试套件)中的一个测试模块,主要用于测试OpenCL实现中的数据类型转换的正确性和精度。该模块包含了多个测试用例,可以检测不同数据类型之间的转换是否正确。 具体来说,test_conversions测试模块包含以下测试内容: 1. 浮点数和整数之间的转换:测试用例涵盖了float、double、half和整数类型之间的转换,包括向下取整、向上取整、截断、饱和等不同的转换方式。 2. 有符号整数和无符号整数之间的转换:测试用例涵盖了有符号整数和无符号整数之间的转换,包括零扩展、符号扩展、截断等不同的转换方式。 3. 坐标型数据类型之间的转换:测试用例涵盖了不同坐标型数据类型之间的转换,包括坐标系相同和坐标系不同的转换方式。 4. 不同位数的整数之间的转换:测试用例涵盖了不同位数的整数之间的转换,包括扩展、截断、饱和等不同的转换方式。 进行test_conversions测试的具体步骤如下: 1. 下载并安装OpenCL CTS测试套件。 2. 运行CTS测试套件,并选择test_conversions测试模块。 3. 运行测试用例,等待测试结果。 4. 检查测试结果,查看是否有测试用例失败或出现错误。如果有失败或错误,需要对OpenCL实现进行调试和修复。 需要注意的是,test_conversions测试模块只是OpenCL CTS测试套件中的一个测试模块,还需要进行其他测试模块的测试才能全面检测OpenCL实现的正确性和兼容性。同时,测试结果也需要结合具体应用场景进行评估,以确定OpenCL实现是否满足应用需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值