我正在尝试实施一种算法来处理超过256个垃圾箱的图像。
在这种情况下处理直方图的主要问题来自于不可能在GPU中分配超过32 Kb作为本地选项卡。
我找到的每像素8位图像的所有算法都在本地使用固定大小的标签。 直方图是该选项卡中的第一个进程,然后屏障上升,最后使用输出向量进行添加。
我正在处理具有超过32K动态箱的红外图像。 所以我无法在GPU内部分配固定大小的标签。
我的算法使用java -classpath target/classes/:target/test-classes/ Main
来直接创建输出直方图。
我正在与OpenCV连接,所以,为了管理可能的饱和情况,我的箱子使用浮点。取决于GPU管理单精度或双精度的能力。
OpenCV不会将atomic_add
,unsigned int
和long
数据类型作为矩阵类型进行管理。
我有错误...我认为这个错误是一种分段错误。 几天后,我仍然不知道会出现什么问题。
这是我的代码:
histogram.cl:
unsigned long
Atomic_Add_f64函数直接来自here和there
的main.cpp
#pragma OPENCL EXTENSION cl_khr_fp64: enable
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics: enable
static void Atomic_Add_f64(__global double *val, double delta)
{
union {
double f;
ulong i;
} old;
union {
double f;
ulong i;
} new;
do {
old.f = *val;
new.f = old.f + delta;
}
while (atom_cmpxchg ( (volatile __global ulong *)val, old.i, new.i) != old.i);
}
static void Atomic_Add_f32(__global float *val, double delta)
{
union
{
float f;
uint i;
} old;
union
{
float f;
uint i;
} new;
do
{
old.f = *val;
new.f = old.f + delta;
}
while (atom_cmpxchg ( (volatile __global ulong *)val, old.i, new.i) != old.i);
}
__kernel void khist(
__global const uchar* _src,
const int src_steps,
const int src_offset,
const int rows,
const int cols,
__global uchar* _dst,
const int dst_steps,
const int dst_offset)
{
const int gid = get_global_id(0);
// printf("This message has been printed from the OpenCL kernel %d \n",gid);
if(gid < rows)
{
__global const _Sty* src = (__global const _Sty*)_src;
__global _Dty* dst = (__global _Dty*) _dst;
const int src_step1 = src_steps/sizeof(_Sty);
const int dst_step1 = dst_steps/sizeof(_Dty);
src += mad24(gid,src_step1,src_offset);
dst += mad24(gid,dst_step1,dst_offset);
_Dty one = (_Dty)1;
for(int c=0;c<cols;c++)
{
const _Rty idx = (_Rty)(*(src+c+src_offset));
ATOMIC_FUN(dst+idx+dst_offset,one);
}
}
}
答案 0 :(得分:0)
你好我到了修理它。 我真的不知道问题的来源。 但是,如果我认为输出是一个指针而不是一个矩阵,那就可以了。
我所做的改变是:
histogram.cl:
__kernel void khist(
__global const uchar* _src,
const int src_steps,
const int src_offset,
const int rows,
const int cols,
__global _Dty* _dst)
{
const int gid = get_global_id(0);
if(gid < rows)
{
__global const _Sty* src = (__global const _Sty*)_src;
__global _Dty* dst = _dst;
const int src_step1 = src_steps/sizeof(_Sty);
src += mad24(gid,src_step1,src_offset);
ulong one = 1;
for(int c=0;c<cols;c++)
{
const _Rty idx = (_Rty)(*(src+c+src_offset));
ATOMIC_FUN(dst+idx,one);
}
}
}
的main.cpp
k.args(cv::ocl::KernelArg::ReadOnly(src),cv::ocl::KernelArg::PtrWriteOnly(dst));
其余代码在两个文件中是相同的。 对我而言,它运作良好。
如果有人知道为什么当输出被声明为指针而不是向量(一行矩阵)时它会起作用我感兴趣。
然而我的问题是修复:)。