ぬの部屋(仮)
nu-no-he-ya
  •    1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • OpenCLのカーネルプログラムとの引数の連絡

     

    と言うわけで、OpenCLのカーネルプログラムの引数に値を渡して、その結果を返してもらうサンプルを作った。

    カーネル側の*var1,*var2にintの値を与え、*retへ結果を格納。

    ・clCreateBufferでデバイスにメモリ確保、
    ・clEnqueueWriteBufferで確保したメモリへ値を代入
    ・clSetKernelArgでカーネルプログラムの引数に確保したメモリのアドレスを指定
    ・clEnqueueReadBufferでデバイス上のメモリから値を取得
    ・clReleaseMemObjectでデバイスのメモリを解放

    と言ったところだろうか。

    http://www.fixstars.com/ja/news/books/opencl/

    ↑この本を参考に書いたが、これ、関数のインタフェースに関してはもちろん事典として記載はあるのだが、具体的にどう使うのかは実例を見て解読するしかないという所が多いように思う。clEnqueueWriteBufferとか、なんとかググらずに済んだが不親切だ。

     

    #pragma warning(disable : 4996 )
    #include <windows.h>
    #include <CL/cl.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #pragma comment(lib,"OpenCL.lib")
    #define MAX_SOURCE_SIZE 0x100000
    int cl_inout(){
        cl_device_id device_id = NULL;
        cl_context context = NULL;
        cl_command_queue command_queue = NULL;
    
        cl_program program = NULL;
        cl_kernel kernel = NULL;
        cl_platform_id platform_id = NULL;
        cl_uint ret_num_devices;
        cl_uint ret_num_platforms;
        cl_int ret;
    
    
        char *source_str;
        size_t source_size;
    
    
        source_str = (char*)malloc(MAX_SOURCE_SIZE);
        strcpy(source_str,
            "__kernel void hello("
            "   __global int* var1,"
            "   __global int* var2,"
            "   __global int* ret"
            ")\n"
            "{\n"
            "    *ret = *var1 + *var2;\n"
            "}\n"
            );
        source_size = strlen(source_str);
    
        /* プラットフォーム・デバイスの情報の取得 */
        ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
        ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &ret_num_devices);
    
        /* OpenCLコンテキストの作成 */
        context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
    
        /* コマンドキューの作成 */
        command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
    
    
        /* メモリバッファの作成 引数として使用 */
        cl_mem arg1_X = NULL;
        cl_mem arg2_Y = NULL;
        cl_mem arg3_R = NULL;
        arg1_X = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, &ret);
        arg2_Y = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, &ret);
        arg3_R = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, &ret);
    
        /* 読み込んだソースからカーネルプログラムを作成 */
        program = clCreateProgramWithSource(context, 1, (const char **)&source_str,
            (const size_t *)&source_size, &ret);
    
        /* カーネルプログラムをビルド */
        ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
    
        /* OpenCL カーネルの作成 */
        kernel = clCreateKernel(program, "hello", &ret);
    
        /* カーネルプログラムの引数に値を設定 */
        int val1 = 20, val2 = 50;
        clEnqueueWriteBuffer(command_queue, arg1_X, CL_TRUE, 0, sizeof(int), &val1, 0, nullptr, nullptr);
        clEnqueueWriteBuffer(command_queue, arg2_Y, CL_TRUE, 0, sizeof(int), &val2, 0, nullptr, nullptr);
    
        /* OpenCLカーネル引数の設定 */
        ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&arg1_X);
        ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&arg2_Y);
        ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&arg3_R);
    
        /* OpenCL カーネルを実行 */
        ret = clEnqueueTask(command_queue, kernel, 0, NULL, NULL);
    
        /* メモリバッファから結果を取得 */
        int ret_val;
        ret = clEnqueueReadBuffer(command_queue, arg3_R, CL_TRUE, 0, sizeof(int), &ret_val, 0, NULL, NULL);
    
    
        /* 終了処理 */
        ret = clFlush(command_queue);
        ret = clFinish(command_queue);
        ret = clReleaseKernel(kernel);
        ret = clReleaseProgram(program);
    
        ret = clReleaseMemObject(arg1_X);
        ret = clReleaseMemObject(arg2_Y);
        ret = clReleaseMemObject(arg3_R);
    
        ret = clReleaseCommandQueue(command_queue);
        ret = clReleaseContext(context);
    
        free(source_str);
    
    
    
        /* 結果の表示 */
        std::cout << ret_val;
        int k;
        std::cin >> k;
    
    
        return 0;
    }