{ "cells": [ { "cell_type": "markdown", "id": "0d6fecdf-48c0-4745-b802-2117fb3137cf", "metadata": {}, "source": [ "# Basic Computations" ] }, { "cell_type": "markdown", "id": "15a05d43-0bf5-48d3-9c88-6074eed82a04", "metadata": {}, "source": [ "## Overview\n", "### In this tutorial, you learn:\n", "\n", "* Applying basic arithmetic and NumPy functions to xarray DataArrays with CuPy.\n", "* Perform operations across multiple datasets\n", "* Understand two important concepts: broadcasting and alignment.\n", "* Performance of Xarray using Cupy vs. Numpy on different array sizes. \n", "\n", "## Prerequisites\n", "\n", "| Concepts | Importance | Notes |\n", "| --- | --- | --- |\n", "| [Familiarity with NumPy](https://foundations.projectpythia.org/core/numpy.html) | Necessary | |\n", "| [Basics of Cupy](Notebook0_Introduction) | Necessary | |\n", "| [Familiarity with Xarray](https://foundations.projectpythia.org/core/xarray.html) | Necessary | |\n", "\n", "- **Time to learn**: 40 minutes\n", "\n", "\n", "## Introduction " ] }, { "cell_type": "markdown", "id": "77343efb-de6d-423c-b1cd-934c5d6d68e1", "metadata": {}, "source": [ "First, let's import our packages\n", "\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "55c72b7d-8899-4e2f-9432-e9cf1531cbdf", "metadata": {}, "outputs": [], "source": [ "## Import NumPy and CuPy\n", "import cupy as cp\n", "import numpy as np\n", "import xarray as xr\n", "import cupy_xarray # Adds .cupy to Xarray objects" ] }, { "cell_type": "markdown", "id": "4ed42841-264a-4eb6-9f82-be9a463be816", "metadata": {}, "source": [ "### Creating Xarray DataArray with CuPy" ] }, { "cell_type": "markdown", "id": "573bb115-0e77-4f86-be9f-9ee6ac1c6f9b", "metadata": {}, "source": [ "In the previous tutorial, we learned how to create a DataArray that wraps a CuPy array:" ] }, { "cell_type": "code", "execution_count": 2, "id": "4b91fc01-9e99-4b01-b700-9b4802b7ef14", "metadata": {}, "outputs": [], "source": [ "arr_gpu = cp.random.rand(10, 10)" ] }, { "cell_type": "code", "execution_count": 3, "id": "431edeb0-661f-4929-a83d-e39a6e753a60", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (x: 10, y: 10)>\n",
       "array([[0.64440645, 0.62072123, 0.75168547, 0.41128605, 0.88459028,\n",
       "        0.47016308, 0.86304331, 0.92990986, 0.0041129 , 0.4666957 ],\n",
       "       [0.56647797, 0.11373418, 0.62628122, 0.78959584, 0.36494045,\n",
       "        0.13310425, 0.73672578, 0.86921365, 0.05596426, 0.55426342],\n",
       "       [0.4720759 , 0.6481852 , 0.46598961, 0.93751977, 0.97099829,\n",
       "        0.94932666, 0.54603983, 0.29783205, 0.36190421, 0.44288443],\n",
       "       [0.62394009, 0.14474529, 0.36714822, 0.30050983, 0.44310121,\n",
       "        0.45300226, 0.84836414, 0.41480516, 0.15972742, 0.30865762],\n",
       "       [0.17974085, 0.43178982, 0.68688623, 0.2870211 , 0.94622374,\n",
       "        0.05305575, 0.10551911, 0.50202377, 0.32414185, 0.52343633],\n",
       "       [0.57433335, 0.55480641, 0.65053659, 0.84821379, 0.86448478,\n",
       "        0.4614566 , 0.41249327, 0.04641715, 0.9086778 , 0.55099052],\n",
       "       [0.99359918, 0.19577754, 0.42470934, 0.20198499, 0.49022272,\n",
       "        0.56950438, 0.55683842, 0.81856686, 0.97131091, 0.73117734],\n",
       "       [0.05195378, 0.09355582, 0.23061675, 0.48168679, 0.20765511,\n",
       "        0.44548051, 0.54251798, 0.63568233, 0.61946882, 0.48324004],\n",
       "       [0.89803925, 0.89935711, 0.57733868, 0.21010146, 0.15491007,\n",
       "        0.27044434, 0.14652858, 0.35991027, 0.87969536, 0.57918609],\n",
       "       [0.31083571, 0.29447116, 0.06544057, 0.46585981, 0.0189647 ,\n",
       "        0.08291839, 0.16705158, 0.53118993, 0.99264236, 0.75636455]])\n",
       "Dimensions without coordinates: x, y
" ], "text/plain": [ "\n", "array([[0.64440645, 0.62072123, 0.75168547, 0.41128605, 0.88459028,\n", " 0.47016308, 0.86304331, 0.92990986, 0.0041129 , 0.4666957 ],\n", " [0.56647797, 0.11373418, 0.62628122, 0.78959584, 0.36494045,\n", " 0.13310425, 0.73672578, 0.86921365, 0.05596426, 0.55426342],\n", " [0.4720759 , 0.6481852 , 0.46598961, 0.93751977, 0.97099829,\n", " 0.94932666, 0.54603983, 0.29783205, 0.36190421, 0.44288443],\n", " [0.62394009, 0.14474529, 0.36714822, 0.30050983, 0.44310121,\n", " 0.45300226, 0.84836414, 0.41480516, 0.15972742, 0.30865762],\n", " [0.17974085, 0.43178982, 0.68688623, 0.2870211 , 0.94622374,\n", " 0.05305575, 0.10551911, 0.50202377, 0.32414185, 0.52343633],\n", " [0.57433335, 0.55480641, 0.65053659, 0.84821379, 0.86448478,\n", " 0.4614566 , 0.41249327, 0.04641715, 0.9086778 , 0.55099052],\n", " [0.99359918, 0.19577754, 0.42470934, 0.20198499, 0.49022272,\n", " 0.56950438, 0.55683842, 0.81856686, 0.97131091, 0.73117734],\n", " [0.05195378, 0.09355582, 0.23061675, 0.48168679, 0.20765511,\n", " 0.44548051, 0.54251798, 0.63568233, 0.61946882, 0.48324004],\n", " [0.89803925, 0.89935711, 0.57733868, 0.21010146, 0.15491007,\n", " 0.27044434, 0.14652858, 0.35991027, 0.87969536, 0.57918609],\n", " [0.31083571, 0.29447116, 0.06544057, 0.46585981, 0.0189647 ,\n", " 0.08291839, 0.16705158, 0.53118993, 0.99264236, 0.75636455]])\n", "Dimensions without coordinates: x, y" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "da_cp = xr.DataArray(arr_gpu, dims=[\"x\", \"y\"])\n", "\n", "da_cp" ] }, { "cell_type": "markdown", "id": "62af1f7c-0ac2-4bad-ab92-8f1bcfbaffe3", "metadata": {}, "source": [ "## Basic Operations with Xarray and CuPy" ] }, { "cell_type": "markdown", "id": "ff85bc62-de58-4859-80d2-433fc6af4dcf", "metadata": {}, "source": [ "### Basic Arithmetic" ] }, { "cell_type": "markdown", "id": "5e700f37-3962-4aeb-86ae-7465e0549e1a", "metadata": {}, "source": [ "Xarray data arrays and datasets are compatible with arithmetic operators and numpy array functions, making it easy to work with arithmetic operators.\n" ] }, { "cell_type": "markdown", "id": "d8ffedc1-51e3-4a9f-8925-b98650133a44", "metadata": {}, "source": [ "Once we have created a DataArray using CuPy, we can perform various operations on it using the familiar Xarray syntax. For example:" ] }, { "cell_type": "code", "execution_count": 6, "id": "2adc12d1-d213-454d-892a-b26e6e10b581", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "result_cp = da_cp * 2 + 200\n", "print(type(result_cp.data))" ] }, { "cell_type": "code", "execution_count": 7, "id": "61cf4ce6-1f2d-40bb-8933-aebc5b850f38", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "da_np = da_cp.as_numpy()\n", "result_np = da_np * 2 + 200\n", "print(type(result_np.data))" ] }, { "cell_type": "markdown", "id": "4a23ebf6-ee17-48de-8474-83dcfe863b18", "metadata": {}, "source": [ "### Reductions\n", "\n", "We can use similar statistical functions as the NumPy equivalants here. For a complete list of statistical functions, please visit [the API reference](https://docs.cupy.dev/en/v8.6.0/reference/statistics.html)." ] }, { "cell_type": "code", "execution_count": 8, "id": "d812cb7b-8a9e-40d3-b2eb-9ed051554db9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 1.24 ms, sys: 98 µs, total: 1.34 ms\n", "Wall time: 1.35 ms\n" ] } ], "source": [ "%%time\n", "# calculate the mean along the x dimension\n", "mean_cp = da_cp.mean(dim=\"x\")" ] }, { "cell_type": "code", "execution_count": 9, "id": "ea6636c6-d666-4d26-aa38-cea7fbf1a090", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(type(mean_cp.data))" ] }, { "cell_type": "code", "execution_count": 10, "id": "340de30b-dac8-424f-a1db-9ee0a80bce18", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 191 µs, sys: 75 µs, total: 266 µs\n", "Wall time: 270 µs\n" ] } ], "source": [ "%%time\n", "# calculate the mean along the x dimension\n", "mean_np = da_np.mean(dim=\"x\")" ] }, { "cell_type": "code", "execution_count": 11, "id": "c65514eb-b61e-4b1c-93c8-9a6d30536177", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(type(mean_np.data))" ] }, { "cell_type": "code", "execution_count": 12, "id": "35bc6495-54bf-40a8-9417-5852f0f8731b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 2.22 ms, sys: 909 µs, total: 3.12 ms\n", "Wall time: 3.15 ms\n" ] } ], "source": [ "%%time\n", "# calculate the standard deviation along the x and y dimensions\n", "std_cp = da_cp.std(dim=[\"x\", \"y\"])" ] }, { "cell_type": "code", "execution_count": 13, "id": "c4c05ec3-68f1-4106-8ee3-587014eaf40e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(type(std_cp.data))" ] }, { "cell_type": "code", "execution_count": 14, "id": "25e128ad-0b55-4528-a273-a80ecb1f5bd4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 215 µs, sys: 85 µs, total: 300 µs\n", "Wall time: 304 µs\n" ] } ], "source": [ "%%time\n", "# calculate the standard deviation along the x and y dimensions\n", "std_np = da_np.std(dim=[\"x\", \"y\"])" ] }, { "cell_type": "code", "execution_count": 15, "id": "c9b131b8-2aa9-4f54-bcea-19ee587a28d3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "print(type(std_cp.data))" ] }, { "cell_type": "code", "execution_count": 16, "id": "c1c09656-6238-4c56-a649-56cca44370b0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 3.85 ms, sys: 942 µs, total: 4.79 ms\n", "Wall time: 4.83 ms\n" ] }, { "data": { "text/plain": [ "cupy.ndarray" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "# calculate the median along the x dimension\n", "med_cp = da_cp.median(dim=[\"x\"])\n", "type(med_cp.data)" ] }, { "cell_type": "code", "execution_count": 17, "id": "4e769ea7-afb0-43f0-9507-4d142d4a9987", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 113 µs, sys: 44 µs, total: 157 µs\n", "Wall time: 160 µs\n" ] }, { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "# calculate the median along the x dimension\n", "med_np = da_np.median(dim=[\"x\"])\n", "type(med_np.data)" ] }, { "cell_type": "markdown", "id": "30425020-0828-4f7a-b9bb-7ade36ceae20", "metadata": {}, "source": [ "Similarly we use statical functions to find order statistics:\n" ] }, { "cell_type": "code", "execution_count": 18, "id": "0ee3c022-1a9c-4464-b728-be9f60f8bbfa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 2.24 ms, sys: 94 µs, total: 2.33 ms\n", "Wall time: 2.33 ms\n" ] }, { "data": { "text/plain": [ "cupy.ndarray" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "# calculate the minimum along all dimensions\n", "min_cp = da_cp.min()\n", "type(min_cp.data)" ] }, { "cell_type": "code", "execution_count": 19, "id": "0df6c10f-335d-45d0-b0d8-40142b519bd9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 104 µs, sys: 0 ns, total: 104 µs\n", "Wall time: 106 µs\n" ] }, { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "# calculate the minimum along all dimensions\n", "min_np = da_np.min()\n", "type(min_np.data)" ] }, { "cell_type": "markdown", "id": "629a7339-b7ad-4636-a5f3-93e0772829f0", "metadata": {}, "source": [ "```{note}\n", "All Xarray operations *should* preserve array type. If they don't, please open an [issue](https://github.com/pydata/xarray/issues/new/choose).\n", "```" ] }, { "cell_type": "markdown", "id": "7bab9311-8a4f-4ce5-bfdf-086aa09d5d11", "metadata": {}, "source": [ "### Universal Functions (`ufunc`)\n", "\n", "Universal functions (or `ufunc` for short) are functions that operate element-wise on ndarrays, meaning they can perform computations on each element of an array without the need for explicit looping. \n", "\n", "These functions are designed to handle vectorized operations, which can significantly improve the performance and readability of your code.\n", "\n", "NumPy's universal functions offer a wide range of mathematical operations, including trigonometric functions (sin, cos, tan), exponential functions (exp, log), comparison operations (greater than, less than), and many others. We can apply these functions to the Xarray DataArray that wraps CuPy arrays:" ] }, { "cell_type": "code", "execution_count": 20, "id": "1304c015-e152-418a-b403-b489e8e2492c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 1.14 ms, sys: 54 µs, total: 1.19 ms\n", "Wall time: 1.2 ms\n" ] }, { "data": { "text/plain": [ "cupy.ndarray" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "# calculate the element-wise trigonometric sine\n", "sin_cp = np.sin(da_cp)\n", "type(sin_cp.data)" ] }, { "cell_type": "code", "execution_count": 21, "id": "f594a824-5459-4f24-9f9b-d5dfffd769c2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 846 µs, sys: 938 µs, total: 1.78 ms\n", "Wall time: 1.79 ms\n" ] }, { "data": { "text/plain": [ "cupy.ndarray" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "round_cp = np.round(da_cp.mean(), 2)\n", "type(round_cp.data)" ] }, { "cell_type": "markdown", "id": "a44f6d72-0e7c-4899-81eb-64187123cfa0", "metadata": {}, "source": [ "## Computing with Multiple Objects\n", "\n", "### Alignment \n", "\n", "Alignment in xarray refers to the process of automatically aligning multiple DataArrays or Datasets based on their coordinates. Alignment ensures that the data along these coordinates is properly aligned before performing operations or calculations. This alignment is crucial because it enables xarray to handle operations on arrays with different sizes, shapes, and dimensions.\n", "\n", "\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 22, "id": "69929337-6ed0-4312-b461-88f4006cf4b9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (space: 3, time: 4)>\n",
       "array([[ 0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11]])\n",
       "Coordinates:\n",
       "  * space    (space) <U1 'a' 'b' 'c'\n",
       "  * time     (time) int64 0 1 2 3
" ], "text/plain": [ "\n", "array([[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11]])\n", "Coordinates:\n", " * space (space) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (space: 2, time: 7)>\n",
       "array([[ 0,  1,  2,  3,  4,  5,  6],\n",
       "       [ 7,  8,  9, 10, 11, 12, 13]])\n",
       "Coordinates:\n",
       "  * space    (space) <U1 'b' 'd'\n",
       "  * time     (time) int64 -2 -1 0 1 2 3 4
" ], "text/plain": [ "\n", "array([[ 0, 1, 2, 3, 4, 5, 6],\n", " [ 7, 8, 9, 10, 11, 12, 13]])\n", "Coordinates:\n", " * space (space) \n", "\n", "Xarray broadcasting work similarly with CuPy and it preserves the data type. Here's an example to illustrate this:" ] }, { "cell_type": "code", "execution_count": 25, "id": "2f395864-7ef6-42a2-812e-703ca82eefd4", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (space: 3)>\n",
       "array([0, 1, 2])\n",
       "Coordinates:\n",
       "  * space    (space) <U1 'a' 'b' 'c'
" ], "text/plain": [ "\n", "array([0, 1, 2])\n", "Coordinates:\n", " * space (space) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (time: 4)>\n",
       "array([0, 1, 2, 3])\n",
       "Coordinates:\n",
       "  * time     (time) int64 0 1 2 3
" ], "text/plain": [ "\n", "array([0, 1, 2, 3])\n", "Coordinates:\n", " * time (time) int64 0 1 2 3" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gpu_arr2 = xr.DataArray(\n", " cp.arange(4),\n", " dims=\"time\",\n", " coords={\"time\": [0, 1, 2, 3]},\n", ")\n", "\n", "gpu_arr2" ] }, { "cell_type": "markdown", "id": "e8e01e23-d697-4485-b466-4288dc1429dd", "metadata": {}, "source": [ "We can explicitly broadcast any number of arrays against each other using `xr.broadcast`:" ] }, { "cell_type": "code", "execution_count": 27, "id": "dd3ce7b7-7d16-4ec3-83a3-751b25e62e2e", "metadata": {}, "outputs": [], "source": [ "arr1_broadcasted, arr2_broadcasted = xr.broadcast(gpu_arr1, gpu_arr2)" ] }, { "cell_type": "code", "execution_count": 28, "id": "19d43635-4b1d-49c3-a94e-f4470360e518", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (space: 3, time: 4)>\n",
       "array([[0, 0, 0, 0],\n",
       "       [1, 1, 1, 1],\n",
       "       [2, 2, 2, 2]])\n",
       "Coordinates:\n",
       "  * space    (space) <U1 'a' 'b' 'c'\n",
       "  * time     (time) int64 0 1 2 3
" ], "text/plain": [ "\n", "array([[0, 0, 0, 0],\n", " [1, 1, 1, 1],\n", " [2, 2, 2, 2]])\n", "Coordinates:\n", " * space (space) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (space: 3, time: 4)>\n",
       "array([[0, 1, 2, 3],\n",
       "       [0, 1, 2, 3],\n",
       "       [0, 1, 2, 3]])\n",
       "Coordinates:\n",
       "  * time     (time) int64 0 1 2 3\n",
       "  * space    (space) <U1 'a' 'b' 'c'
" ], "text/plain": [ "\n", "array([[0, 1, 2, 3],\n", " [0, 1, 2, 3],\n", " [0, 1, 2, 3]])\n", "Coordinates:\n", " * time (time) int64 0 1 2 3\n", " * space (space) " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "# Creating figure with two subplots\n", "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))\n", "\n", "# Plot 1 : CuPy time and NumPy time\n", "ax1.plot(sizes, cp_times, marker=\"o\", label=\"CuPy Time\")\n", "ax1.plot(sizes, np_times, marker=\"o\", label=\"NumPy Time\")\n", "ax1.set_xlabel(\"Array Size\")\n", "ax1.set_ylabel(\"Time\")\n", "ax1.set_xticks(sizes)\n", "ax1.legend()\n", "\n", "# Plot 2 : Speedup\n", "ax2.plot(sizes, speedups, marker=\"o\")\n", "ax2.set_xlabel(\"Array Size\")\n", "ax2.set_ylabel(\"Speedup (CuPy time / NumPy time)\")\n", "ax2.set_xticks(sizes)\n", "fig.suptitle(\"Relative Humidity Calculation\")\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "ae89bf5f-10b1-435d-b9f6-487def091dbd", "metadata": {}, "source": [ "The plots above clearly illustrate that as the size of the data increases, the performance improvement offered by CuPy becomes increasingly significant." ] }, { "cell_type": "markdown", "id": "add5a5c1-8a18-4717-8775-9b75edb8347a", "metadata": {}, "source": [ "Congratulations! You have now uncovered the basic operations and capabilities of CuPy. \n", "\n", "## Summary\n", "\n", "In this notebook, we have learned about:\n", " \n", "* Applying basic arithmetic and NumPy functions to xarray DataArrays with CuPy.\n", "* Perform operations across multiple datasets\n", "* Understand two important concepts: broadcasting and alignment.\n", "* Performance of Cupy vs. Numpy on different array sizes. \n", "\n", "```{seealso}\n", "\n", "[CuPy User Guide](https://docs.cupy.dev/en/stable/user_guide/index.html) \n", "[Xarray User Guide](https://docs.xarray.dev/en/stable/user-guide/index.html) \n", "[Cupy-Xarray Github](https://github.com/xarray-contrib/cupy-xarray.git) \n", "```" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }