`clEnqueueFillBuffer()` 仅随机正确填充缓冲区
`clEnqueueFillBuffer()` fills a buffer correctly only at random
我试图用默认值 ({-1, -2}
) 填充 OpenCL cl_int2
缓冲区,但是 OpenCL 函数 clEnqueueFillBuffer()
用 不同 值每次我 运行 它 - 缓冲区仅随机填充预期值。函数returns 错误码0
.
多个 运行s 的片段输出示例:
0 : -268435456
0 : -2147483648
0 : -536870912
0 : 268435456
0 : 0
0 : -1342177280
-1: -2
我正在 运行ning OS X 10.11.6,配备 Radeon HD 6750M 和 OpenCL 1.2 版。
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;
我可以重现这个。在配备 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
问题是您的填充图案对于您的 GPU 来说太大了。我 运行 遇到了同样的问题,试图用 cl_double
填充一个模式,就像你的 cl_int2
一样是 64 位。我认为 clEnqueueFillBuffer
正在调用一个不允许模式
的内置内核
自从 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
"corresponding" CUDA API、cudaMemset
只能接受 int
大小的模式。但是,该限制在 CUDA 文档中有说明,而 OpenCL 文档明确使用 cl_float4
(与 cl_double2
大小相同)作为示例。所以这显然是一个错误,而不是一个未记录的功能。
但我猜 Apple 已经在 macOS 10.14 中解决了这个问题,因为他们正在弃用 OPENCL!
我试图用默认值 ({-1, -2}
) 填充 OpenCL cl_int2
缓冲区,但是 OpenCL 函数 clEnqueueFillBuffer()
用 不同 值每次我 运行 它 - 缓冲区仅随机填充预期值。函数returns 错误码0
.
多个 运行s 的片段输出示例:
0 : -268435456
0 : -2147483648
0 : -536870912
0 : 268435456
0 : 0
0 : -1342177280
-1: -2
我正在 运行ning OS X 10.11.6,配备 Radeon HD 6750M 和 OpenCL 1.2 版。
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;
我可以重现这个。在配备 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
问题是您的填充图案对于您的 GPU 来说太大了。我 运行 遇到了同样的问题,试图用 cl_double
填充一个模式,就像你的 cl_int2
一样是 64 位。我认为 clEnqueueFillBuffer
正在调用一个不允许模式
自从 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
"corresponding" CUDA API、cudaMemset
只能接受 int
大小的模式。但是,该限制在 CUDA 文档中有说明,而 OpenCL 文档明确使用 cl_float4
(与 cl_double2
大小相同)作为示例。所以这显然是一个错误,而不是一个未记录的功能。
但我猜 Apple 已经在 macOS 10.14 中解决了这个问题,因为他们正在弃用 OPENCL!