| 260 | |
| 261 | |
| 262 | class PartialReduce(ArrayExpr): |
| 263 | _parameters = [ |
| 264 | "array", |
| 265 | "func", |
| 266 | "split_every", |
| 267 | "keepdims", |
| 268 | "dtype", |
| 269 | "name", |
| 270 | "reduced_meta", |
| 271 | ] |
| 272 | _defaults = { |
| 273 | "keepdims": False, |
| 274 | "dtype": None, |
| 275 | "name": None, |
| 276 | "reduced_meta": None, |
| 277 | } |
| 278 | |
| 279 | def __dask_tokenize__(self): |
| 280 | if not self._determ_token: |
| 281 | # TODO: Is there an actual need to overwrite this? |
| 282 | self._determ_token = _tokenize_deterministic( |
| 283 | self.func, self.array, self.split_every, self.keepdims, self.dtype |
| 284 | ) |
| 285 | return self._determ_token |
| 286 | |
| 287 | @cached_property |
| 288 | def _name(self): |
| 289 | return ( |
| 290 | (self.operand("name") or funcname(self.func)) |
| 291 | + "-" |
| 292 | + self.deterministic_token |
| 293 | ) |
| 294 | |
| 295 | @cached_property |
| 296 | def chunks(self): |
| 297 | chunks = [ |
| 298 | ( |
| 299 | tuple(1 for p in partition_all(self.split_every[i], c)) |
| 300 | if i in self.split_every |
| 301 | else c |
| 302 | ) |
| 303 | for (i, c) in enumerate(self.array.chunks) |
| 304 | ] |
| 305 | |
| 306 | if not self.keepdims: |
| 307 | out_axis = [i for i in range(self.array.ndim) if i not in self.split_every] |
| 308 | getter = lambda k: get(out_axis, k) |
| 309 | chunks = list(getter(chunks)) |
| 310 | return tuple(chunks) |
| 311 | |
| 312 | def _layer(self): |
| 313 | x = self.array |
| 314 | parts = [ |
| 315 | list(partition_all(self.split_every.get(i, 1), range(n))) |
| 316 | for (i, n) in enumerate(x.numblocks) |
| 317 | ] |
| 318 | keys = product(*map(range, map(len, parts))) |
| 319 | if not self.keepdims: |
no outgoing calls
no test coverage detected
searching dependent graphs…