2017-07-01 4 views
0

MJPEGデコーダのシーケンシャルCコードをOpenCLに変換しようとしています。 this githubプロジェクトからCコードを入手しました。EclipseでCOULD NOT CREATE KERNELと言った後にコードが終了する

私は今、IDCTの元のCコードをOpenCLに変換しようとしています。

IDCTの.cファイルのコードをコピーして貼り付け、invCosine.clという名前の.clファイルに貼り付けました。

invCosine.cl

 #define IDCT_INT_MIN (- IDCT_INT_MAX - 1) 
     #define IDCT_INT_MAX 2147483647 

     /* 
     * Useful constants: 
     */ 

     /* 
     * ck = cos(k*pi/16) = s8-k = sin((8-k)*pi/16) times 1 << C_BITS and 
     * rounded 
     */ 
     #define c0_1 16384 
     #define c0_s2 23170 
     #define c1_1 16069 
     #define c1_s2 22725 

    .... 
    .... 
    .... 
    .... 
    .... 
    .... 

__kernel void idct1D(__global cl_int *Y) { 
    cl_int z1[8], z2[8], z3[8]; 

    /* 
    * Stage 1: 
    */ 

    but(Y[0], Y[4], z1[1], z1[0]); 
    rot(1, 6, Y[2], Y[6], &z1[2], &z1[3]); 
    but(Y[1], Y[7], z1[4], z1[7]); 
    z1[5] = CMUL(sqrt2, Y[3]); 
    z1[6] = CMUL(sqrt2, Y[5]); 

    /* 
    * Stage 2: 
    */ 
    but(z1[0], z1[3], z2[3], z2[0]); 
    but(z1[1], z1[2], z2[2], z2[1]); 
    but(z1[4], z1[6], z2[6], z2[4]); 
    but(z1[7], z1[5], z2[5], z2[7]); 

    /* 
    * Stage 3: 
    */ 
    z3[0] = z2[0]; 
    z3[1] = z2[1]; 
    z3[2] = z2[2]; 
    z3[3] = z2[3]; 
    rot(0, 3, z2[4], z2[7], &z3[4], &z3[7]); 
    rot(0, 1, z2[5], z2[6], &z3[5], &z3[6]); 

    /* 
    * Final stage 4: 
    */ 
    but(z3[0], z3[7], Y[7], Y[0]); 
    but(z3[1], z3[6], Y[6], Y[1]); 
    but(z3[2], z3[5], Y[5], Y[2]); 
    but(z3[3], z3[4], Y[4], Y[3]); 
} 

私は基本的にコピーされ、idct.cと呼ばれる元のファイルから#define文を貼り付けました。私は同じファイル.cからカーネルのコードをコピーして貼り付け、キーワード__kernel__globalcl_intをこのカーネルに追加しました。現時点では、私は最適化されたOpenCLコードを書いたくありません。 IDCTの計算をGPUにオフロードしたいだけです。

次のようにメインのファイルで私のホスト・コードは次のとおりです。

//////////////OpenCL parameters///////////////////////////// 

      int out; 
      cl_platform_id platform_id; 
      cl_uint ret_num_platforms; 
      cl_device_id device_id; 
      cl_uint ret_num_devices; 
      cl_context context; 
      cl_command_queue command_queue; 
      cl_program program; 
      //size_t kernel_code_size; 
      int *result; 
      cl_int ret; 
      cl_kernel kernel; 
      int storeResult; 


          FILE *fp; 
          const char fileName[] = "/root/Downloads/tima_seq_version/src/invCosine.cl"; 
          size_t source_size; 
          char *source_str; 

         /* Load kernel source file */ 
         fp = fopen(fileName, "rb"); 
         if (!fp) { 
          fprintf(stderr, "Failed to load kernel.\n"); 
          exit(1); 
         } 


         source_str = (char *)malloc(MAX_SOURCE_SIZE); 
        source_size = fread(source_str, 1, MAX_SOURCE_SIZE, fp); 
        fclose(fp); 

     /////////Set platform, context, command-queue...........///////////////////////// 

      /* Get Platform */ 
       ret= clGetPlatformIDs(1, &platform_id, &ret_num_platforms); 
       if (ret_num_platforms == 0) 
        { 
         printf("Found 0 platforms!\n"); 
        return EXIT_FAILURE; 
        } 
       /* Get Device */ 
       ret= clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &ret_num_devices); 
       printf("Number of devices: %d\n", ret_num_devices); 

       /* Create Context */ 
       context = clCreateContext(0, 1, &device_id, NULL, NULL, &ret); 

       if (!context) 
       { 
        printf("NO cCONTEXT\n"); 
        return EXIT_FAILURE; 

       } 

       /* Create Command Queue */ 
       command_queue = clCreateCommandQueue(context, device_id, 0, &ret); 

       if (!command_queue) 
       { 
        printf("NO command queue\n"); 
        return EXIT_FAILURE; 

       } 

       /* Create kernel from source */ 
          program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret); 

          if (!program) 
          { 
           printf("NO PROGRAM!!!!\n"); 
           return EXIT_FAILURE; 
          } 

          clBuildProgram(program, 1, &device_id, "", NULL, NULL); 

         if (ret != CL_SUCCESS) { 
           printf("building program failed\n"); 
           if (ret == CL_BUILD_PROGRAM_FAILURE) { 
            size_t log_size; 
            clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); 
            char *log = (char *) malloc(log_size); 
            clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, log_size, log, NULL); 
            printf("%s\n", log); 
           } 
          } 

       kernel= clCreateKernel(program, "idct1D", &ret); 

       if(!kernel || ret != CL_SUCCESS) 
       { 
        printf("-----COULD NOT CREATE KERNEL!!---\n"); 
        exit(1); 
       } 

私はアプリケーションを実行すると、私は次の出力を得る:カーネルがない理由を理解するために

Number of devices: 2 
-----COULD NOT CREATE KERNEL!!--- 

を私のすべてのidctコードを削除し、カーネルコードをコピーしてthisのリンクから私の.clファイルに貼り付けました:

もう一度アプリケーションを実行すると、スムーズに実行され、同じエラーは発生しませんでした。

Idctカーネルが検出されないのはなぜですか?

P. Eclipse IDEを使用して、コードを作成して実行しています。

+2

あなたは 'clBuildProgram'の戻り値をテストしていません。私はそれが失敗している可能性があり、 'clGetProgramBuildInfo'で取得した結果のエラーメッセージが問題を明らかにする可能性があります。 – doynax

答えて

1

カーネルエラーを表示する理由は、実際にはエラーコードclBuildProgramをチェックしていないためです。代わりにret = clBuildProgram(program, 1, &device_id, "", NULL, NULL);を実行すると、clBuildProgram呼び出しでエラーが発生します。

このエラーが発生する理由は、OpenCL C言語にはcl_intデータ型がないためです。つまり、カーネル内で使用することはできません。 cl_ *タイプは、ホスト側の使用のためのものです。あなたのような.clファイルの中に、あなたが提供されたコードではなくintを使用するようにカーネルを変更butrotマクロに必要なすべての定義を、持っていると仮定するなど

のchar int型、float型、などの定期的な型を使用する必要がありますcl_intの問題を解決する必要があります。

関連する問題