Why is this numba.jit function to add 1 to each element of a 2d array several times creating a noisy output?

Viewed 53
@cuda.jit
def increment_a_2D_array(an_array, output):
    cx = cuda.grid(1)

    lims = (50,50,50)
    a = cx
    x = a // (lims[1] * lims[2])
    a = a % (lims[1] * lims[2])
    y = a // (lims[2])
    a = a % lims[2]
    z = a // 1

    if -1 < x < lims[0] and -1 < y < lims[1] and -1 < z < lims[2]:
        if math.isnan(output[x,y]):
            output[x,y] = 1
        else:
            output[x,y] += 1 #an_array[x, y]

z = np.random.uniform(size=(50,50)) * 0
s = 50

for i in range(50):
    outputempty = np.ones(shape=((s*2)-1, s)) * math.nan

    an_array = cuda.to_device(z)
    output = cuda.to_device(outputempty)

    threadsperblock = (4)
    blockspergrid_x = math.ceil((50*50*50) / threadsperblock)
    blockspergrid = (blockspergrid_x)
    increment_a_2D_array[blockspergrid, threadsperblock](an_array, output)

    outputonhost = output.copy_to_host()

    z = outputonhost

    plt.imshow(outputonhost)
    plt.show()

The above code, as the title suggests, is meant to iterate through a 2d array adding 1 to each element 50 times, effectively iterating through 3 dimensions - the x and y of the image and then a third dimension z for the 50 times each pixel needs 1 adding to it. This is a simplification of other code I've written, as this is the root of the issue. I cannot understand why the output looks noisy, that is rather than every pixel being 50, they're relatively random and all around 1, as shown here:

as shown here.

I have attempted to use cuda.grid(3) as well, and pass in 3 dimensional threadsperblock and blockspergrid, but that has the same issue.

0 Answers
Related