1. 程式人生 > >【OpenCL】OpenCL程式設計:主機與裝置的資料傳輸

【OpenCL】OpenCL程式設計:主機與裝置的資料傳輸

主機和裝置之間資料傳輸最簡單的函式是clEnqueueReadBuffer和clEnqueueWriteBuffer。

另外還有clEnqueueReadImage和clEnqueueWriteImage。

和clEnqueueReadBufferRect和clEnqueueWriteBufferRect。

它們的函式原型如下:

其中buffer_origin = buffer_origin[2] * buffer_slice_pitch + buffer_origin[1] * buffer_row_pitch + buffer_origin[0],host_origin=host_origin

[2] * host_slice_pitch + host_origin[1] * host_row_pitch + host_origin[0]。

float matrix[50], sub_matrix[50]={0};
const size_t buffer_origin[3] = { 5 * sizeof(float), 3, 0 };
const size_t host_origin[3] = { 1 * sizeof(float), 1, 0 };
const size_t region[3] = { 4 * sizeof(float), 4, 1 };
cl_mem matrix_buffer;

for (int i=0; i < 50; i++)
{
	matrix[i] = i + 1.0;
	if (i % 10 == 0)
	{
		cout << endl;
	}
	cout << matrix[i] << "  ";
}
cout << endl;

matrix_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(matrix), matrix, &err);
if (err < 0)
{
	cout << "Failed to create buffer." << err << endl;
	return err;
}

err = clSetKernelArg(found_kernel, 0, sizeof(cl_mem), &matrix_buffer);
if (err < 0)
{
	cout << "Failed to set kernel arg." << err << endl;
	return err;
}

err = clEnqueueTask(queue, found_kernel, 0, NULL, NULL);
if (err < 0)
{
	cout << "Failed to enqueue task." << err << endl;
	return err;
}

err = clEnqueueWriteBuffer(queue, matrix_buffer, CL_TRUE, 0, sizeof(matrix), matrix, 0, NULL, NULL);
if (err < 0)
{
	cout << "Failed to write buffer." << err << endl;
	return err;
}

err = clEnqueueReadBufferRect(queue, matrix_buffer, CL_TRUE, buffer_origin, 
		host_origin, region, 0, 0, 0, 0, sub_matrix, 0, NULL, NULL);
if (err < 0)
{
	cout << "Failed to read buffer rect." << err << endl;
	return err;
}

for (int i=0; i<50; i++)
{
	if (i % 10 == 0)
	{
		cout << endl;
	}
	cout << sub_matrix[i] << "  ";
}