C++Builder6使用OpenCL

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

时间: 2024-08-03 23:16:51

C++Builder6使用OpenCL的相关文章

OpenCL入门:(二:用GPU计算两个数组和)

本文编写一个计算两个数组和的程序,用CPU和GPU分别运算,计算运算时间,并且校验最后的运算结果.文中代码偏多,原理建议阅读下面文章,文中介绍了OpenCL相关名词概念. http://opencl.codeplex.com/wikipage?title=OpenCL%20Tutorials%20-%201  (英文版) http://www.cnblogs.com/leiben/archive/2012/06/05/2536508.html (博友翻译的中文版) 一.创建工程 按照OpenCL

面向OPENCL的ALTERA SDK

面向OPENCL的ALTERA SDK 使用面向开放计算语言 (OpenCL?) 的?Altera??SDK,用户可以抽象出传统的硬件 FPGA 开发流程,采用更快.更高层面的软件开发流程.在基于 x86 的主机上迅速完成 OpenCL 加速器代码仿真,获得详细的优化报告,包括专门的算法流水线相关信息,缩短编译时间,直至得到满意的内核代码结果.利用预先编写的最优?OpenCL?或者?RTL?功能,从主程序调用它们,或者直接从您的?OpenCL?内核调用它们. 什么是 OpenCL? OpenCL

编译GDAL支持OpenCL使用GPU加速

前言 GDAL库中提供的gdalwarp支持各种高性能的图像重采样算法,图像重采样算法广泛应用于图像校正,重投影,裁切,镶嵌等算法中,而且对于这些算法来说,计算坐标变换的运算量是相当少的,绝大部分运算量都在图像的重采样算法中,尤其是三次卷积采样以及更高级的重采样算法来说,运算量会成倍的增加,所以提升这些算法的处理效率优先是提高重采样的效率.由于GPU的多核心使得目前对于GPU的并行处理非常热,同时也能大幅度的提升处理速度.基于上述原因,GDALWARP也提供了基于OPENCL的GPU加速,之前在

配置VS2013 OpenCL环境

配置VS2013 OpenCL环境 1. 安装CUDA安装包 由于目前的CUDA安装包自带显卡驱动.CUAD工具.OpenCL的SDK:其中OpenCL的相关内容的默认目录有: CL文件夹的目录:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\include OpenCL.lib文件目录:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib OpenCL.dll文件目

CUDA和OpenCL异同点比较

CUDA和OpenCL异同点比较 一.概述 对CUDA和opencl有一定的编程经验,但是细心的人可以发现,OPENCL就是仿照CUDA来做的.既然两个GPU的编程框架如此相像,那么他们究竟有什么不同呢?下面就一一道来. 二.数据并行的模型 OpenCL采用的数据并行模型就是采用CUDA的数据并行模型.下面的表格反应了CUDA和opencl并行模型之间的映射关系. OpenCL CUDA Kernel函数 Kernel函数 主机程序 主机程序 N-DRange 网格 工作项 线程 工作组 线程块

GPGPU OpenCL/CUDA 高性能编程的10大注意事项

转载自:http://hc.csdn.net/contents/content_details?type=1&id=341 1.展开循环 如果提前知道了循环的次数,可以进行循环展开,这样省去了循环条件的比较次数.但是同时也不能使得kernel代码太大. 1 #include 2 using namespace std; 3 4 int main(){ 5 int sum=0; 6 for(int i=1;i<=100;i++){ 7 sum+=i; 8 } 9 10 sum=0; 11 fo

使用OpenCL+OpenCV实现图像旋转(一)

[题外话]近期申请了一个微信公众号:平凡程式人生.有兴趣的朋友可以关注,那里将会涉及更多更新OpenCL+OpenCV以及图像处理方面的文章. 最近在学习<OPENCL异构计算>,其中有一个实例是使用OpenCL实现图像旋转.这个实例中并没有涉及读取.保存.显示图像等操作,其中也存在一些小bug.在学习OpenCL之初,完整地实现这个实例还是很有意义的事情. 1.图像旋转原理 所谓图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程.这个点通常就是图像的中心. 由于是按照中心旋

OpenCL Device Information

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #ifdef __APPLE__ 5 #include <OpenCL/opencl.h> 6 #else 7 #include <CL/cl.h> 8 #endif 9 10 11 12 #define MEM_SIZE (128) 13 #define MAX_SOURCE_SIZE (0x100000) 14 15 int main() 16 { 17 cl_

很有趣的一个sourceforge论坛对话,主题关于libjpegturbo的opencl patch

第一个人说写了一个支持windows平台的patch,用于支持opencl解码,还没试过 这位老兄提了4个建议: 1. 是否有必要建立单独的Cl/目录?似乎应该是外部opencl toolkit提供的 2. 在新的c文件中包含license声明 3. libjpeg-turbo支持动态地指定底层算法,希望opencl也能采用这种方式实现 4. opencl的相关检测应该不暴露出来 这哥接着回复:我加单独的opencl目录是为了那些没有安装opencl sdk的哥们能够独立使用我们的版本而不需要单