|
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