opencl - padding产生不同的输出

时间:2017-11-06 17:02:41

标签: python image numpy opencl pyopencl

我试图用零填充一个形状(28 * 28)的数组。此数组是使用PIL库将图像转换为数组的结果。我使用OpenCL编写了一个内核。该程序适用于随机numpy数组,但不适用于从图像转换的数组。但是,图像被正确地转换成阵列,即它输出所需的像素值。 我遇到过类似的问题,之前问题出在内核中的数据类型(我不得不将float更改为double)。

import numpy
from PIL import Image
from numpy import array
import pyopencl as cl 

def pad(x, order):
    kernelsource = """
    __kernel void pad(
    __global double* A,
    __global double* B,
    const unsigned int M)
    {
        int i = get_global_id(0);
        int j = get_global_id(1);

        if((i<M) && (j<M))
        {

            if((j == 0) || (j == M-1) || (i == 0) || (i == M-1))
            {
                B[i*M + j] = 0;
            }else{
                B[i*M + j] = A[(i-1)*(M-2) + j-1];
            }           
        }
    }
    """
    context = cl.create_some_context()
    queue = cl.CommandQueue(context)
    program = cl.Program(context, kernelsource).build()

    out_order = order + 2

    h_a = x
    d_a = cl.Buffer(context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=h_a)

    h_b = numpy.empty((out_order,out_order))
    d_b = cl.Buffer(context, cl.mem_flags.WRITE_ONLY, h_b.nbytes)

    pad = program.pad
    pad.set_scalar_arg_dtypes([None, None, numpy.uint32])

    pad(queue, h_b.shape, None, d_a, d_b, out_order)
    queue.finish()
    cl.enqueue_copy(queue, h_b, d_b)

    return h_b

当我运行这段代码时:

arr = numpy.random.rand(3,3)
print pad(arr,3)

我得到了正确的结果:

[[ 0.          0.          0.          0.          0.        ]
[ 0.          0.75495661  0.58017939  0.61390089  0.        ]
[ 0.          0.33017635  0.98233609  0.77542593  0.        ]
[ 0.          0.94607981  0.6020772   0.14673336  0.        ]
[ 0.          0.          0.          0.          0.        ]]

但是,在运行时:

image = Image.open('1.jpg')

data = array(image)

print pad(data,data.shape[0])

我明白了:

  [[  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000]
[  0.00000000e+000  -4.73788662e+226  -5.14319684e+303  -1.27732501e+294
 -1.27733779e+294  -1.27701620e+294  -8.36396791e+298               nan
 -1.96381395e+289  -1.68533731e+308               nan   3.62029008e-217
              nan  -1.79768197e+308               nan   5.97554844e-311
 -7.58630869e+298   2.78134240e-309   2.17953307e-289               nan
  7.74667808e-304               nan   3.19854370e-308               nan
  5.77663315e-275   7.29111854e-304   8.34430283e-309   1.09916879e-311
 -7.22416349e+221   0.00000000e+000]

...
...
[  0.00000000e+000   5.43230923e-311   7.38794055e-310   5.43230922e-312
  6.51877107e-311   8.47440239e-310   5.43230922e-312   1.08646185e-310
  9.56086424e-310   5.43230922e-312   1.19510803e-310   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
  6.36598737e-314   1.58101007e-322   0.00000000e+000   3.16202013e-322
  2.47032823e-322   0.00000000e+000   4.94065646e-324   0.00000000e+000
  6.36598738e-314   0.00000000e+000]
[  0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000   0.00000000e+000   0.00000000e+000
    0.00000000e+000   0.00000000e+000]]

出了什么问题?数据类型有问题吗?

1 个答案:

答案 0 :(得分:1)

正如我之前提到的,数据类型不匹配。因此,输入数组必须转换为double的dtype。 代码:

image = Image.open('1.jpg')

data = array(image,dtype="double")

print pad(data,data.shape[0])