|
| 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. |
0 commit comments