分割错误:11个带有Pyopencl中的图像

时间:2019-06-05 00:50:29

标签: python c opencl pyopencl

我正在尝试在OpenCL中应用过滤器。但是,似乎存在一些向/从设备复制图像以及执行我不了解的图像内核计算的方面。结果,我得到了无法跟踪的C Segmentation fault: 11 error

内核和convolve_image充分说明了我得到的错误,但如果有人想重现该错误,我会提供所有代码。

下面是我的内核

 __kernel void Convolve(__read_only image2d_t imgSrc,
                                __constant float * kernelValues,
                                int kernelSize,
                                __write_only image2d_t imgConvolved)
    {
        const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | //Natural coordinates
                              CLK_ADDRESS_CLAMP | //Clamp to zeros
                              CLK_FILTER_NEAREST; //Don't interpolate
     int column = get_global_id(0);
     int row = get_global_id(1);

     int halfWidth = (int)(kernelSize/2);

     float4 sum = {0.0f,0.0f,0.0f,0.0f};
     int kernelIndex = 0;
     int2 coords;

     for(int i = -halfWidth; i<= halfWidth; i++)
     {
      printf("here");

        coords.y = row + i;
        for(int j = -halfWidth; j <= halfWidth; j++)
        {
            coords.x =column+j;
            float4 pixel;
            pixel = read_imagef(imgSrc,smp,coords);

            sum.x += pixel * kernelValues[kernelIndex++];
        }
     }
     coords.x = column;
     coords.y= row;
     write_imagef(imgConvolved,coords,sum);
    }

这是我加载图像的方式-convolve_image

def convolve_image(imgIn,convolution_kernel,kernel_size):
    "apply morphological operation to image using GPU"
    # (1) setup OpenCL
    platforms = cl.get_platforms() # a platform corresponds to a driver (e.g. AMD)
    platform = platforms[0] # take first platform
    devices = platform.get_devices(cl.device_type.GPU) # get GPU devices of selected platform
    device = devices[0] # take first GPU
    context = cl.Context([device]) # put selected GPU into context object
    queue = cl.CommandQueue(context, device) # create command queue for selected GPU and context

    # (2) get shape of input image, allocate memory for output to which result can be copied to
    shape = imgIn.shape
    imgOut = numpy.empty_like(imgIn)   
    print(shape)

    h_kernel = convolution_kernel


    # Send the data to the guest memory.
    d_kernel = cl.Buffer(context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=h_kernel)
    #print(h_image_output)
    # (2) create image buffers which hold images for OpenCL
    imgInBuf = cl.Image(context, cl.mem_flags.READ_ONLY, cl.ImageFormat(cl.channel_order.RGB, cl.channel_type.FLOAT), shape=shape) # holds a gray-valued image of given shape
    imgOutBuf = cl.Image(context, cl.mem_flags.WRITE_ONLY, cl.ImageFormat(cl.channel_order.RGB, cl.channel_type.FLOAT), shape=shape) # placeholder for gray-valued image of given shape
    kernel_width = cl.Buffer(context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=numpy.int32(kernel_size))

    # (3) load and compile OpenCL program
    program = cl.Program(context, open('kernel.cl').read()).build()

    # (3) from OpenCL program, get kernel object and set arguments (input image, operation type, output image)
    kernel = cl.Kernel(program, 'Convolve') # name of function according to kernel.py
    kernel.set_arg(0, imgInBuf) # input image buffer
    kernel.set_arg(1, d_kernel)
    kernel.set_arg(2, kernel_width) 
    kernel.set_arg(3, imgOutBuf) # output image buffer

    # (4) copy image to device, execute kernel, copy data back
    cl.enqueue_copy(queue, imgInBuf, imgIn, origin=(0, 0), region=shape, is_blocking=False) # copy image from CPU to GPU
    print("here")
    cl.enqueue_nd_range_kernel(queue, kernel, shape, None) # execute kernel, work is distributed across shape[0]*shape[1] work-items (one work-item per pixel of the image)
    cl.enqueue_copy(queue, imgOut, imgOutBuf, origin=(0, 0), region=shape, is_blocking=True) # wait until finished copying resulting image back from GPU to CPU

    return imgOut

以下是辅助功能:

def normalize_kernel(kernel, dim):
    """Normalizes a kernel
    Args:
        kernel: a two-d kernel
    """
    for x in range(0, dim):
        for y in range(dim):
            kernel[x][y] = kernel[x][y] / numpy.sum(kernel)
    return kernel


def gaussian_kernel(dim, sigma):
    """
    The Guassian blur function is as follows:

                           x² + y²
    G(x,y) =    1        - -------
            --------- * e    2σ²
              2πσ²
    Finally the kernel is normalized to avoid too dark or too light areas.
    """
    rows = dim
    cols = dim
    arr = numpy.empty([rows, cols]).astype(numpy.float32)
    center = dim / 2
    total = 0.0
    for x in range(0, rows):
        for y in range(0, cols):
            x_ = x - center
            y_ = y - center
            arr[x][y] = (1 / (2.0 * math.pi * math.pow(sigma, 2))) * math.pow(math.e, -1.0 * (
                (math.pow(x_, 2) + math.pow(y_, 2)) / (2.0 * math.pow(sigma, 2))))
            total = total + arr[x][y]

    return normalize_kernel(arr, dim)

最后是主要内容:

def main( ):
    path =sys.argv[1]
    print(path)
    img = cv2.imread(path)
    print(type(img))


    # Kernel parameters
    kernel_dim = 5
    kernel_sig = 1
    convolution_kernel = gaussian_kernel(kernel_dim, kernel_sig)  # gaussian_kernel(kernel_dim, kernel_sig)

    print ("The kernel:\n", convolution_kernel)


    # dilate
    convolved = convolve_image(img,convolution_kernel,kernel_dim)
    cv2.imwrite('convolved.png', convolved)



if __name__ == '__main__':
    main()

0 个答案:

没有答案
相关问题