@@ -46,7 +46,7 @@ The following snippet imports the most commonly used features that are needed to
46
46
import numpy as np
47
47
48
48
import gt4py.next as gtx
49
- from gt4py.next import float64, neighbor_sum, where
49
+ from gt4py.next import float64, neighbor_sum, where, Dims
50
50
```
51
51
52
52
#### Fields
@@ -91,11 +91,12 @@ Let's see an example for a field operator that adds two fields elementwise:
91
91
92
92
``` {code-cell} ipython3
93
93
@gtx.field_operator
94
- def add(a: gtx.Field[[CellDim, KDim], float64],
95
- b: gtx.Field[[CellDim, KDim], float64]) -> gtx.Field[[CellDim, KDim], float64]:
94
+ def add(a: gtx.Field[gtx.Dims [CellDim, KDim], float64],
95
+ b: gtx.Field[gtx.Dims [CellDim, KDim], float64]) -> gtx.Field[gtx.Dims [CellDim, KDim], float64]:
96
96
return a + b
97
97
```
98
98
99
+ \_ Note: for now ` Dims ` is not mandatory, hence this type hint is also accepted: ` gtx.Field[[CellDim, KDim], float64] `
99
100
You can call field operators from [ programs] ( #Programs ) , other field operators, or directly. The code snippet below shows a direct call, in which case you have to supply two additional arguments: ` out ` , which is a field to write the return value to, and ` offset_provider ` , which is left empty for now. The result of the field operator is a field with all entries equal to 5, but for brevity, only the average and the standard deviation of the entries are printed:
100
101
101
102
``` {code-cell} ipython3
@@ -115,9 +116,9 @@ This example program below calls the above elementwise addition field operator t
115
116
116
117
``` {code-cell} ipython3
117
118
@gtx.program
118
- def run_add(a : gtx.Field[[CellDim, KDim], float64],
119
- b : gtx.Field[[CellDim, KDim], float64],
120
- result : gtx.Field[[CellDim, KDim], float64]):
119
+ def run_add(a : gtx.Field[gtx.Dims [CellDim, KDim], float64],
120
+ b : gtx.Field[gtx.Dims [CellDim, KDim], float64],
121
+ result : gtx.Field[gtx.Dims [CellDim, KDim], float64]):
121
122
add(a, b, out=result)
122
123
add(b, result, out=result)
123
124
```
@@ -247,11 +248,11 @@ Pay attention to the syntax where the field offset `E2C` can be freely accessed
247
248
248
249
``` {code-cell} ipython3
249
250
@gtx.field_operator
250
- def nearest_cell_to_edge(cell_values: gtx.Field[[CellDim], float64]) -> gtx.Field[[EdgeDim], float64]:
251
+ def nearest_cell_to_edge(cell_values: gtx.Field[gtx.Dims [CellDim], float64]) -> gtx.Field[gtx.Dims [EdgeDim], float64]:
251
252
return cell_values(E2C[0])
252
253
253
254
@gtx.program
254
- def run_nearest_cell_to_edge(cell_values: gtx.Field[[CellDim], float64], out : gtx.Field[[EdgeDim], float64]):
255
+ def run_nearest_cell_to_edge(cell_values: gtx.Field[gtx.Dims [CellDim], float64], out : gtx.Field[gtx.Dims [EdgeDim], float64]):
255
256
nearest_cell_to_edge(cell_values, out=out)
256
257
257
258
run_nearest_cell_to_edge(cell_values, edge_values, offset_provider={"E2C": E2C_offset_provider})
@@ -273,12 +274,12 @@ Similarly to the previous example, the output is once again a field on edges. Th
273
274
274
275
``` {code-cell} ipython3
275
276
@gtx.field_operator
276
- def sum_adjacent_cells(cells : gtx.Field[[CellDim], float64]) -> gtx.Field[[EdgeDim], float64]:
277
- # type of cells(E2C) is gtx.Field[[CellDim, E2CDim], float64]
277
+ def sum_adjacent_cells(cells : gtx.Field[gtx.Dims [CellDim], float64]) -> gtx.Field[gtx.Dims [EdgeDim], float64]:
278
+ # type of cells(E2C) is gtx.Field[gtx.Dims [CellDim, E2CDim], float64]
278
279
return neighbor_sum(cells(E2C), axis=E2CDim)
279
280
280
281
@gtx.program
281
- def run_sum_adjacent_cells(cells : gtx.Field[[CellDim], float64], out : gtx.Field[[EdgeDim], float64]):
282
+ def run_sum_adjacent_cells(cells : gtx.Field[gtx.Dims [CellDim], float64], out : gtx.Field[gtx.Dims [EdgeDim], float64]):
282
283
sum_adjacent_cells(cells, out=out)
283
284
284
285
run_sum_adjacent_cells(cell_values, edge_values, offset_provider={"E2C": E2C_offset_provider})
@@ -302,7 +303,7 @@ This function takes 3 input arguments:
302
303
- mask: a field with dtype boolean
303
304
- true branch: a tuple, a field, or a scalar
304
305
- false branch: a tuple, a field, of a scalar
305
- The mask can be directly a field of booleans (e.g. ` gtx.Field[[CellDim], bool] ` ) or an expression evaluating to this type (e.g. ` gtx.Field[[CellDim], float64] > 3 ` ).
306
+ The mask can be directly a field of booleans (e.g. ` gtx.Field[gtx.Dims [CellDim], bool] ` ) or an expression evaluating to this type (e.g. ` gtx.Field[[CellDim], float64] > 3 ` ).
306
307
The ` where ` builtin loops over each entry of the mask and returns values corresponding to the same indexes of either the true or the false branch.
307
308
In the case where the true and false branches are either fields or scalars, the resulting output will be a field including all dimensions from all inputs. For example:
308
309
@@ -312,8 +313,8 @@ result_where = gtx.as_field([CellDim, KDim], np.zeros(shape=grid_shape))
312
313
b = 6.0
313
314
314
315
@gtx.field_operator
315
- def conditional(mask: gtx.Field[[CellDim, KDim], bool], a: gtx.Field[[CellDim, KDim], float64], b: float
316
- ) -> gtx.Field[[CellDim, KDim], float64]:
316
+ def conditional(mask: gtx.Field[gtx.Dims [CellDim, KDim], bool], a: gtx.Field[gtx.Dims [CellDim, KDim], float64], b: float
317
+ ) -> gtx.Field[gtx.Dims [CellDim, KDim], float64]:
317
318
return where(mask, a, b)
318
319
319
320
conditional(mask, a, b, out=result_where, offset_provider={})
@@ -329,13 +330,13 @@ result_1 = gtx.as_field([CellDim, KDim], np.zeros(shape=grid_shape))
329
330
result_2 = gtx.as_field([CellDim, KDim], np.zeros(shape=grid_shape))
330
331
331
332
@gtx.field_operator
332
- def _conditional_tuple(mask: gtx.Field[[CellDim, KDim], bool], a: gtx.Field[[CellDim, KDim], float64], b: float
333
- ) -> tuple[gtx.Field[[CellDim, KDim], float64], gtx.Field[[CellDim, KDim], float64]]:
333
+ def _conditional_tuple(mask: gtx.Field[gtx.Dims [CellDim, KDim], bool], a: gtx.Field[gtx.Dims [CellDim, KDim], float64], b: float
334
+ ) -> tuple[gtx.Field[gtx.Dims [CellDim, KDim], float64], gtx.Field[gtx.Dims [CellDim, KDim], float64]]:
334
335
return where(mask, (a, b), (b, a))
335
336
336
337
@gtx.program
337
- def conditional_tuple(mask: gtx.Field[[CellDim, KDim], bool], a: gtx.Field[[CellDim, KDim], float64], b: float,
338
- result_1: gtx.Field[[CellDim, KDim], float64], result_2: gtx.Field[[CellDim, KDim], float64]
338
+ def conditional_tuple(mask: gtx.Field[gtx.Dims [CellDim, KDim], bool], a: gtx.Field[gtx.Dims [CellDim, KDim], float64], b: float,
339
+ result_1: gtx.Field[gtx.Dims [CellDim, KDim], float64], result_2: gtx.Field[gtx.Dims [CellDim, KDim], float64]
339
340
):
340
341
_conditional_tuple(mask, a, b, out=(result_1, result_2))
341
342
@@ -360,17 +361,17 @@ result_2 = gtx.as_field([CellDim, KDim], np.zeros(shape=grid_shape))
360
361
361
362
@gtx.field_operator
362
363
def _conditional_tuple_nested(
363
- mask: gtx.Field[[CellDim, KDim], bool], a: gtx.Field[[CellDim, KDim], float64], b: gtx.Field[[CellDim, KDim], float64], c: gtx.Field[[CellDim, KDim], float64], d: gtx.Field[[CellDim, KDim], float64]
364
+ mask: gtx.Field[gtx.Dims [CellDim, KDim], bool], a: gtx.Field[gtx.Dims [CellDim, KDim], float64], b: gtx.Field[gtx.Dims [CellDim, KDim], float64], c: gtx.Field[gtx.Dims [CellDim, KDim], float64], d: gtx.Field[gtx.Dims [CellDim, KDim], float64]
364
365
) -> tuple[
365
- tuple[gtx.Field[[CellDim, KDim], float64], gtx.Field[[CellDim, KDim], float64]],
366
- tuple[gtx.Field[[CellDim, KDim], float64], gtx.Field[[CellDim, KDim], float64]],
366
+ tuple[gtx.Field[gtx.Dims [CellDim, KDim], float64], gtx.Field[gtx.Dims [CellDim, KDim], float64]],
367
+ tuple[gtx.Field[gtx.Dims [CellDim, KDim], float64], gtx.Field[gtx.Dims [CellDim, KDim], float64]],
367
368
]:
368
369
return where(mask, ((a, b), (b, a)), ((c, d), (d, c)))
369
370
370
371
@gtx.program
371
372
def conditional_tuple_nested(
372
- mask: gtx.Field[[CellDim, KDim], bool], a: gtx.Field[[CellDim, KDim], float64], b: gtx.Field[[CellDim, KDim], float64], c: gtx.Field[[CellDim, KDim], float64], d: gtx.Field[[CellDim, KDim], float64],
373
- result_1: gtx.Field[[CellDim, KDim], float64], result_2: gtx.Field[[CellDim, KDim], float64]
373
+ mask: gtx.Field[gtx.Dims [CellDim, KDim], bool], a: gtx.Field[gtx.Dims [CellDim, KDim], float64], b: gtx.Field[gtx.Dims [CellDim, KDim], float64], c: gtx.Field[gtx.Dims [CellDim, KDim], float64], d: gtx.Field[gtx.Dims [CellDim, KDim], float64],
374
+ result_1: gtx.Field[gtx.Dims [CellDim, KDim], float64], result_2: gtx.Field[gtx.Dims [CellDim, KDim], float64]
374
375
):
375
376
_conditional_tuple_nested(mask, a, b, c, d, out=((result_1, result_2), (result_2, result_1)))
376
377
@@ -425,19 +426,19 @@ The second lines first creates a temporary field using `edge_differences(C2E)`,
425
426
426
427
``` {code-cell} ipython3
427
428
@gtx.field_operator
428
- def pseudo_lap(cells : gtx.Field[[CellDim], float64],
429
- edge_weights : gtx.Field[[CellDim, C2EDim], float64]) -> gtx.Field[[CellDim], float64]:
430
- edge_differences = cells(E2C[0]) - cells(E2C[1]) # type: gtx.Field[[EdgeDim], float64]
429
+ def pseudo_lap(cells : gtx.Field[gtx.Dims [CellDim], float64],
430
+ edge_weights : gtx.Field[gtx.Dims [CellDim, C2EDim], float64]) -> gtx.Field[gtx.Dims [CellDim], float64]:
431
+ edge_differences = cells(E2C[0]) - cells(E2C[1]) # type: gtx.Field[gtx.Dims [EdgeDim], float64]
431
432
return neighbor_sum(edge_differences(C2E) * edge_weights, axis=C2EDim)
432
433
```
433
434
434
435
The program itself is just a shallow wrapper over the ` pseudo_lap ` field operator. The significant part is how offset providers for both the edge-to-cell and cell-to-edge connectivities are supplied when the program is called:
435
436
436
437
``` {code-cell} ipython3
437
438
@gtx.program
438
- def run_pseudo_laplacian(cells : gtx.Field[[CellDim], float64],
439
- edge_weights : gtx.Field[[CellDim, C2EDim], float64],
440
- out : gtx.Field[[CellDim], float64]):
439
+ def run_pseudo_laplacian(cells : gtx.Field[gtx.Dims [CellDim], float64],
440
+ edge_weights : gtx.Field[gtx.Dims [CellDim, C2EDim], float64],
441
+ out : gtx.Field[gtx.Dims [CellDim], float64]):
441
442
pseudo_lap(cells, edge_weights, out=out)
442
443
443
444
result_pseudo_lap = gtx.as_field([CellDim], np.zeros(shape=(6,)))
@@ -454,7 +455,7 @@ As a closure, here is an example of chaining field operators, which is very simp
454
455
455
456
``` {code-cell} ipython3
456
457
@gtx.field_operator
457
- def pseudo_laplap(cells : gtx.Field[[CellDim], float64],
458
- edge_weights : gtx.Field[[CellDim, C2EDim], float64]) -> gtx.Field[[CellDim], float64]:
458
+ def pseudo_laplap(cells : gtx.Field[gtx.Dims [CellDim], float64],
459
+ edge_weights : gtx.Field[gtx.Dims [CellDim, C2EDim], float64]) -> gtx.Field[gtx.Dims [CellDim], float64]:
459
460
return pseudo_lap(pseudo_lap(cells, edge_weights), edge_weights)
460
461
```
0 commit comments