CUDA Historogram2d不工作

2024-09-27 09:28:55 发布

您现在位置:Python中文网/ 问答频道 /正文

由于似乎缺乏一个像样的二维直方图为CUDA(我可以找到。。。指针(欢迎),我正在尝试用pyCUDA实现它。你知道吗

下面是直方图的样子(使用Numpy):

Numpy Histogram

到目前为止我得到的是:

code = '''
__global__ void histogram2d(const float *in_x, const float *in_y, const float *in_w, float *out) {{
    int start = blockIdx.x * blockDim.x + threadIdx.x;

    float *block_out = &out[{xres} * {yres} * {num_chans} * blockIdx.x];

    for(int i = 0; i < {length}; i++) {{
        float x = in_x[start + i];
        float y = in_y[start + i];
        int w_idx = (start + i) * {num_chans};

        int xbin = (int) (((x - {xmin}) / {xptp}) * {xres});
        int ybin = (int) (((y - {ymin}) / {yptp}) * {yres});

        if (0 <= xbin && xbin < {xres} && 0 <= ybin && ybin < {yres}) {{
            for(int c = 0; c < {num_chans}; c++) {{
                atomicAdd(&block_out[(ybin * {xres} + xbin) * {num_chans} + c], in_w[w_idx + c]);
            }}
        }}
    }}
}}
'''.format(**args)

------

__global__ void histogram2d(const float *in_x, const float *in_y, const float *in_w, float *out) {
    int start = blockIdx.x * blockDim.x + threadIdx.x;

    float *block_out = &out[50 * 50 * 4 * blockIdx.x];

    for(int i = 0; i < 100; i++) {
        float x = in_x[start + i];
        float y = in_y[start + i];
        int w_idx = (start + i) * 4;

        int xbin = (int) (((x - -10.0) / 20.0) * 50);
        int ybin = (int) (((y - -10.0) / 20.0) * 50);

        if (0 <= xbin && xbin < 50 && 0 <= ybin && ybin < 50) {
            for(int c = 0; c < 4; c++) {
                atomicAdd(&block_out[(ybin * 50 + xbin) * 4 + c], in_w[w_idx + c]);
            }
        }
    }
}

CUDA histogram

索引似乎有问题,但我以前没有做过太多纯CUDA,所以我不知道它是什么。下面是我认为与python等价的东西:

def slow_hist(in_x, in_y, in_w, out, blockx, blockdimx, threadx):
    start = blockx * blockdimx + threadx

    block_out_addr = args['xres'] * args['yres'], args['num_chans'] * blockx

    for i in range(args['length']):
        x = in_x[start + i]
        y = in_y[start + i]
        w_idx = (start + i) * args['num_chans']

        xbin = int(((x - args['xmin']) / args['xptp']) * args['xres'])
        ybin = int(((y - args['ymin']) / args['yptp']) * args['yres'])

        if 0 <= xbin < args['xres'] and 0 <= ybin < args['yres']:
            for c in range(args['num_chans']):
                out[(ybin * args['xres'] + xbin) * args['num_chans'] + c] += in_w[w_idx + c]

Pure-python histogram

所有的代码都是可见的,包括这些图像at the Github page of this notebook(这个单元格在底部)。你知道吗

我在这个CUDA代码里做错了什么?我尝试过很多小的调整(将atomicAdd地址跨1、4、8、16、转置输出等),但似乎我遗漏了一些微妙的东西,可能是指针算法的工作方式。任何帮助都将不胜感激。你知道吗


Tags: inforargsfloatoutstartnumint
1条回答
网友
1楼 · 发布于 2024-09-27 09:28:55

为CUDA部分的输出数组分配的数组使用了Numpy的默认float64而不是float32,因此内存是预期的两倍。以下是新的直方图输出:

New CUDA histogram

我仍然非常感谢有助于解释为什么这些直方图彼此如此不同的评论或答案。你知道吗

相关问题 更多 >

    热门问题