Skip to content

Commit 5624c37

Browse files
Add icon-liskov DSL Preprocessor (#117)
Introduces icon_liskov a preprocessor which enables the generation of integration code between ICON and Gt4Py stencils in Icon4Py.
1 parent 686e5aa commit 5624c37

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4129
-17
lines changed

.flake8

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,31 @@
33
max-line-length = 100
44
max-complexity = 15
55
doctests = true
6-
ignore =
7-
B008 # Do not perform function calls in argument defaults
8-
D1 # Public code object needs docstring
9-
DAR # Disable dargling errors by default
10-
E203 # Whitespace before ':' (black formatter breaks this sometimes)
11-
E501 # Line too long (using Bugbear's B950 warning)
12-
W503 # Line break occurred before a binary operator
6+
extend-ignore =
7+
# Do not perform function calls in argument defaults
8+
B008,
9+
# Public code object needs docstring
10+
D1,
11+
# Disable dargling errors by default
12+
DAR,
13+
# Whitespace before ':' (black formatter breaks this sometimes)
14+
E203,
15+
# Line too long (using Bugbear's B950 warning)
16+
E501,
17+
# Line break occurred before a binary operator
18+
W503
1319

1420
exclude =
15-
.eggs
16-
.gt_cache
17-
.ipynb_checkpoints
18-
.tox
19-
_local_
20-
build
21-
dist
22-
docs
23-
_external_src
24-
tests/_disabled
21+
.eggs,
22+
.gt_cache,
23+
.ipynb_checkpoints,
24+
.tox,
25+
_local_,
26+
build,
27+
dist,
28+
docs,
29+
_external_src,
30+
tests/_disabled,
2531
setup.py
2632

2733
rst-roles =

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ repos:
3737
# args: [--remove]
3838
- id: name-tests-test
3939
args: [--pytest-test-first]
40+
exclude: ^liskov/tests/samples
4041

4142
- repo: https://gitlab.com/bmares/check-json5
4243
rev: v1.0.0

liskov/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# icon4py-liskov
2+
3+
A preprocessor that facilitates integration of gt4py code into the ICON model.
4+
5+
## Installation
6+
7+
To install the icon4py-liskov package, follow the instructions in the `README.md` file located in the root of the repository.
8+
9+
## Description
10+
11+
The icon4py-liskov package includes the `icon_liskov` CLI tool which takes a fortran file as input and processes it with the ICON-Liskov DSL Preprocessor. This preprocessor adds the necessary `USE` statements and generates OpenACC `DATA CREATE` statements and declares DSL input/output fields based on directives in the input file. The preprocessor also processes stencils defined in the input file using the `START STENCIL` and `END STENCIL` directives, inserting the necessary code to run the stencils and adding nvtx profile statements if specified with the `--profile` flag.
12+
13+
### Usage
14+
15+
To use the `icon_liskov` tool, run the following command:
16+
17+
```bash
18+
icon_liskov <input_filepath> <output_filepath> [--profile]
19+
```
20+
21+
Where `input_filepath` is the path to the input file to be processed, and `output_filepath` is the path to the output file. The optional `--profile` flag adds nvtx profile statements to the stencils.
22+
23+
### Preprocessor directives
24+
25+
The ICON-Liskov DSL Preprocessor supports the following directives:
26+
27+
#### `!$DSL IMPORTS()`
28+
29+
This directive generates the necessary `USE` statements to import the Fortran to C interfaces.
30+
31+
#### `!$DSL START CREATE()`
32+
33+
This directive generates an OpenACC `DATA CREATE` statement for all output fields used in each DSL (icon4py) stencil.
34+
35+
#### `!$DSL END CREATE()`
36+
37+
This directive generates an OpenACC `END DATA` statement which is neccessary to close the OpenACC data region.
38+
39+
#### `!$DSL DECLARE()`
40+
41+
This directive is used to declare all DSL input/output fields. The required arguments are the field name and its associated dimensions. For example:
42+
43+
```fortran
44+
!$DSL DECLARE(vn=(nproma, p_patch%nlev, p_patch%nblks_e))
45+
```
46+
47+
will generate the following code:
48+
49+
```fortran
50+
! DSL INPUT / OUTPUT FIELDS
51+
REAL(wp), DIMENSION((nproma, p_patch%nlev, p_patch%nblks_e)) :: vn_before
52+
```
53+
54+
Furthermore, this directive also takes two optional keyword arguments. `type` takes a string which will be used to fill in the type of the declared field, for example `type=LOGICAL`. `suffix` takes a string which will be used as the suffix of the field e.g. `suffix=dsl`, by default the suffix is `before`.
55+
56+
#### `!$DSL START STENCIL()`
57+
58+
This directive denotes the start of a stencil. Required arguments are `name`, `vertical_lower`, `vertical_upper`, `horizontal_lower`, `horizontal_upper`. The value for `name` must correspond to a stencil found in one of the stencil modules inside `icon4py`, and all fields defined in the directive must correspond to the fields defined in the respective icon4py stencil. Optionally, absolute and relative tolerances for the output fields can also be set using the `_tol` or `_abs` suffixes respectively. An example call looks like this:
59+
60+
```fortran
61+
!$DSL START STENCIL(name=mo_nh_diffusion_stencil_06; &
62+
!$DSL z_nabla2_e=z_nabla2_e(:,:,1); area_edge=p_patch%edges%area_edge(:,1); &
63+
!$DSL fac_bdydiff_v=fac_bdydiff_v; vn=p_nh_prog%vn(:,:,1); vn_abs_tol=1e-21_wp; &
64+
!$DSL vertical_lower=1; vertical_upper=nlev; &
65+
!$DSL horizontal_lower=i_startidx; horizontal_upper=i_endidx)
66+
```
67+
68+
In addition, other optional keyword arguments are the following:
69+
70+
- `accpresent`: Takes a boolean string input, and controls the default data-sharing behavior for variables used in the OpenACC parallel region. Setting the flag to true will cause all variables to be assumed present on the device by default (`DEFAULT(PRESENT)`), and no explicit data-sharing attributes need to be specified. Setting it to false will require explicit data-sharing attributes for every variable used in the parallel region (`DEFAULT(NONE)`). By default it is set to false.<br><br>
71+
72+
- `mergecopy`: Takes a boolean string input. When set to True consecutive before field copy regions of stencils that have the mergecopy flag set to True are combined into a single before field copy region with a new name created by concatenating the names of the merged stencil regions. This is useful when there are consecutive stencils. By default it is set to false.<br><br>
73+
74+
- `copies`: Takes a boolean string input, and controls whether before field copies should be made or not. If set to False only the `#ifdef __DSL_VERIFY` directive is generated. Defaults to true.<br><br>
75+
76+
#### `!$DSL END STENCIL()`
77+
78+
This directive denotes the end of a stencil. The required argument is `name`, which must match the name of the preceding `START STENCIL` directive.
79+
80+
Together, the `START STENCIL` and `END STENCIL` directives result in the following generated code at the start and end of a stencil respectively.
81+
82+
```fortran
83+
#ifdef __DSL_VERIFY
84+
!$ACC PARALLEL IF( i_am_accel_node .AND. acc_on ) DEFAULT(NONE) ASYNC(1)
85+
vn_before(:, :, :) = vn(:, :, :)
86+
!$ACC END PARALLEL
87+
```
88+
89+
```fortran
90+
call nvtxEndRange()
91+
#endif
92+
call wrap_run_mo_nh_diffusion_stencil_06( &
93+
z_nabla2_e=z_nabla2_e(:, :, 1), &
94+
area_edge=p_patch%edges%area_edge(:, 1), &
95+
fac_bdydiff_v=fac_bdydiff_v, &
96+
vn=p_nh_prog%vn(:, :, 1), &
97+
vn_before=vn_before(:, :, 1), &
98+
vn_abs_tol=1e-21_wp, &
99+
vertical_lower=1, &
100+
vertical_upper=nlev, &
101+
horizontal_lower=i_startidx, &
102+
horizontal_upper=i_endidx
103+
)
104+
```
105+
106+
Additionally, there are the following keyword arguments:
107+
108+
- `noendif`: Takes a boolean string input and controls whether an `#endif` is generated or not. Defaults to false.<br><br>
109+
110+
- `noprofile`: Takes a boolean string input and controls whether a nvtx end profile directive is generated or not. Defaults to false.<br><br>
111+
112+
#### `!$DSL INSERT()`
113+
114+
This directive allows the user to generate any text that is placed between the parentheses. This is useful for situations where custom code generation is necessary.
115+
116+
#### `!$DSL START PROFILE()`
117+
118+
This directive allows generating an nvtx start profile data statement, and takes the stencil `name` as an argument.
119+
120+
#### `!$DSL END PROFILE()`
121+
122+
This directive allows generating an nvtx end profile statement.
123+
124+
#### `!$DSL ENDIF()`
125+
126+
This directive generates an `#endif` statement.

liskov/requirements-dev.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-r ../base-requirements-dev.txt
2+
-e ../common
3+
-e .

liskov/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-r ../base-requirements.txt
2+
../common
3+
.

liskov/setup.cfg

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# This file is mainly used to configure package creation with setuptools.
2+
# Documentation:
3+
# http://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files
4+
#
5+
[metadata]
6+
name = icon4py_liskov
7+
description = ICON preprocessor to integrate Gt4Py code.
8+
long_description = file: README.md
9+
long_description_content_type = text/markdown
10+
url = https://github.com/C2SM/icon4py
11+
author = ETH Zurich
12+
author_email = gridtools@cscs.ch
13+
license = gpl3
14+
license_files = LICENSE
15+
platforms = Linux, Mac
16+
classifiers =
17+
Development Status :: 3 - Alpha
18+
Intended Audience :: Science/Research
19+
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
20+
Operating System :: POSIX
21+
Programming Language :: Python
22+
Programming Language :: Python :: 3
23+
Programming Language :: Python :: 3 :: Only
24+
Programming Language :: Python :: 3.10
25+
Programming Language :: Python :: Implementation :: CPython
26+
Topic :: Scientific/Engineering :: Atmospheric Science
27+
Topic :: Scientific/Engineering :: Mathematics
28+
Topic :: Scientific/Engineering :: Physics
29+
project_urls =
30+
Source Code = https://github.com/GridTools/gt4py
31+
32+
[options]
33+
packages = find_namespace:
34+
install_requires =
35+
icon4py-common
36+
37+
python_requires = >=3.10
38+
package_dir =
39+
= src
40+
zip_safe = False
41+
42+
[options.package_data]
43+
# References:
44+
# https://setuptools.pypa.io/en/latest/userguide/datafiles.html
45+
# https://github.com/abravalheri/experiment-setuptools-package-data
46+
* = *.md, *.rst, *.toml, *.txt, py.typed
47+
48+
[options.packages.find]
49+
where = src
50+
exclude =
51+
tests
52+
53+
[options.entry_points]
54+
console_scripts =
55+
icon_liskov = icon4py.liskov.cli:main

liskov/setup.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# ICON4Py - ICON inspired code in Python and GT4Py
2+
#
3+
# Copyright (c) 2022, ETH Zurich and MeteoSwiss
4+
# All rights reserved.
5+
#
6+
# This file is free software: you can redistribute it and/or modify it under
7+
# the terms of the GNU General Public License as published by the
8+
# Free Software Foundation, either version 3 of the License, or any later
9+
# version. See the LICENSE.txt file at the top-level directory of this
10+
# distribution for a copy of the license or check <https://www.gnu.org/licenses/>.
11+
#
12+
# SPDX-License-Identifier: GPL-3.0-or-later
13+
14+
from setuptools import setup
15+
16+
17+
if __name__ == "__main__":
18+
setup()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ICON4Py - ICON inspired code in Python and GT4Py
2+
#
3+
# Copyright (c) 2022, ETH Zurich and MeteoSwiss
4+
# All rights reserved.
5+
#
6+
# This file is free software: you can redistribute it and/or modify it under
7+
# the terms of the GNU General Public License as published by the
8+
# Free Software Foundation, either version 3 of the License, or any later
9+
# version. See the LICENSE.txt file at the top-level directory of this
10+
# distribution for a copy of the license or check <https://www.gnu.org/licenses/>.
11+
#
12+
# SPDX-License-Identifier: GPL-3.0-or-later

liskov/src/icon4py/liskov/cli.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# ICON4Py - ICON inspired code in Python and GT4Py
2+
#
3+
# Copyright (c) 2022, ETH Zurich and MeteoSwiss
4+
# All rights reserved.
5+
#
6+
# This file is free software: you can redistribute it and/or modify it under
7+
# the terms of the GNU General Public License as published by the
8+
# Free Software Foundation, either version 3 of the License, or any later
9+
# version. See the LICENSE.txt file at the top-level directory of this
10+
# distribution for a copy of the license or check <https://www.gnu.org/licenses/>.
11+
#
12+
# SPDX-License-Identifier: GPL-3.0-or-later
13+
14+
import pathlib
15+
16+
import click
17+
18+
from icon4py.liskov.logger import setup_logger
19+
from icon4py.liskov.pipeline import (
20+
load_gt4py_stencils,
21+
parse_fortran_file,
22+
run_code_generation,
23+
)
24+
25+
26+
logger = setup_logger(__name__)
27+
28+
29+
@click.command("icon_liskov")
30+
@click.argument(
31+
"input_filepath",
32+
type=click.Path(
33+
exists=True, dir_okay=False, resolve_path=True, path_type=pathlib.Path
34+
),
35+
)
36+
@click.argument(
37+
"output_filepath",
38+
type=click.Path(dir_okay=False, resolve_path=True, path_type=pathlib.Path),
39+
)
40+
@click.option(
41+
"--profile", "-p", is_flag=True, help="Add nvtx profile statements to stencils."
42+
)
43+
def main(
44+
input_filepath: pathlib.Path, output_filepath: pathlib.Path, profile: bool
45+
) -> None:
46+
"""Command line interface for interacting with the ICON-Liskov DSL Preprocessor.
47+
48+
Usage:
49+
icon_liskov <input_filepath> <output_filepath> [--profile]
50+
51+
Options:
52+
-p --profile Add nvtx profile statements to stencils.
53+
54+
Arguments:
55+
input_filepath Path to the input file to process.
56+
output_filepath Path to the output file to generate.
57+
"""
58+
parsed = parse_fortran_file(input_filepath)
59+
parsed_checked = load_gt4py_stencils(parsed)
60+
run_code_generation(parsed_checked, input_filepath, output_filepath, profile)
61+
62+
63+
if __name__ == "__main__":
64+
main()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# ICON4Py - ICON inspired code in Python and GT4Py
2+
#
3+
# Copyright (c) 2022, ETH Zurich and MeteoSwiss
4+
# All rights reserved.
5+
#
6+
# This file is free software: you can redistribute it and/or modify it under
7+
# the terms of the GNU General Public License as published by the
8+
# Free Software Foundation, either version 3 of the License, or any later
9+
# version. See the LICENSE.txt file at the top-level directory of this
10+
# distribution for a copy of the license or check <https://www.gnu.org/licenses/>.
11+
#
12+
# SPDX-License-Identifier: GPL-3.0-or-later
13+
14+
# required import for CheckForDirectiveClasses metaclass
15+
import icon4py.liskov.parsing.types as ts # noqa: F401

0 commit comments

Comments
 (0)