如何在OpenCL中使用clEnqueueWriteBufferRect

问题描述 投票:0回答:1

我想在OpenCL中使用clEnqueueReadBufferRect。为此,我需要将region定义为其通过的论证之一。但是OpenCL的引用之间存在不一致在在线reference中,提到

正在读取或写入的2D或3D矩形的(宽度,高度,深度)以字节为单位。对于2D矩形副本,区域[2]给出的深度值应为1。

但是在reference book,第77页中提到

区域定义了正在读取或写入的2D或3D矩形的(字节宽度,行高度,切片深度)。对于2D矩形副本,区域[2]给定的深度值应为1。区域中的值不能为0

但是很遗憾,这些指南都不适合我,我应该提供in的区域(列的宽度,行的高度,切片的深度),否则,当我将它们定义为字节而不是行/列时,出现错误[ C0]。现在哪个是正确的?

CL_INVALID_VALUE
buffer opencl
1个回答
0
投票

您提供的在线参考链接说:

区域

正在读取或写入的2D或3D矩形的(字节宽度,行高度,切片深度)。对于2D矩形副本,由region [2]给出的深度值应为1。region中的值不能为0。

这与您稍后引用的“参考书”一致。这是因为您的第一个链接指向OpenCL 2.0,而第二个链接指向1.2。

您提到的不一致之处在于1.2的在线手册和1.2的PDF之间,但是2.0的在线手册与PDF一致。因此,我认为这是1.2在线手册中的错误,该错误已在2.0中修复]

否则,当我将它们定义为字节而不是行/列时

什么是“列”,它与字节有何不同?

缓冲区矩形副本的“元素”始终为字节。如果要从缓冲区读取/写入一维矩形,则它仅传输 #define WGX 16 #define WGY 16 #include "misc.hpp" int main(int argc, char** argv) { int i; int n = 1000; int filterWidth = 3; int filterRadius = (int) filterWidth/2; int padding = filterRadius * 2; double h = 1.0 / n; int width_x[2]; int height_x[2]; int deviceWidth[2]; int deviceHeight[2]; int deviceDataSize[2]; for (i = 0; i < 2; ++i) { set_domain_length(n, n, height_x[i], width_x[i], i); } float* x = new float [height_x[0] * width_x[0]]; init_unknown(x, height_x[0], width_x[0], 0); set_bndryCond(x, width_x[0], h); std::vector<cl::Platform> platforms; cl::Platform::get(&platforms); assert(platforms.size() > 0); cl::Platform myPlatform = platforms[0]; std::vector<cl::Device> devices; myPlatform.getDevices(CL_DEVICE_TYPE_GPU, &devices); assert(devices.size() > 0); cl::Device myDevice = devices[0]; cl_display_info(myPlatform, myDevice); cl::Context context(myDevice); std::ifstream kernelFile("iterative_scheme.cl"); std::string src(std::istreambuf_iterator<char>(kernelFile), (std::istreambuf_iterator<char>())); cl::Program::Sources sources(1,std::make_pair(src.c_str(),src.length() + 1)); cl::Program program(context, sources); cl::CommandQueue queue(context, myDevice); deviceWidth[0] = roundUp(width_x[0], WGX); deviceHeight[0] = height_x[0]; deviceDataSize[0] = deviceWidth[0] * deviceHeight[0] * sizeof(float); cl::Buffer buffer_x; try { buffer_x = cl::Buffer(context, CL_MEM_READ_WRITE, deviceDataSize[0]); } catch (cl::Error& error) { std::cout << " ---> Problem in creating buffer(s) " << std::endl; std::cout << " ---> " << getErrorString(error) << std::endl; exit(0); } cl::size_t<3> buffer_origin; buffer_origin[0] = 0; buffer_origin[1] = 0; buffer_origin[2] = 0; cl::size_t<3> host_origin; host_origin[0] = 0; host_origin[1] = 0; host_origin[2] = 0; cl::size_t<3> region; region[0] = (size_t)(deviceWidth[0]); region[1] = (size_t)(height_x[0]); region[2] = 1; std::cout << "===> Start writing data to device" << std::endl; try { queue.enqueueWriteBufferRect(buffer_x, CL_TRUE, buffer_origin, host_origin, region, deviceWidth[0] * sizeof(float), 0, width_x[0] * sizeof(float), 0, x); } catch (cl::Error& error) { std::cout << " ---> Problem in writing data from Host to Device: " << std::endl; std::cout << " ---> " << getErrorString(error) << std::endl; exit(0); } // Build the program std::cout << "===> Start building program" << std::endl; try { program.build("-cl-std=CL2.0"); std::cout << " ---> Build Successfully " << std::endl; } catch(cl::Error& error) { std::cout << " ---> Problem in building program " << std::endl; std::cout << " ---> " << getErrorString(error) << std::endl; std::cout << " ---> " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(myDevice) << std::endl; exit(0); } std::cout << "===> Start reading data from device" << std::endl; // read result y and residual from the device buffer_origin[0] = (size_t)(filterRadius * sizeof(float)); buffer_origin[1] = (size_t)filterRadius; buffer_origin[2] = 0; host_origin[0] = (size_t)(filterRadius * sizeof(float)); host_origin[1] = (size_t)filterRadius; host_origin[2] = 0; // region of x region[0] = (size_t)(width_x[0] - padding); region[1] = (size_t)(height_x[0] - padding); region[2] = 1; try { queue.enqueueReadBufferRect(buffer_x, CL_TRUE, buffer_origin, host_origin, region, deviceWidth[0] * sizeof(float), 0, deviceWidth[0] * sizeof(float), 0, x); } catch (cl::Error& error) { std::cout << " ---> Problem reading buffer in device: " << std::endl; std::cout << " ---> " << getErrorString(error) << std::endl; exit(0); } delete[] (x); return 0; } 字节。 API之所以具有“行”和“切片”的原因是,如果使用2D / 3D区域,则数据之间可以有填充。但一维区域中的元素之间不能有填充。

© www.soinside.com 2019 - 2024. All rights reserved.