Search code examples
pythonimagenumpyopenclpyopencl

opencl - padding produces different output


I am trying to pad an array of shape (28*28) with zeroes. This array is the result of converting an image into array using PIL library. I wrote a kernel using OpenCL. The program works fine for a random numpy array but doesn't work well with the array converted from image. However, the image is converted into array properly,i.e, it outputs the desired pixel values. I have come across a similar situation a before where the problem was with the datatype inside the kernel (I had to change float to 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

when i run this piece of code:

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

i get the correct result:

[[ 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.        ]]

but, while running this:

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

data = array(image)

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

i get this:

  [[  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]]

What went wrong? Is something wrong with datatypes?


Solution

  • As I had mentioned earlier, the datatypes didn't match. So, the input array had to be converted into dtype of double. code:

    image = Image.open('1.jpg')
    
    data = array(image,dtype="double")
    
    print pad(data,data.shape[0])