2016-09-13 9 views
0

私が知る限り、メモリオブジェクトにアクセスするためにclEnqueueMapBufferを使用できます。読み取り/書き込み操作を使用する代わりに、デバイス上のメモリオブジェクトをホスト上のメモリ領域にマップできます。 私はそれをテストするための非常に簡単なコードを書いた。このコードはチャーター 'X'をGPUに送り、カーネルはそれに1を加えて 'Y'を得るべきですが、私はそうしません。 clEnqueueUnmapMemObjectは、GPUメモリに格納された結果をホスト上のバッファにコピーしないようです! これは私のコードです:OpenCl clEnqueueMapBufferが正しく動作しませんか?

#include <iostream> 
#include <CL\cl.h> 
using namespace std; 
#pragma warning(disable : 4996) 
#define PROGRAM "__kernel void hello(__global char* string)\ 
{\ 
string[0] = string[0] + 1;\ 
}" 

int main() { 
cl_platform_id platform; cl_device_id device; cl_context context; 
cl_program program; cl_int error; cl_build_status status; 

char *programBuffer = PROGRAM; 

// make contex 
clGetPlatformIDs(1, &platform, NULL); 
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL); 
context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL); 

//built program 
program = clCreateProgramWithSource(context, 1, (const char**)&programBuffer, nullptr, NULL); 
const char options[] = "-cl-std=CL1.1 -cl-mad-enable -Werror"; 
error = clBuildProgram(program, 1, &device, options, NULL, NULL); 

// create kernel 
cl_command_queue command_queue; 
command_queue = clCreateCommandQueue(context, device, NULL, nullptr); 
cl_kernel kernels, found_kernel; 
cl_uint num_kernels; 

error = clCreateKernelsInProgram(program, 0, nullptr, &num_kernels); 
kernels = clCreateKernel(program, "hello", nullptr); 
//make buffers 
cl_mem memobj = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR| CL_MEM_READ_WRITE, 2 * sizeof(char), nullptr, &error);//if nulptr nazarim then itt will retun null pointer 
error = clSetKernelArg(kernels, 0, sizeof(cl_mem), (void *)&memobj); 
// I am goign to send this data to GPU 
char *CPU_2_GPU_Data = new char[2]{ "X" }; 
void* mapbuffer =clEnqueueMapBuffer(command_queue, memobj, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, 2 * sizeof(char), 0, nullptr, nullptr, &error); 
memccpy(mapbuffer, CPU_2_GPU_Data, 0, 2 * sizeof(char)); 
cout<<"I am sending this dat to GPU:"<<(char*)(mapbuffer)<<endl; 
error = clEnqueueTask(command_queue, kernels, 0, nullptr, nullptr); 
clEnqueueUnmapMemObject(command_queue, memobj, mapbuffer, 1, nullptr, nullptr); 
cout << "I am getiing this data from GPU:" << (char*)(mapbuffer) << endl; 
clReleaseContext(context); 
return 0; 

}

実際に私はマッピングメモリオブジェクトを使用してGPUにデータを送信することができますが、私は結果を読ん傾けます。コードを動作させるために、GPUに明示的にデータを送信するように依頼しなければなりません:

char* newbuffer = new char[2]; 
clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0, 2 * sizeof(char), newbuffer, 0, nullptr, nullptr); 
cout << "the result is :" << newbuffer << endl; 

なぜ起こるのですか?なぜ私はメモリオブジェクトをマッピングしてGPUにデータを送ることができますが、結果を戻すことはできませんか?

+0

どのGPUを使用していますか? – Jovasa

+0

@ Jovasa私はAMD Radeon M270を使用していますが、インテル(R)HDグラフィックス5500もあります。 – MEMS

答えて

2

目的は次のとおりです。 1)ホスト上で読むためにマップします。 2)マップを解除して、GPUで再度使用できるようにします。 3)これを再度マップして、ホストから読み取ります。 4)次に、マップを解除してクリーンアップします。

あなたはマッピングされているように見えますが、タスクを起動してマッピング解除しているようです。したがって、データを読み込もうとする時点で、マップされていないためホストは実際にそれを読み取ることができません。

+0

お返事ありがとうございます! バッファをマップ解除しないと、私はまだ間違った結果を得ます!あなたは私が持っていると述べた内容に基づいて 再び 1-地図 2-アンマップ 3ランカーネル 4マップ に5-データは、現在 6-アンマップ 権利をホストに転送されますか? – MEMS

+1

右。マップされている間はホスト上でそれを読み取って、マップされていない間はデバイスで読み取る必要があります。だからあなたがマップを解除しなければ、GPUはそれを読むことができないので、それもうまくいかないでしょう。 – Lee

+0

私はそれを試みたが、うまくいかなかった! 私が試すことができる例がありますか? – MEMS

関連する問題