Skip to content

Commit 0992e30

Browse files
committed
Rename Enoki to Dr.Jit
1 parent dc79aba commit 0992e30

17 files changed

+1062
-1370
lines changed

_tutorial_template.ipynb

+4-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
},
4646
"outputs": [],
4747
"source": [
48-
"# Add mitsuba and enoki to PATH (this shouldn't be necessary)\n",
48+
"# Add mitsuba and drjit to PATH (this shouldn't be necessary)\n",
4949
"import sys\n",
5050
"sys.path.append('../../../build/python')"
5151
]
@@ -56,7 +56,7 @@
5656
"metadata": {},
5757
"outputs": [],
5858
"source": [
59-
"import enoki as ek \n",
59+
"import drjit as dr\n",
6060
"import mitsuba\n",
6161
"mitsuba.set_variant('scalar_rgb')"
6262
]
@@ -112,7 +112,7 @@
112112
"name": "python",
113113
"nbconvert_exporter": "python",
114114
"pygments_lexer": "ipython3",
115-
"version": "3.8.5"
115+
"version": "3.8.10"
116116
},
117117
"metadata": {
118118
"interpreter": {
@@ -126,5 +126,5 @@
126126
"version": 3
127127
},
128128
"nbformat": 4,
129-
"nbformat_minor": 2
129+
"nbformat_minor": 4
130130
}

basics/00_enoki_cheat_sheet.ipynb

+67-67
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
"id": "8ad9f0d7",
66
"metadata": {},
77
"source": [
8-
"# 0. Enoki cheat sheet\n",
8+
"# 0. Dr.Jit cheat sheet\n",
99
"\n",
1010
"## Overview\n",
1111
"\n",
12-
"This short tutorial recaps the basic functionallities and routines of the Enoki library."
12+
"This short tutorial recaps the basic functionallities and routines of the Dr.Jit library."
1313
]
1414
},
1515
{
@@ -19,9 +19,9 @@
1919
"source": [
2020
"### Similarity with NumPy\n",
2121
"\n",
22-
"On the Python side, the Enoki *syntax* is very similar to NumPy. Moreover, as we will see later, both frameworks are interoperable.\n",
22+
"On the Python side, the Dr.Jit *syntax* is very similar to NumPy. Moreover, as we will see later, both frameworks are interoperable.\n",
2323
"\n",
24-
"Let's first import both NumPy and Enoki using the alias `np` and `ek` respectively"
24+
"Let's first import both NumPy and Dr.Jit using the alias `np` and `dr` respectively"
2525
]
2626
},
2727
{
@@ -32,27 +32,27 @@
3232
"outputs": [],
3333
"source": [
3434
"import numpy as np\n",
35-
"import enoki as ek"
35+
"import drjit as dr"
3636
]
3737
},
3838
{
3939
"cell_type": "markdown",
4040
"id": "a51da003",
4141
"metadata": {},
4242
"source": [
43-
"Unlike NumPy, Enoki can perform array arithmetic on both CPU and GPU through various template variants which are exposed in top-level packages:\n",
43+
"Unlike NumPy, Dr.Jit can perform array arithmetic on both CPU and GPU through various template variants which are exposed in top-level packages:\n",
4444
"\n",
4545
"| Variant | Description |\n",
4646
"| --------------- | ------------------------------------------------------------------ |\n",
47-
"| `enoki.scalar` | Arrays built on top of scalars (float, int, etc.) |\n",
48-
"| `enoki.llvm` | Arrays built on top of LLVMArray |\n",
49-
"| `enoki.cuda` | Arrays built on top of CUDAArray |\n",
50-
"| `enoki.llvm.ad` | Similar to `enoki.llvm` but with automatic differentiation support |\n",
51-
"| `enoki.cuda.ad` | Similar to `enoki.cuda` but with automatic differentiation support |\n",
47+
"| `drjit.scalar` | Arrays built on top of scalars (float, int, etc.) |\n",
48+
"| `drjit.llvm` | Arrays built on top of LLVMArray |\n",
49+
"| `drjit.cuda` | Arrays built on top of CUDAArray |\n",
50+
"| `drjit.llvm.ad` | Similar to `drjit.llvm` but with automatic differentiation support |\n",
51+
"| `drjit.cuda.ad` | Similar to `drjit.cuda` but with automatic differentiation support |\n",
5252
"\n",
5353
"These packages all contains various types like: `Bool, Float, Int, UInt, Array2f, Array2i, Matrix2f Matrix3f, ...`\n",
5454
"\n",
55-
"Let's create some arrays using the `enoki.llvm` variants and play around with the NumPy interoperability:"
55+
"Let's create some arrays using the `drjit.llvm` variants and play around with the NumPy interoperability:"
5656
]
5757
},
5858
{
@@ -65,13 +65,13 @@
6565
"name": "stdout",
6666
"output_type": "stream",
6767
"text": [
68-
"c -> (<class 'enoki.llvm.Float'>) = [9.0, 8.0, 7.0, 6.0]\n",
68+
"c -> (<class 'drjit.llvm.Float'>) = [9.0, 8.0, 7.0, 6.0]\n",
6969
"d -> (<class 'numpy.ndarray'>) = [9. 8. 7. 6.]\n"
7070
]
7171
}
7272
],
7373
"source": [
74-
"from enoki.llvm import Float, UInt32\n",
74+
"from drjit.llvm import Float, UInt32\n",
7575
"\n",
7676
"# Create some floating-point arrays\n",
7777
"a = Float([1.0, 2.0, 3.0, 4.0])\n",
@@ -95,7 +95,7 @@
9595
"source": [
9696
"### Array construction routines\n",
9797
"\n",
98-
"This section provides an overview of various Enoki routines (and their NumPy correspondence) to construct arrays."
98+
"This section provides an overview of various Dr.Jit routines (and their NumPy correspondence) to construct arrays."
9999
]
100100
},
101101
{
@@ -108,28 +108,28 @@
108108
"name": "stdout",
109109
"output_type": "stream",
110110
"text": [
111-
"ek.zero: [0.0, 0.0, 0.0, 0.0, 0.0]\n",
112-
"ek.full: [0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 0.10000000149011612]\n",
113-
"ek.arange: [0, 1, 2, 3, 4]\n",
114-
"ek.linespace: [0.0, 0.5, 1.0, 1.5, 2.0]\n"
111+
"dr.zero: [0.0, 0.0, 0.0, 0.0, 0.0]\n",
112+
"dr.full: [0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 0.10000000149011612]\n",
113+
"dr.arange: [0, 1, 2, 3, 4]\n",
114+
"dr.linespace: [0.0, 0.5, 1.0, 1.5, 2.0]\n"
115115
]
116116
}
117117
],
118118
"source": [
119119
"# Initialize floating-point array of size 5 with zeros\n",
120-
"a = ek.zero(Float, 5) # np.zeros(5)\n",
121-
"print(f'ek.zero: {a}')\n",
120+
"a = dr.zero(Float, 5) # np.zeros(5)\n",
121+
"print(f'dr.zero: {a}')\n",
122122
"\n",
123123
"# Initialize floating-point array of size 5 with a constant value\n",
124-
"a = ek.full(Float, 0.1, 5) # np.ones(5, 0.4)\n",
125-
"print(f'ek.full: {a}')\n",
124+
"a = dr.full(Float, 0.1, 5) # np.ones(5, 0.4)\n",
125+
"print(f'dr.full: {a}')\n",
126126
"\n",
127-
"a = ek.arange(UInt32, 5) # np.arange(5)\n",
128-
"print(f'ek.arange: {a}')\n",
127+
"a = dr.arange(UInt32, 5) # np.arange(5)\n",
128+
"print(f'dr.arange: {a}')\n",
129129
"\n",
130130
"# Return evenly spaced numbers over a specified interval\n",
131-
"a = ek.linspace(Float, 0.0, 2.0, 5) # np.linspace(0.0, 2.0, 5)\n",
132-
"print(f'ek.linespace: {a}')"
131+
"a = dr.linspace(Float, 0.0, 2.0, 5) # np.linspace(0.0, 2.0, 5)\n",
132+
"print(f'dr.linespace: {a}')"
133133
]
134134
},
135135
{
@@ -139,11 +139,11 @@
139139
"source": [
140140
"### Masking\n",
141141
"\n",
142-
"Writing codes using Enoki often means working with large arrays at once. Therefore it is not possible to use regular `if .. else ..` statements based on concret values, as different elements in the array might branch differently. This is where **masking** comes to the rescue! \n",
142+
"Writing codes using Dr.Jit often means working with large arrays at once. Therefore it is not possible to use regular `if .. else ..` statements based on concret values, as different elements in the array might branch differently. This is where **masking** comes to the rescue! \n",
143143
"\n",
144144
"A mask (or `Bool`) is an array of boolean values that can be used to disable arithmetic operations on part of an array. It is possible to create such masks with any regular boolean arithmetic (e.g. `>, <, >=, <=`). \n",
145145
"\n",
146-
"Often time, we combine masks with the `ek.select(mask, a, b)` statement which correspond to the ternary statement `mask ? a : b`. This is similar to the `np.where` function in NumPy."
146+
"Often time, we combine masks with the `dr.select(mask, a, b)` statement which correspond to the ternary statement `mask ? a : b`. This is similar to the `np.where` function in NumPy."
147147
]
148148
},
149149
{
@@ -156,16 +156,16 @@
156156
"name": "stdout",
157157
"output_type": "stream",
158158
"text": [
159-
"x -> (<class 'enoki.llvm.Float'>) [0.0, 1.0, 2.0, 3.0, 4.0]\n",
160-
"m -> (<class 'enoki.llvm.Bool'>) [False, False, False, True, True]\n",
161-
"y -> (<class 'enoki.llvm.Float'>) [1.0, 1.0, 1.0, 4.0, 4.0]\n"
159+
"x -> (<class 'drjit.llvm.Float'>) [0.0, 1.0, 2.0, 3.0, 4.0]\n",
160+
"m -> (<class 'drjit.llvm.Bool'>) [False, False, False, True, True]\n",
161+
"y -> (<class 'drjit.llvm.Float'>) [1.0, 1.0, 1.0, 4.0, 4.0]\n"
162162
]
163163
}
164164
],
165165
"source": [
166-
"x = ek.arange(Float, 5)\n",
166+
"x = dr.arange(Float, 5)\n",
167167
"m = x > 2.0 # True for all values of a that are greater than 2.0\n",
168-
"y = ek.select(m, 4.0, 1.0) # Set the values greater than 2.0 to 4.0 otherwise to 1.0\n",
168+
"y = dr.select(m, 4.0, 1.0) # Set the values greater than 2.0 to 4.0 otherwise to 1.0\n",
169169
"print(f'x -> ({type(x)}) {x}')\n",
170170
"print(f'm -> ({type(m)}) {m}')\n",
171171
"print(f'y -> ({type(y)}) {y}')"
@@ -178,12 +178,12 @@
178178
"source": [
179179
"### Basic math arithmetic\n",
180180
"\n",
181-
"All common math operators like `+, -, /, *, *=, +=, %, //, ...` are supported with Enoki arrays.\n",
181+
"All common math operators like `+, -, /, *, *=, +=, %, //, ...` are supported with Dr.Jit arrays.\n",
182182
"\n",
183-
"Similarly to NumPy, Enoki provides all kinds of math arithmetic that can be performed on the entire array in a single call. Here is a non-exaustive list of those math functions:\n",
183+
"Similarly to NumPy, Dr.Jit provides all kinds of math arithmetic that can be performed on the entire array in a single call. Here is a non-exaustive list of those math functions:\n",
184184
"`abs, min, max, sqrt, pow, sin, cos, tan, atan2, sincos, sec, cot, asin, acos, atan, exp, exp2, log, log2, sinh, cosh, tanh, asinh, acosh, atanh, ...`\n",
185185
"\n",
186-
"Those routines are present in the root enoki package, hence can be used as follow:"
186+
"Those routines are present in the root drjit package, hence can be used as follow:"
187187
]
188188
},
189189
{
@@ -201,8 +201,8 @@
201201
}
202202
],
203203
"source": [
204-
"s, c = ek.sincos(a)\n",
205-
"m = ek.min(s, c)\n",
204+
"s, c = dr.sincos(a)\n",
205+
"m = dr.min(s, c)\n",
206206
"print(f'm: {m}')"
207207
]
208208
},
@@ -213,7 +213,7 @@
213213
"source": [
214214
"### Horizontal operations\n",
215215
"\n",
216-
"Enoki also provides operations that require a pass over the entire array and return a single scalar value. Those operations are expensive as they will trigger a syncronization point, hence it is better to avoid them if possible.\n",
216+
"Dr.Jit also provides operations that require a pass over the entire array and return a single scalar value. Those operations are expensive as they will trigger a syncronization point, hence it is better to avoid them if possible.\n",
217217
"\n",
218218
"The following snippet of code explores a few of those:"
219219
]
@@ -229,46 +229,46 @@
229229
"output_type": "stream",
230230
"text": [
231231
"a: [1.0, 2.0, 3.0, 4.0, 5.0]\n",
232-
"ek.hsum(a): 15.0\n",
233-
"ek.hprod(a): 120.0\n",
234-
"ek.hmean(a): 3.0\n",
232+
"dr.hsum(a): 15.0\n",
233+
"dr.hprod(a): 120.0\n",
234+
"dr.hmean(a): 3.0\n",
235235
"m: [False, False, True, True, True]\n",
236-
"ek.all(m): False\n",
237-
"ek.any(m): True\n",
238-
"ek.none(m): False\n"
236+
"dr.all(m): False\n",
237+
"dr.any(m): True\n",
238+
"dr.none(m): False\n"
239239
]
240240
}
241241
],
242242
"source": [
243-
"a = ek.arange(Float, 5) + 1\n",
243+
"a = dr.arange(Float, 5) + 1\n",
244244
"print(f'a: {a}')\n",
245245
"\n",
246246
"# Horizontal sum\n",
247-
"b = ek.hsum(a) # np.sum(a)\n",
248-
"print(f'ek.hsum(a): {b}')\n",
247+
"b = dr.hsum(a) # np.sum(a)\n",
248+
"print(f'dr.hsum(a): {b}')\n",
249249
"\n",
250250
"# Horizontal product\n",
251-
"b = ek.hprod(a) # np.prod(a)\n",
252-
"print(f'ek.hprod(a): {b}')\n",
251+
"b = dr.hprod(a) # np.prod(a)\n",
252+
"print(f'dr.hprod(a): {b}')\n",
253253
"\n",
254254
"# Mean value over the entire array\n",
255-
"b = ek.hmean(a) # np.mean(a)\n",
256-
"print(f'ek.hmean(a): {b}')\n",
255+
"b = dr.hmean(a) # np.mean(a)\n",
256+
"print(f'dr.hmean(a): {b}')\n",
257257
"\n",
258258
"m = a > 2\n",
259259
"print(f'm: {m}')\n",
260260
"\n",
261261
"# True if all value of the mask array are True\n",
262-
"b = ek.all(m) # np.all(m)\n",
263-
"print(f'ek.all(m): {b}')\n",
262+
"b = dr.all(m) # np.all(m)\n",
263+
"print(f'dr.all(m): {b}')\n",
264264
"\n",
265265
"# True if any value of the mask array are True\n",
266-
"b = ek.any(m) # np.any(m)\n",
267-
"print(f'ek.any(m): {b}')\n",
266+
"b = dr.any(m) # np.any(m)\n",
267+
"print(f'dr.any(m): {b}')\n",
268268
"\n",
269269
"# True if no value of the mask array are True\n",
270-
"b = ek.none(m) # ~np.any(m)\n",
271-
"print(f'ek.none(m): {b}')"
270+
"b = dr.none(m) # ~np.any(m)\n",
271+
"print(f'dr.none(m): {b}')"
272272
]
273273
},
274274
{
@@ -278,9 +278,9 @@
278278
"source": [
279279
"### `gather` and `scatter` routines\n",
280280
"\n",
281-
"In programming languages like C++ or Python, it is possible to access the i-th element of an array using the `array[i]` syntax. This can both be used to read or write values in an array. Similarly, Enoki provides such read/write functionalities through the `ek.gather` and `ek.scatter` functions. Those are much more powerful than the regular array accessors as the index `i` can be an array itself! In which case the read operation (e.g. `ek.gather`) would return a array as well, not just a single value.\n",
281+
"In programming languages like C++ or Python, it is possible to access the i-th element of an array using the `array[i]` syntax. This can both be used to read or write values in an array. Similarly, Dr.Jit provides such read/write functionalities through the `dr.gather` and `dr.scatter` functions. Those are much more powerful than the regular array accessors as the index `i` can be an array itself! In which case the read operation (e.g. `dr.gather`) would return a array as well, not just a single value.\n",
282282
"\n",
283-
"Here is how one should use the `ek.gather` routine to read entries from an Enoki array:"
283+
"Here is how one should use the `dr.gather` routine to read entries from an Dr.Jit array:"
284284
]
285285
},
286286
{
@@ -300,9 +300,9 @@
300300
}
301301
],
302302
"source": [
303-
"source = ek.linspace(Float, 0, 1, 5)\n",
303+
"source = dr.linspace(Float, 0, 1, 5)\n",
304304
"indices = UInt32([1, 2]) # Only read the 2nd and 3rd elements of the source array\n",
305-
"result = ek.gather(Float, source, indices)\n",
305+
"result = dr.gather(Float, source, indices)\n",
306306
"print(f'source: {source}')\n",
307307
"print(f'indices: {indices}')\n",
308308
"print(f'result: {result}')"
@@ -313,7 +313,7 @@
313313
"id": "07f6203b",
314314
"metadata": {},
315315
"source": [
316-
"And here is how one can write entries at specific indices into a Enoki array"
316+
"And here is how one can write entries at specific indices into a Dr.Jit array"
317317
]
318318
},
319319
{
@@ -333,10 +333,10 @@
333333
}
334334
],
335335
"source": [
336-
"target = ek.zero(Float, 5)\n",
336+
"target = dr.zero(Float, 5)\n",
337337
"indices = UInt32([0, 3, 4]) # Write to the first and last two elements of the target array\n",
338338
"source = Float([1.0, 2.0, 3.0])\n",
339-
"ek.scatter(target, source, indices)\n",
339+
"dr.scatter(target, source, indices)\n",
340340
"print(f'indices: {indices}')\n",
341341
"print(f'source: {source}')\n",
342342
"print(f'target: {target}')"
@@ -345,7 +345,7 @@
345345
],
346346
"metadata": {
347347
"kernelspec": {
348-
"display_name": "Python 3",
348+
"display_name": "Python 3 (ipykernel)",
349349
"language": "python",
350350
"name": "python3"
351351
},

0 commit comments

Comments
 (0)