【问题标题】:OpenCL C++ HelloWorldOpenCL C++ HelloWorld
【发布时间】:2022-01-30 17:59:25
【问题描述】:

下午好! 我在本教程中学习 OpenCL C++:Click(没必要)

视频使用CL API版本1.2,所以我下载了OpenCL 1.2 em> 此回复中链接的标题:https://stackoverflow.com/a/57017982/11968932

Visual Studio 2022 没有显示错误,但程序会输出这些符号:

╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠

应该是"Hello World!"

这是程序本身。 主持人:

#define CL_USE_DEPRECATED_OPENCL_1_2_APIS

#include <CL/cl.hpp>
#include <iostream>
#include <fstream>

int main() 
{
    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);

    auto platform = platforms.front();
    std::vector<cl::Device> devices;
    platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);

    auto device = devices.front();

    std::ifstream helloWorldFile("HelloWorld.cl");
    std::string src(std::istreambuf_iterator<char>(helloWorldFile), (std::istreambuf_iterator<char>()) );

    cl::Program::Sources sources(1, std::make_pair(src.c_str(), src.length() + 1));

    cl::Context context(device);
    cl::Program program(context, sources);

    auto err = program.build("cl-std=CL1.2");

    char buf[16];
    cl::Buffer memBuf(context, CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY, sizeof(buf));
    cl::Kernel kernel(program, "HelloWorld", &err);
    kernel.setArg(0, memBuf);

    cl::CommandQueue queue(context, device);
    queue.enqueueTask(kernel);
    queue.enqueueReadBuffer(memBuf, CL_TRUE, 0, sizeof(buf), buf);

    std::cout << buf << " - buf" << std::endl;
}

HelloWorld.cl:

_kernel void HelloWorld(_global char* data)
{
    data[0] = 'H';
    data[1] = 'e';
    data[2] = 'l';
    data[3] = 'l';
    data[4] = 'o';
    data[5] = ' ';
    data[6] = 'W';
    data[7] = 'o';
    data[8] = 'r';
    data[9] = 'l';
    data[10] = 'd';
    data[11] = '!';
    data[12] = '\n';
}

谢谢 ;)

【问题讨论】:

  • 表示调试模式下 msvc 上未初始化的堆栈内存。相关:https://stackoverflow.com/questions/12905027/displaying-this-symbol-instead-of-desired-characters
  • 是的,这是因为程序没有启动,也没有改变缓冲区值。
  • 您确定HelloWorld.cl 文件已被读取吗?也许它在错误的文件夹中。发生错误时您的代码不会退出。
  • @drescherjm 是的,我刚刚检查过了。我可以在资源管理器和 VS 资源管理器中看到这两个文件,它们位于同一个文件夹中。我试图删除 HelloWorld.cl,但我看到了同样的错误。所以看起来它只是找不到文件,但不要显示错误。
  • @drescherjm 实际上 CL 1.2 已经过时,所以我尝试不安装具有最新版本头文件(c.hpp 和 OpenCL.lib)的当前版本的 CUDA。在这种情况下,没有函数 queue.enqueueTask(kernel);而且我不知道新版本中的哪个功能负责它。你知道吗?是的,感谢您的回复!

标签: c++ visual-studio opencl opencl-c


【解决方案1】:

三个错误:

  1. 可以是__kernelkernel,但不是_kernel 带一个下划线; __global 相同
  2. cl::Buffer memBuf(context, CL_MEM_READ_WRITE, 16*sizeof(buf)); - 这里有两件事是错误的:CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY 标志意味着设备端的缓冲区完全不可访问,它只为第一个字符分配内存(忘记了16*sizeof(buf)
  3. queue.enqueueReadBuffer(memBuf, CL_TRUE, 0, 16*sizeof(buf), (void*)buf); - 忘了16*sizeof(buf)

我还必须不带任何参数地做auto err = program.build();

另请注意:

  • 虽然有效,但堆栈分配 (char buf[16];) 会限制缓冲区大小。请改用堆分配 (char* buf = new char[16];)(不要忘记 delete[] buf;)。
  • 不要使用queue.enqueueTask(kernel);,而是使用queue.enqueueNDRangeKernel(cl_kernel, cl::NullRange, cl::NDRange(...), cl::NDRange(32));。使用它,您可以指定全局和局部范围。

最后,有点广告:我创建了一个OpenCL-Wrapper 来大大简化 OpenCL 的学习和工作。这个 Wrapper 消除了跟踪缓冲区大小或为 CPU 和设备提供重复缓冲区的需要。您需要为 HelloWorld 示例编写的代码明显更短、更容易:

#include "opencl.hpp"
int main() {
    const Device device(select_device_with_most_flops()); // compile OpenCL C code for the fastest available device
    const uint N = 16u; // size of vectors
    Memory<char> buf(device, N); // allocate memory on both host and device
    const Kernel HelloWorld(device, N, "HelloWorld", buf); // kernel that runs on the device
    HelloWorld.run(); // run add_kernel on the device
    buf.read_from_device(); // copy data from device memory to host memory
    println(buf.data());
}
#include "kernel.hpp" // note: string literals can't be arbitrarily long, so periodically interrupt with )+R(
string opencl_c_container() { return R( // ########################## begin of OpenCL C code ####################################################################

kernel void HelloWorld(global char* data) {
    data[0] = 'H';
    data[1] = 'e';
    data[2] = 'l';
    data[3] = 'l';
    data[4] = 'o';
    data[5] = 32; // spaces are wrongly converted with stringification macro, so use ascii code here instead of ' '
    data[6] = 'W';
    data[7] = 'o';
    data[8] = 'r';
    data[9] = 'l';
    data[10] = 'd';
    data[11] = '!';
    data[12] = '\n';
}

);} // ############################################################### end of OpenCL C code #####################################################################

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 2021-02-19
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多