| 26 | |
| 27 | |
| 28 | class Blockwise(ArrayExpr): |
| 29 | _parameters = [ |
| 30 | "func", |
| 31 | "out_ind", |
| 32 | "name", |
| 33 | "token", |
| 34 | "dtype", |
| 35 | "adjust_chunks", |
| 36 | "new_axes", |
| 37 | "align_arrays", |
| 38 | "concatenate", |
| 39 | "_meta_provided", |
| 40 | "kwargs", |
| 41 | ] |
| 42 | _defaults = { |
| 43 | "name": None, |
| 44 | "token": None, |
| 45 | "dtype": None, |
| 46 | "adjust_chunks": None, |
| 47 | "new_axes": None, |
| 48 | "align_arrays": True, |
| 49 | "concatenate": None, |
| 50 | "_meta_provided": None, |
| 51 | "kwargs": None, |
| 52 | } |
| 53 | |
| 54 | @cached_property |
| 55 | def args(self): |
| 56 | return self.operands[len(self._parameters) :] |
| 57 | |
| 58 | @cached_property |
| 59 | def _meta_provided(self): |
| 60 | # We catch recursion errors if key starts with _meta, so define |
| 61 | # explicitly here |
| 62 | return self.operand("_meta_provided") |
| 63 | |
| 64 | @cached_property |
| 65 | def _meta(self): |
| 66 | if self._meta_provided is not None: |
| 67 | return meta_from_array( |
| 68 | self._meta_provided, ndim=self.ndim, dtype=self._meta_provided.dtype |
| 69 | ) |
| 70 | else: |
| 71 | return compute_meta( |
| 72 | self.func, self.operand("dtype"), *self.args[::2], **self.kwargs |
| 73 | ) |
| 74 | |
| 75 | @cached_property |
| 76 | def chunks(self): |
| 77 | if self.align_arrays: |
| 78 | chunkss, arrays, _ = unify_chunks_expr(*self.args) |
| 79 | else: |
| 80 | arginds = [ |
| 81 | (a, i) for (a, i) in toolz.partition(2, self.args) if i is not None |
| 82 | ] |
| 83 | chunkss = {} |
| 84 | # For each dimension, use the input chunking that has the most blocks; |
| 85 | # this will ensure that broadcasting works as expected, and in |
no outgoing calls
searching dependent graphs…