| 212 | |
| 213 | |
| 214 | class Elemwise(Blockwise): |
| 215 | _parameters = ["op", "dtype", "name", "where"] |
| 216 | _defaults = { |
| 217 | "dtype": None, |
| 218 | "name": None, |
| 219 | "where": True, |
| 220 | } |
| 221 | align_arrays = True |
| 222 | new_axes: dict = {} |
| 223 | adjust_chunks = None |
| 224 | concatenate = None |
| 225 | |
| 226 | @cached_property |
| 227 | def _meta(self): |
| 228 | return compute_meta( |
| 229 | self._info[0], self.dtype, *self.elemwise_args, **self.kwargs |
| 230 | ) |
| 231 | |
| 232 | @property |
| 233 | def elemwise_args(self): |
| 234 | return self.operands[len(self._parameters) :] |
| 235 | |
| 236 | @property |
| 237 | def out_ind(self): |
| 238 | shapes = [] |
| 239 | for arg in self.elemwise_args: |
| 240 | shape = getattr(arg, "shape", ()) |
| 241 | if any(is_dask_collection(x) for x in shape): |
| 242 | # Want to exclude Delayed shapes and dd.Scalar |
| 243 | shape = () |
| 244 | shapes.append(shape) |
| 245 | if isinstance(self.where, ArrayExpr): |
| 246 | shapes.append(self.where.shape) |
| 247 | |
| 248 | shapes = [s if isinstance(s, Iterable) else () for s in shapes] |
| 249 | out_ndim = len( |
| 250 | broadcast_shapes(*shapes) |
| 251 | ) # Raises ValueError if dimensions mismatch |
| 252 | return tuple(range(out_ndim))[::-1] |
| 253 | |
| 254 | @cached_property |
| 255 | def _info(self): |
| 256 | if self.operand("dtype") is not None: |
| 257 | need_enforce_dtype = True |
| 258 | dtype = self.operand("dtype") |
| 259 | else: |
| 260 | # We follow NumPy's rules for dtype promotion, which special cases |
| 261 | # scalars and 0d ndarrays (which it considers equivalent) by using |
| 262 | # their values to compute the result dtype: |
| 263 | # https://github.com/numpy/numpy/issues/6240 |
| 264 | # We don't inspect the values of 0d dask arrays, because these could |
| 265 | # hold potentially very expensive calculations. Instead, we treat |
| 266 | # them just like other arrays, and if necessary cast the result of op |
| 267 | # to match. |
| 268 | vals = [ |
| 269 | ( |
| 270 | np.empty((1,) * max(1, a.ndim), dtype=a.dtype) |
| 271 | if not is_scalar_for_elemwise(a) |
no outgoing calls
no test coverage detected
searching dependent graphs…