xref: /libCEED/examples/python/tutorial-1-vector.ipynb (revision 2027fb9d13fe34211738d8539f90542a9801ae2c)
1{
2 "cells": [
3  {
4   "cell_type": "markdown",
5   "metadata": {},
6   "source": [
7    "# libCEED for Python examples\n",
8    "\n",
9    "This is a tutorial to illustrate the main feautures of the Python interface for [libCEED](https://github.com/CEED/libCEED/), the low-level API library for efficient high-order discretization methods developed by the co-design [Center for Efficient Exascale Discretizations](https://ceed.exascaleproject.org/) (CEED) of the [Exascale Computing Project](https://www.exascaleproject.org/) (ECP).\n",
10    "\n",
11    "While libCEED's focus is on high-order finite/spectral element method implementations, the approach is mostly algebraic and thus applicable to other discretizations in factored form, as explained in the [user manual](https://libceed.org/)."
12   ]
13  },
14  {
15   "cell_type": "markdown",
16   "metadata": {},
17   "source": [
18    "## Setting up libCEED for Python\n",
19    "\n",
20    "Install libCEED for Python by running"
21   ]
22  },
23  {
24   "cell_type": "code",
25   "execution_count": null,
26   "metadata": {},
27   "outputs": [],
28   "source": [
29    "! python -m pip install libceed"
30   ]
31  },
32  {
33   "cell_type": "markdown",
34   "metadata": {},
35   "source": [
36    "## CeedVector\n",
37    "\n",
38    "Here we show some basic examples to illustrate the `libceed.Vector` class. In libCEED, CeedVectors constitute the main data structure and serve as input/output for `libceed.Operator`. \n",
39    "\n",
40    "We illustrate the simple creation of a `libceed.Vector`, how to specify its size, and how to read or manipulate its data."
41   ]
42  },
43  {
44   "cell_type": "code",
45   "execution_count": null,
46   "metadata": {},
47   "outputs": [],
48   "source": [
49    "import libceed\n",
50    "\n",
51    "ceed = libceed.Ceed()\n",
52    "\n",
53    "n = 10\n",
54    "x = ceed.Vector(n)"
55   ]
56  },
57  {
58   "cell_type": "markdown",
59   "metadata": {},
60   "source": [
61    "The size of the `CeedVector` can also be specified as "
62   ]
63  },
64  {
65   "cell_type": "code",
66   "execution_count": null,
67   "metadata": {},
68   "outputs": [],
69   "source": [
70    "x = ceed.Vector(size=10)"
71   ]
72  },
73  {
74   "cell_type": "markdown",
75   "metadata": {},
76   "source": [
77    "* In the following example, we associate the data stored in a `libceed.Vector` with a `numpy.array` and use it to set and read the `libceed.Vector`'s data"
78   ]
79  },
80  {
81   "cell_type": "code",
82   "execution_count": null,
83   "metadata": {},
84   "outputs": [],
85   "source": [
86    "import numpy as np\n",
87    "\n",
88    "ceed = libceed.Ceed()\n",
89    "x = ceed.Vector(size=3)\n",
90    "\n",
91    "a = np.arange(1, 4, dtype=\"float64\")\n",
92    "x.set_array(a, cmode=libceed.USE_POINTER)\n",
93    "\n",
94    "with x.array_read() as b:\n",
95    "  print(b)"
96   ]
97  },
98  {
99   "cell_type": "markdown",
100   "metadata": {},
101   "source": [
102    "* In the following example, we set all entries to the same value and then visualize the `libceed.Vector`"
103   ]
104  },
105  {
106   "cell_type": "code",
107   "execution_count": null,
108   "metadata": {},
109   "outputs": [],
110   "source": [
111    "ceed = libceed.Ceed()\n",
112    "x = ceed.Vector(size=5)\n",
113    "\n",
114    "x.set_value(10)\n",
115    "\n",
116    "print(x)"
117   ]
118  },
119  {
120   "cell_type": "markdown",
121   "metadata": {},
122   "source": [
123    "* In the following example, we set one vector from the array of another vector"
124   ]
125  },
126  {
127   "cell_type": "code",
128   "execution_count": null,
129   "metadata": {},
130   "outputs": [],
131   "source": [
132    "ceed = libceed.Ceed()\n",
133    "n = 10\n",
134    "\n",
135    "x = ceed.Vector(n)\n",
136    "y = ceed.Vector(n)\n",
137    "\n",
138    "a = np.arange(1, 1 + n, dtype=\"float64\")\n",
139    "x.set_array(a, cmode=libceed.USE_POINTER)\n",
140    "\n",
141    "with x.array() as x_array:\n",
142    "  y.set_array(x_array, cmode=libceed.USE_POINTER)\n",
143    "\n",
144    "with y.array_read() as y_array:\n",
145    "  print(y_array)\n"
146   ]
147  },
148  {
149   "cell_type": "markdown",
150   "metadata": {},
151   "source": [
152    "* In the following example, we access and modify only one entry of the `libceed.Vector`"
153   ]
154  },
155  {
156   "cell_type": "code",
157   "execution_count": null,
158   "metadata": {},
159   "outputs": [],
160   "source": [
161    "n = 10\n",
162    "\n",
163    "x = ceed.Vector(n)\n",
164    "a = np.zeros(n, dtype=\"float64\")\n",
165    "x.set_array(a, cmode=libceed.USE_POINTER)\n",
166    "\n",
167    "with x.array() as b:\n",
168    "  b[3] = -3.14;\n",
169    "a[3]"
170   ]
171  },
172  {
173   "cell_type": "markdown",
174   "metadata": {},
175   "source": [
176    "* In the following example, we compute the $L_1$, $L_2$ (default), and $L_{\\infty}$ norms of a `libceed.Vector` (keeping in mind that these are local norm computations; not accurate for parallel executions with no reductions)."
177   ]
178  },
179  {
180   "cell_type": "code",
181   "execution_count": null,
182   "metadata": {},
183   "outputs": [],
184   "source": [
185    "n = 10\n",
186    "x = ceed.Vector(n)\n",
187    "\n",
188    "a = np.arange(0, n, dtype=\"float64\")\n",
189    "for i in range(n):\n",
190    "  if (i % 2 == 0):\n",
191    "    a[i] *= -1\n",
192    "x.set_array(a, cmode=libceed.USE_POINTER)\n",
193    "\n",
194    "norm_1 = x.norm(normtype=libceed.NORM_1)\n",
195    "print(norm_1)\n",
196    "\n",
197    "norm_2 = x.norm()\n",
198    "print(norm_2)\n",
199    "\n",
200    "norm_max = x.norm(normtype=libceed.NORM_MAX)\n",
201    "print(norm_max)"
202   ]
203  },
204  {
205   "cell_type": "markdown",
206   "metadata": {},
207   "source": [
208    "* If you have installed libCEED with CUDA support and Numba, you can use device memory in your `libceed.Vector`s. In the following example, we create a `libceed.Vector` with a libCEED contex that supports CUDA, associate the data stored in a CeedVector with a `numpy.array`, and get a Numba `DeviceNDArray` containing the data on the device."
209   ]
210  },
211  {
212   "cell_type": "code",
213   "execution_count": null,
214   "metadata": {},
215   "outputs": [],
216   "source": [
217    "ceed_gpu = libceed.Ceed('/gpu/cuda')\n",
218    "\n",
219    "n = 10\n",
220    "x = ceed_gpu.Vector(n)\n",
221    "\n",
222    "a = np.arange(1, 1 + n, dtype=\"float64\")\n",
223    "x.set_array(a, cmode=libceed.USE_POINTER)\n",
224    "\n",
225    "with x.array_read(memtype=libceed.MEM_DEVICE) as device_array:\n",
226    "    print(device_array)"
227   ]
228  }
229 ],
230 "metadata": {
231  "kernelspec": {
232   "display_name": "Python 3",
233   "language": "python",
234   "name": "python3"
235  },
236  "language_info": {
237   "codemirror_mode": {
238    "name": "ipython",
239    "version": 3
240   },
241   "file_extension": ".py",
242   "mimetype": "text/x-python",
243   "name": "python",
244   "nbconvert_exporter": "python",
245   "pygments_lexer": "ipython3",
246   "version": "3.8.5"
247  }
248 },
249 "nbformat": 4,
250 "nbformat_minor": 4
251}
252