|
338 | 338 | "in parallel to each block. This ability can be activated using\n", |
339 | 339 | "`dask=\"parallelized\"`. \n", |
340 | 340 | "\n", |
341 | | - "We will use `scipy.integrate.trapz` as an example of a function that cannot\n", |
342 | | - "handle dask arrays and requires a core dimension. If we call `trapz` with a dask\n", |
| 341 | + "We will use `scipy.integrate.trapezoid` as an example of a function that cannot\n", |
| 342 | + "handle dask arrays and requires a core dimension. If we call `trapezoid` with a dask\n", |
343 | 343 | "array, we get a numpy array back that is, the values have been eagerly computed.\n", |
344 | 344 | "This is undesirable behaviour\n" |
345 | 345 | ] |
|
354 | 354 | "import scipy as sp\n", |
355 | 355 | "import scipy.integrate\n", |
356 | 356 | "\n", |
357 | | - "sp.integrate.trapz(\n", |
| 357 | + "sp.integrate.trapezoid(\n", |
358 | 358 | " ds.air.data, axis=ds.air.get_axis_num(\"lon\")\n", |
359 | 359 | ") # does NOT return a dask array, you should see activity on the dashboard" |
360 | 360 | ] |
|
377 | 377 | "outputs": [], |
378 | 378 | "source": [ |
379 | 379 | "integrated = xr.apply_ufunc(\n", |
380 | | - " sp.integrate.trapz,\n", |
| 380 | + " sp.integrate.trapezoid,\n", |
381 | 381 | " ds,\n", |
382 | 382 | " input_core_dims=[[\"lon\"]],\n", |
383 | 383 | " kwargs={\"axis\": -1},\n", |
|
479 | 479 | "tags": [] |
480 | 480 | }, |
481 | 481 | "source": [ |
482 | | - "The core dimension for `trapz` is `lon`, and there is only one chunk along `lon`. This means that integrating along `lon` is a \"blockwise\" or \"embarrassingly parallel\" operation and `dask=\"parallelized\"` works quite well. \n", |
| 482 | + "The core dimension for `trapezoid` is `lon`, and there is only one chunk along `lon`. This means that integrating along `lon` is a \"blockwise\" or \"embarrassingly parallel\" operation and `dask=\"parallelized\"` works quite well. \n", |
483 | 483 | "\n", |
484 | 484 | "```{caution} Question\n", |
485 | 485 | "Do you understand why `integrate(ds)` when `ds` has a single chunk along `lon` is a \"embarrassingly parallel\" operation?\n", |
|
535 | 535 | "source": [ |
536 | 536 | "def integrate_wrapper(array, **kwargs):\n", |
537 | 537 | " print(f\"received array of type {type(array)}, shape {array.shape}\")\n", |
538 | | - " result = sp.integrate.trapz(array, **kwargs)\n", |
| 538 | + " result = sp.integrate.trapezoid(array, **kwargs)\n", |
539 | 539 | " print(f\"received array of type {type(result)}, shape {result.shape}\")\n", |
540 | 540 | " return result\n", |
541 | 541 | "\n", |
|
611 | 611 | "\n", |
612 | 612 | "Conceptually, there is a two-way flow of information between various packages when executing `integrated.compute()`:\n", |
613 | 613 | "\n", |
614 | | - "`xarray.apply_ufunc` ↔ `dask.array.apply_gufunc` ↔ `integrate_wrapper` ↔ `scipy.integrate.trapz` ↔ `ds.air.data`\n", |
| 614 | + "`xarray.apply_ufunc` ↔ `dask.array.apply_gufunc` ↔ `integrate_wrapper` ↔ `scipy.integrate.trapezoid` ↔ `ds.air.data`\n", |
615 | 615 | "\n", |
616 | 616 | "\n", |
617 | 617 | "When executed\n", |
618 | 618 | "\n", |
619 | 619 | "1. Xarray loops over all data variables.\n", |
620 | 620 | "1. Xarray unwraps the underlying dask array (e.g. `ds.air`) and passes that to dask's `apply_gufunc`.\n", |
621 | 621 | "1. `apply_gufunc` calls `integrate_wrapper` on each block of the array.\n", |
622 | | - "1. For each block, `integrate_wrapper` calls `scipy.integrate.trapz` and returns one block of the output array.\n", |
| 622 | + "1. For each block, `integrate_wrapper` calls `scipy.integrate.trapezoid` and returns one block of the output array.\n", |
623 | 623 | "1. dask stitches all the output blocks to form the output array.\n", |
624 | 624 | "1. `xarray.apply_ufunc` wraps the output array with Xarray metadata to give the final result.\n", |
625 | 625 | "\n", |
|
0 commit comments