C++Builder6使用OpenCL具有一定意义,经过努力,已经可以运行了,记录内容供参考。(使用的是Intel集成显卡主板)
1. 转换库:OpenCL以静态库方式提供开发,Intel只有一种COFF格式静态库,C++Builder6使用OMF格式静态库,所以需要转换。C++Builder6自带coff2omf.exe转换即可。
2. 创建控制台程序,创建OpenCL目录,考入SDK安装目录下的CL文件夹,考入转换过的OpenCL.lib库文件,再创建一个OpenCL目录,考入应用源文件和头文件。
3. 修改头文件
3.1 修改考入的cl.h文件:
//修改#include <CL/cl_platform.h>为
#include "..\OpenCL\Intel\CL\cl_platform.h"。
//关闭
/* Deprecated OpenCL 1.1 APIs */
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
//clCreateImage2D(cl_context /* context */,
// cl_mem_flags /* flags */,
// const cl_image_format * /* image_format */,
// size_t /* image_width */,
// size_t /* image_height */,
// size_t /* image_row_pitch */,
// void * /* host_ptr */,
// cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
//clCreateImage3D(cl_context /* context */,
// cl_mem_flags /* flags */,
// const cl_image_format * /* image_format */,
// size_t /* image_width */,
// size_t /* image_height */,
// size_t /* image_depth */,
// size_t /* image_row_pitch */,
// size_t /* image_slice_pitch */,
// void * /* host_ptr */,
// cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
//clEnqueueMarker(cl_command_queue /* command_queue */,
// cl_event * /* event */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
//clEnqueueWaitForEvents(cl_command_queue /* command_queue */,
// cl_uint /* num_events */,
// const cl_event * /* event_list */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
//clEnqueueBarrier(cl_command_queue /* command_queue */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL
//clUnloadCompiler(void) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
//extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED void * CL_API_CALL
//clGetExtensionFunctionAddress(const char * /* func_name */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
3.2 修改考入的cl_platform.h文件:
/*typedef int16_t cl_short __attribute__((aligned(2))); typedef uint16_t cl_ushort __attribute__((aligned(2))); typedef int32_t cl_int __attribute__((aligned(4))); typedef uint32_t cl_uint __attribute__((aligned(4))); typedef int64_t cl_long __attribute__((aligned(8))); typedef uint64_t cl_ulong __attribute__((aligned(8))); typedef uint16_t cl_half __attribute__((aligned(2))); typedef float cl_float __attribute__((aligned(4))); typedef double cl_double __attribute__((aligned(8)));*/ //修改为 #pragma pack(2) typedef int16_t cl_short; typedef uint16_t cl_ushort; typedef uint16_t cl_half; #pragma pack() #pragma pack(4) typedef float cl_float; typedef int32_t cl_int; typedef uint32_t cl_uint; #pragma pack() #pragma pack(8) typedef int64_t cl_long; typedef uint64_t cl_ulong; typedef double cl_double; #pragma pack() //注意:#pragma pack只能改变结构,可能不能改变内存,未验证 //关闭 //#warning Need to implement some method to align data here
4. 将..\OpenCL\Intel\OpenCL\OpenCL.cpp加入项目,自动包含..\OpenCL\Intel\OpenCL\OpenCL.h。
OpenCL.h文件
#ifndef OpenCLH
#define OpenCLH
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS // 使用OpenCL 1.2
#include "..\OpenCL\Intel\CL\cl.h"
class COpenCL
{
public:
bool Install(void);// 安装
void ReleaseKernel(cl_kernel Kernel);// 释放核
void UnInstall(void);// 卸载
cl_mem CreateBuffer(size_t mem_size, cl_mem_flags mem_flag);// 创建缓冲区
bool WriteBuffer(cl_mem RefersBufferObject, void *pInputData, size_t mem_size);// 写缓冲区
bool ReadBuffer(cl_mem RefersBufferObject, void *pOutData, size_t mem_size);// 读缓冲区
cl_kernel CreateProgramSource(const char *pKernelProgramSource, const char *pKernelFunctionName);// 创建异构源代码
bool SetKernelArg(cl_kernel Kernel, cl_int ParamNumber, cl_mem Mem_D);// 输入核参数
bool ExecuteKernel(cl_kernel KernelName, cl_uint work_dims, const size_t *global_work_size, const size_t *local_work_size);// 运行GPU核函数
cl_uchar *MapBuf(cl_mem RefersBufferObject, size_t MapByteCount, cl_map_flags map_flag);// 映射缓冲区
void ReleaseMemObject(cl_mem MemObject);// 释放存储器资源
void Finish(void);// 等待刷新
private:
cl_device_id DevicesID; // 设备ID
cl_context Context; // 设备管理
cl_command_queue CommandQueue; // 命令队列
cl_program Program; // 核对象
};
#endif
OpenCL.cpp文件
#include "OpenCL.h"
bool COpenCL::Install(void)
{
cl_int Err; cl_platform_id PlatformID;
Err = clGetPlatformIDs(1, &PlatformID, NULL);
if (Err != CL_SUCCESS) return true;
Err = clGetDeviceIDs(PlatformID, CL_DEVICE_TYPE_GPU, 1, &DevicesID, NULL);
if (Err != CL_SUCCESS) return true;
Context = clCreateContext(0, 1, &DevicesID, NULL, NULL, &Err);
if (Err != CL_SUCCESS) return true;
CommandQueue = clCreateCommandQueue(Context, DevicesID, 0, &Err);
if (Err != CL_SUCCESS) return true;
return false;
}
void COpenCL::ReleaseKernel(cl_kernel Kernel)
{
if (Kernel != 0)
{
clReleaseKernel(Kernel);
Kernel = 0;
}
}
void COpenCL::UnInstall(void)
{
if (Program != 0)
{
clReleaseProgram(Program);
Program = 0;
}
if (CommandQueue != 0)
{
clReleaseCommandQueue(CommandQueue);
CommandQueue = 0;
}
if (Context != 0)
{
clReleaseContext(Context);
Context = 0;
}
}
cl_mem COpenCL::CreateBuffer(size_t mem_size, cl_mem_flags mem_flag)
{
return clCreateBuffer(Context, mem_flag, mem_size, NULL, NULL);
}
bool COpenCL::WriteBuffer(cl_mem RefersBufferObject, void *pInputData, size_t mem_size)
{
cl_int Err = clEnqueueWriteBuffer(CommandQueue, RefersBufferObject, CL_TRUE, 0, mem_size, pInputData, 0, NULL, NULL);
if (Err != CL_SUCCESS) return false;
return true;
}
bool COpenCL::ReadBuffer(cl_mem RefersBufferObject, void *pOutData, size_t mem_size)
{
cl_int Err = clEnqueueReadBuffer(CommandQueue, RefersBufferObject, CL_TRUE, 0, mem_size, pOutData, 0, NULL, NULL);
if (Err != CL_SUCCESS) return false;
return true;
}
cl_kernel COpenCL::CreateProgramSource(const char *pKernelProgramSource, const char *pKernelFunctionName)
{
Program = clCreateProgramWithSource(Context, 1, &pKernelProgramSource, NULL, NULL);
clBuildProgram(Program, 1, &DevicesID, NULL, NULL, NULL);
return clCreateKernel(Program, pKernelFunctionName, NULL);
}
bool COpenCL::SetKernelArg(cl_kernel Kernel, cl_int ParamNumber, cl_mem Mem_D)
{
cl_int Err = clSetKernelArg(Kernel, ParamNumber, sizeof(cl_mem), &Mem_D);
if (Err != CL_SUCCESS) return false;
return true;
}
bool COpenCL::ExecuteKernel(cl_kernel KernelName, cl_uint work_dims, const size_t *global_work_size, const size_t *local_work_size)
{
cl_int Err = clEnqueueNDRangeKernel(CommandQueue, KernelName, work_dims, NULL, global_work_size, local_work_size, 0, NULL, NULL);
if (Err != CL_SUCCESS) return false;
return true;
}
cl_uchar *COpenCL::MapBuf(cl_mem RefersBufferObject, size_t MapByteCount, cl_map_flags map_flag)
{
return (cl_uchar *)clEnqueueMapBuffer(CommandQueue, RefersBufferObject, CL_TRUE, map_flag, 0, MapByteCount, 0, NULL, NULL, NULL);
}
void COpenCL::ReleaseMemObject(cl_mem MemObject)
{
if (MemObject != 0)
{
clReleaseMemObject(MemObject);
MemObject = 0;
}
}
void COpenCL::Finish(void)
{
clFinish(CommandQueue);
}
//---------------------------------------------------------------------------
解释:
1. 因库格式不对,所以不能直接包含,转换后放在解决方案的一个相对目录中,显式链接。
2. 因C++Builder 6不认识__attribute__等,需要修改考入的包含头文件。
在Win10 C++Builder 6编译通过。
注意:可能存在潜在问题,目前简单测试没问题。
原文:https://www.cnblogs.com/hbg200/p/10203634.html