pyopencl icon indicating copy to clipboard operation
pyopencl copied to clipboard

Broadcasting of Arrays and non-scalar but unit-sized numpy arrays

Open zachjweiner opened this issue 3 years ago • 1 comments

After 78bedd865, binary operations between a unit-sized numpy array and a PyOpenCL array ends up looping over each element of the CL array.

import pyopencl as cl
import pyopencl.array
import numpy as np
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)

ary = cl.array.to_device(queue, np.random.rand(10))
np_ary = np.random.rand(1)
ary + np_ary

Namely, pyopencl.Array.__add__ returns NotImplemented in this case and so python then asks the numpy array what to do. It appears numpy chooses to loop over each scalar element of the CL array and call its __add__ method, and for some reason converts the unit-sized array into a scalar (which is why the single-element additions don't fail).

Could the np.isscalar(other) check be replaced (or augmented with) other.size == 1, perhaps?

Also, a few binary ops were missed in 78bedd865, like __iadd__ and comparisons - was this intentional?

cc @kaushikcfd

zachjweiner avatar Jul 28 '21 20:07 zachjweiner

Could the np.isscalar(other) check be replaced (or augmented with) other.size == 1, perhaps?

Replacing or augmenting with other.size == 1 might not be the correct behavior as the resulting array's shape might not follow numpy's broadcasting semantics. (I'm also unsure what's the correct behavior here)

Also, a few binary ops were missed in 78bedd8, like iadd and comparisons - was this intentional?

Oops, that's a bug.

kaushikcfd avatar Jul 28 '21 21:07 kaushikcfd