【问题标题】:Why the same opencl code cannot be run on IMX.6?为什么相同的 opencl 代码不能在 IMX.6 上运行?
【发布时间】:2014-03-19 08:59:03
【问题描述】:

我们正在尝试使用 OpenCL 在 IMX.6 上进行一些图像处理。

我们使用了已经测试过的 opencl 代码。在 kernel.cl 文件中,唯一的 opencl 就是

int i= get_global_id(0);
int j= get_global_id(1);

其他所有作品都是基于pure-c语言而不是opencl。

并且代码在 PC 上运行良好。

但是,当我们在 IMX.6 上测试代码时。所有状态都显示正确,但我们无法得到正确的结果。

读写缓冲函数clEnqueueReadBuffer完全没有问题,我们测试了上传的图片。但是内核运行函数没有任何结果。 clEnqueueNDRangeKernel。

有人知道为什么吗? 对了,这道题是opencl的2000题:)

这是整个代码:

  __kernel void IPM(__global const unsigned char* image_ROI_data, __global unsigned char* IPM_data, __global float* parameter_IPM)
{
float camera_col=parameter_IPM[1];
float camera_row=parameter_IPM[0];

float camera_height=parameter_IPM[2];
float camera_alpha=parameter_IPM[3];
float camera_theta=parameter_IPM[4];

float image_vp=parameter_IPM[5];

float IPM_width=parameter_IPM[6];
float IPM_height=parameter_IPM[7];

int IPM_lineByte=(((int)IPM_width+3)/4)*4;
int image_lineByte=(((int)camera_col+3)/4)*4;

int i= get_global_id(0);
int j= get_global_id(1);

*(IPM_data+((int)IPM_height-j)*IPM_lineByte+i)=0;

float multiple=(float)(IPM_width/20);

// Real x and Real y(they are both meters)
float x=(float)(i-IPM_width/2)/multiple;
float y=(float)(j)/multiple;

// The coordinator in capture image.
float u=(camera_row-1)*(atan(camera_height/sqrt(x*x+y*y))+camera_alpha-camera_theta)/(2*camera_alpha);
float v=(camera_col-1)*(atan(x/y)+camera_alpha)/(2*camera_alpha);

// If the point was in capture image, choose its pixel and fill the image.
// As it is only a ROI so it is u-image_vp
if (((int)u-(int)image_vp)>0 && (int)u<(int)camera_row && v>0 && v<camera_col)
{
    *(IPM_data+((int)IPM_height-j)*IPM_lineByte+i)=
        *(image_ROI_data+((int)u-(int)image_vp)* image_lineByte+(int)v);
}

}

【问题讨论】:

  • 如果您的目标平台与 OpenCL 完整配置文件兼容,请运行最简单的向量加法内核以确保一切正常。如果可以的话,附上你的一些代码来看看,你的问题目前很笼统
  • 在嵌入式配置文件上运行?他们说这个配置文件中的大部分功能都被减少了。它也符合 opencl 1.1。您的 PC 可能具有 opencl 1.2 功能和更高的值。
  • @RomanArzumanyan Arzumanyan 感谢您的回答。我已经在两个平台上测试了简单的向量添加代码。没有问题。但是,只是这段代码有一些问题。
  • @huseyintugrulbuyukisik 您好,感谢您的回答。我上传了整个内核代码,你可以看到,它们都在cl1.0...
  • 我能看到的代码中唯一的“怀疑”是显式类型转换。您可以尝试使用转换类函数

标签: image-processing buffer opencl embedded-linux


【解决方案1】:
 int i= get_global_id(0); // starts from zero
 int j= get_global_id(1); // this too

 float x=(float)(i-IPM_width/2)  // maybe zero maybe not
 float y=(float)(j)/multiple;    // becomes zero

 float v=(camera_col-1)*(atan(x/y)+camera_alpha)/(2*camera_alpha);
                                ^
                                |
                                |
                               / \
                           division by zero
                 Becomes NaN or INF, and the rest follow.
             Then you get a wrong result originating from this.

  Especially when you use it for pointer calculus:

  *(IPM_data+((int)IPM_height-j)*IPM_lineByte+i)=
    *(image_ROI_data+((int)u-(int)image_vp)* image_lineByte+(int)v);
                                                                 ^
                                                                 |
                                                                 |
                                                                /-\
                                                    gg if "if" body is entered

【讨论】:

    【解决方案2】:

    您的设备仅支持嵌入式 OpenCL 配置文件,它是您的 PC 支持的完整配置文件的子集。通常,您需要重构代码以使其与嵌入式配置文件兼容。

    【讨论】:

    • 您好,感谢您的回答。
    • 我上传了整个代码。如您所见,嵌入式配置文件之外没有任何功能或其他东西......
    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    相关资源
    最近更新 更多