'clEnqueueFillBuffer()' 仅随机正确填充缓冲区
`clEnqueueFillBuffer()` fills a buffer correctly only at random
我正在尝试用默认值({-1, -2}
(填充 OpenCL cl_int2
缓冲区,但是 OpenCL 函数每次运行时clEnqueueFillBuffer()
用不同的值填充我的缓冲区——缓冲区仅随机填充预期值。该函数返回错误代码0
。
代码段在多次运行时的输出示例:
-
0 : -268435456
-
0 : -2147483648
-
0 : -536870912
-
0 : 268435456
-
0 : 0
-
0 : -1342177280
-
-1: -2
我运行的是带有Radeon HD 6750M和OpenCL 1.2版本的OS X 10.11.6。
clbParticle_hashmap_lookup_table = clCreateBuffer(context,
CL_MEM_READ_WRITE,
sizeof(cl_int2)*this->CUBE_CELLS,
nullptr,
&err_code);
// ...
cl_int2 default_hashmap_pattern = { .s = {-1, -2} };
clEnqueueFillBuffer(queue,
clbParticle_hashmap_lookup_table,
&default_hashmap_pattern,
sizeof(cl_int2),
0,
sizeof(cl_int2)*this->CUBE_CELLS,
0,
nullptr, nullptr);
clFinish(queue);
// copy and print the data:
size_t hashmap_lookup_table_size = sizeof(cl_int2)*this->CUBE_CELLS;
cl_int2* hashmap_lookup_table_bytes = (cl_int2*) malloc(hashmap_lookup_table_size);
clEnqueueReadBuffer(queue,
clbParticle_hashmap_lookup_table,
CL_TRUE,
0,
hashmap_lookup_table_size,
hashmap_lookup_table_bytes,
0,
nullptr, nullptr);
clFinish(queue);
cout << endl << "Lookup table: " << endl;
for (int i=0; i<this->CUBE_CELLS; i++)
cout << setw(10) << hashmap_lookup_table_bytes[i].s[0] << " : "
<< setw(10) << hashmap_lookup_table_bytes[i].s[1] << endl;
问题是您的填充模式对于您的 GPU 来说太大了。我在尝试用像您的cl_int2
一样 64 位的cl_double
填充模式时遇到了同样的问题。我认为clEnqueueFillBuffer
正在调用一个不允许模式的内置内核
我可以重现这一点。在装有Radeon Pro 450的Macbook Sierra上,以下脚本:
int N = 100000;
float *a = new float[N];
cl_mem a_gpu = clCreateBuffer(context, CL_MEM_READ_WRITE, N * sizeof(float), 0, &err);
checkError(err);
for(int it = 0; it < 100; it++) {
float value = 123.0f + it;
err = clEnqueueFillBuffer(queue, a_gpu, &value, sizeof(value), 0, N * sizeof(float), 0, 0, 0);
checkError(err);
clFinish(queue);
err = clEnqueueReadBuffer(queue, a_gpu, CL_TRUE, 0,
sizeof(cl_float) * N, a, 0, NULL, NULL);
checkError(err);
clFinish(queue);
cout << it << " a[N - 1]=" << a[N - 1] << endl;
}
delete[] a;
给出的结果如下:
Using Apple , OpenCL platform: Apple
Using OpenCL device: AMD Radeon Pro 450 Compute Engine
0 a[N - 1]=-1.39445e-31
1 a[N - 1]=0
2 a[N - 1]=0
3 a[N - 1]=0
4 a[N - 1]=0
5 a[N - 1]=0
6 a[N - 1]=129
7 a[N - 1]=0
8 a[N - 1]=131
9 a[N - 1]=132
10 a[N - 1]=133
11 a[N - 1]=134
12 a[N - 1]=135
13 a[N - 1]=0
14 a[N - 1]=0
15 a[N - 1]=0
16 a[N - 1]=0
17 a[N - 1]=0
18 a[N - 1]=0
19 a[N - 1]=0
20 a[N - 1]=0
21 a[N - 1]=0
22 a[N - 1]=0
23 a[N - 1]=0
24 a[N - 1]=0
25 a[N - 1]=0
26 a[N - 1]=0
27 a[N - 1]=0
28 a[N - 1]=0
29 a[N - 1]=0
30 a[N - 1]=0
31 a[N - 1]=154
32 a[N - 1]=0
自 2017 年 3 月开始学习 OpenCL 以来,我只在 macOS 上遇到过此错误(当时不记得 macOS 版本(。GPU是GT 750M(这可能无关紧要(,pattern
是cl_double2
。在GTX 760上相同的例程Linux上没有这样的问题。我怀疑这是因为macOS上的OpenCL 1.2支持不完整,正如clinfo
(在macOS上编译和执行(警告的那样:
NOTE: your OpenCL library only supports OpenCL 1.0,
but some installed platforms support OpenCL 1.2.
Programs using 1.2 features may crash
or behave unexpectedly
cudaMemset
,"相应的"CUDA API,只能接受int
大小的模式。但是,CUDA 文档中说明了该限制,而 OpenCL 文档显然使用了 cl_float4
(大小与 cl_double2
相同(作为示例。因此,这显然是一个错误,而不是未记录的功能。
但我想苹果已经在macOS 10.14中解决了这个问题,因为他们正在弃用OPENCL!
- C++:使用缓冲区中的数据填充结构
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- 缓冲区填充了不同类型的数据和严格的混叠
- DirectX11只绘制填充索引和顶点缓冲区中的一半顶点
- 填充和保存线程之间的共享缓冲区
- strcpy_s将超过字符串长度的字符串复制到目标缓冲区(用 0xFE 填充)
- 缓冲区用不需要的数据填充 char 数组中的最后一个空格
- InternetReadFile 填充缓冲区,但返回零字节读取
- 无法使用两种不同的频率填充 *.wav 文件的缓冲区
- P/调用C++用于填充托管缓冲区的 DLL
- 是否存在以相反顺序填充缓冲区的MEMSET函数
- FFMPEG挂在缓冲区填充C 上
- 在 C++ 中填充重复的自定义协议缓冲区字段
- C - 分配一个未签名的炭缓冲区,然后用字符串填充
- C/C++ 从字符缓冲区读取以填充结构
- 如果缓冲区由数据流填充,则 C++ boost async_read_some被缓冲区阻止
- 将额外的字节填充到要通过网络发送的flatbuffer的缓冲区指针
- 在本地将数据填充到recv缓冲区中
- 在 c++ 中使用消息结构读取/填充数据缓冲区的正确方法是什么?
- 从流和缓冲区填充矢量时会产生不同的结果