Skip to content

Commit 4c7f22b

Browse files
committed
Merge branch '2846_rename_inlined_routines' of github.com:stfc/PSyclone into 2846_rename_inlined_routines
2 parents 3396a82 + 28c39d3 commit 4c7f22b

17 files changed

Lines changed: 494 additions & 236 deletions

changelog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
3) PR #3480 for #3478. Updates OMPParallelLoopTrans to correctly
2+
use the kwargs approach.
3+
4+
2) PR #3455 for #3170. Adds support for fields and operators with
5+
explicit real32 and real64 kinds.
6+
17
1) PR #3472 for #3471. Let the transformations get_options method
28
account for sub-transformation options.
39

config/psyclone.cfg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ precision_map = i_def: 4,
9191
r_solver: 4,
9292
r_tran: 8,
9393
r_bl: 8,
94-
r_um: 8
94+
r_um: 8,
95+
real64: 8,
96+
real32: 4
9597

9698
# Specify whether we generate code to perform runtime correctness checks.
9799
# Allowed values:

doc/user_guide/lfric.rst

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ Mixed Precision
432432

433433
The LFRic API supports the ability to specify the precision required
434434
by the model via precision variables. To make use of this, the code
435-
developer must declare scalars, arrays, fields and operators in the algorithm
435+
developer must declare scalars, arrays, fields and operators in the Algorithm
436436
layer with the required LFRic-supported precision. In the current
437437
implementation there are two supported precisions for ``REAL`` data and
438438
one each for ``INTEGER`` and ``LOGICAL`` data. The actual precision used in
@@ -471,6 +471,10 @@ associated kernel metadata description and their precision:
471471
+--------------------------+---------------------------------------+-----------+
472472
| R_TRAN_FIELD_TYPE | GH_FIELD, GH_REAL | R_TRAN |
473473
+--------------------------+---------------------------------------+-----------+
474+
| FIELD_REAL32_TYPE | GH_FIELD, GH_REAL | REAL32 |
475+
+--------------------------+---------------------------------------+-----------+
476+
| FIELD_REAL64_TYPE | GH_FIELD, GH_REAL | REAL64 |
477+
+--------------------------+---------------------------------------+-----------+
474478
| INTEGER_FIELD_TYPE | GH_FIELD, GH_INTEGER | I_DEF |
475479
+--------------------------+---------------------------------------+-----------+
476480
| OPERATOR_TYPE | GH_OPERATOR, GH_REAL | R_DEF |
@@ -479,13 +483,18 @@ associated kernel metadata description and their precision:
479483
+--------------------------+---------------------------------------+-----------+
480484
| R_TRAN_OPERATOR_TYPE | GH_OPERATOR, GH_REAL | R_TRAN |
481485
+--------------------------+---------------------------------------+-----------+
486+
| OPERATOR_REAL32_TYPE | GH_OPERATOR, GH_REAL | REAL32 |
487+
+--------------------------+---------------------------------------+-----------+
488+
| OPERATOR_REAL64_TYPE | GH_OPERATOR, GH_REAL | REAL64 |
489+
+--------------------------+---------------------------------------+-----------+
482490
| COLUMNWISE_OPERATOR_TYPE | GH_COLUMNWISE_OPERATOR, GH_REAL | R_SOLVER |
483491
+--------------------------+---------------------------------------+-----------+
484492

485493
As can be seen from the above table, the kernel metadata does not
486494
capture all of the precision options. For example, from the metadata
487495
it is not possible to determine whether a ``REAL`` scalar, ``REAL`` field
488-
or ``REAL`` operator has precision ``R_DEF``, ``R_SOLVER`` or ``R_TRAN``.
496+
or ``REAL`` operator has precision ``R_DEF``, ``R_SOLVER``, ``R_TRAN``
497+
or one of the Fortran intrinsic precisions (``REAL32``, ``REAL64``).
489498

490499
If a scalar, array, field, or operator is specified with a particular
491500
precision in the algorithm layer then any associated kernels that it
@@ -601,6 +610,10 @@ outlined in the table below:
601610
+-------------------------+------------------+--------------+
602611
| ``r_tran_field_type`` | ``real`` | ``r_tran`` |
603612
+-------------------------+------------------+--------------+
613+
| ``field_real32_type`` | ``real`` | ``real32`` |
614+
+-------------------------+------------------+--------------+
615+
| ``field_real64_type`` | ``real`` | ``real64`` |
616+
+-------------------------+------------------+--------------+
604617
| ``integer_field_type`` | ``integer`` | ``i_def`` |
605618
+-------------------------+------------------+--------------+
606619

@@ -701,7 +714,8 @@ a message that indicates the problem.
701714
| Fortran Datatype | Supported Precision |
702715
+==================+==========================+
703716
| ``real`` | ``r_def``, ``r_bl``, |
704-
| | ``r_solver``, ``r_tran`` |
717+
| | ``r_solver``, ``r_tran``,|
718+
| | ``real32``, ``real64`` |
705719
+------------------+--------------------------+
706720
| ``integer`` | ``i_def`` |
707721
+------------------+--------------------------+
@@ -731,6 +745,10 @@ outlined in the table below:
731745
+----------------------------+------------------+--------------+
732746
| ``r_tran_operator_type`` | ``real`` | ``r_tran`` |
733747
+----------------------------+------------------+--------------+
748+
| ``operator_real32_type`` | ``real`` | ``real32`` |
749+
+----------------------------+------------------+--------------+
750+
| ``operator_real64_type`` | ``real`` | ``real64`` |
751+
+----------------------------+------------------+--------------+
734752

735753
.. _lfric-mixed-precision-cma-operators:
736754

src/psyclone/domain/lfric/lfric_constants.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,11 @@ def __init__(self) -> None:
384384

385385
# ---------- Infrastructure module maps -------------------------------
386386

387+
# Those kind symbols used in LFRic that are actually
388+
# Fortran intrinsics (and thus don't come from constants_mod).
389+
LFRicConstants.INTRINSIC_KINDS = ("real32", "real64")
390+
LFRicConstants.FORTRAN_ISO_MOD_NAME = "iso_fortran_env"
391+
387392
# Dictionary allowing us to look-up the name of the Fortran module,
388393
# type and proxy-type associated with each LFRic data structure type.
389394
# Data structure type mandates its proxy name, Fortran intrinsic type
@@ -420,6 +425,18 @@ def __init__(self) -> None:
420425
"proxy_type": "r_bl_field_proxy_type",
421426
"intrinsic": "real",
422427
"kind": "r_bl"},
428+
# 'real'-valued field with explicit 32-bit precision
429+
"r_32_field": {"module": "field_real32_mod",
430+
"type": "field_real32_type",
431+
"proxy_type": "field_real32_proxy_type",
432+
"intrinsic": "real",
433+
"kind": "real32"},
434+
# 'real'-valued field with explicit 64-bit precision
435+
"r_64_field": {"module": "field_real64_mod",
436+
"type": "field_real64_type",
437+
"proxy_type": "field_real64_proxy_type",
438+
"intrinsic": "real",
439+
"kind": "real64"},
423440
# 'integer'-valued field with data of kind 'i_def'
424441
"integer_field": {"module": "integer_field_mod",
425442
"type": "integer_field_type",
@@ -432,6 +449,18 @@ def __init__(self) -> None:
432449
"proxy_type": "operator_proxy_type",
433450
"intrinsic": "real",
434451
"kind": "r_def"},
452+
# 'real'-valued operator with real32 data
453+
"r_32_operator": {"module": "operator_real32_mod",
454+
"type": "operator_real32_type",
455+
"proxy_type": "operator_real32_proxy_type",
456+
"intrinsic": "real",
457+
"kind": "real32"},
458+
# 'real'-valued operator with real32 data
459+
"r_64_operator": {"module": "operator_real64_mod",
460+
"type": "operator_real64_type",
461+
"proxy_type": "operator_real64_proxy_type",
462+
"intrinsic": "real",
463+
"kind": "real64"},
435464
# 'real'-valued operator with data of kind 'r_solver'
436465
"r_solver_operator": {
437466
"module": "r_solver_operator_mod",
@@ -454,6 +483,13 @@ def __init__(self) -> None:
454483
"intrinsic": "real",
455484
"kind": "r_solver"}}
456485

486+
# Construct a reverse map from type to the name of the LFRic
487+
# data type for all real field types.
488+
LFRicConstants.REAL_DATA_TYPE_RMAP = {}
489+
for key, value in LFRicConstants.DATA_TYPE_MAP.items():
490+
if value["intrinsic"] == "real" and "field" in key:
491+
LFRicConstants.REAL_DATA_TYPE_RMAP[value["type"]] = key
492+
457493
# Mapping from a vector type used in the algorithm-layer to
458494
# the actual type used in the PSy-layer.
459495
LFRicConstants.FIELD_VECTOR_TO_FIELD_MAP = {

src/psyclone/domain/lfric/lfric_driver_creator.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def __init__(self, region_name: Optional[tuple[str, str]] = None) -> None:
7272
# -------------------------------------------------------------------------
7373
def handle_precision_symbols(self, symbol_table: SymbolTable) -> None:
7474
'''This function adds an import of the various precision
75-
symbols used by LFRic from the constants_mod module.
75+
symbols used by LFRic from the constants_mod module. It also adds
76+
imports of the real32 and real64 intrinsic kinds.
7677
7778
:param symbol_table: the symbol table to which the precision symbols
7879
must be added.
@@ -87,15 +88,27 @@ def handle_precision_symbols(self, symbol_table: SymbolTable) -> None:
8788
# does not exist at all in LFRic, but is still in LFRic's psyclone.cfg
8889
# file. TODO #2018 and
8990
# https://code.metoffice.gov.uk/trac/lfric/ticket/4674
91+
names_to_skip = ["r_quad", "r_phys"] + list(const.INTRINSIC_KINDS)
9092
api_config = Config.get().api_conf("lfric")
9193
all_precisions = [name for name in api_config.precision_map
92-
if name not in ["r_quad", "r_phys"]]
94+
if name not in names_to_skip]
9395
for prec_name in all_precisions:
9496
symbol_table.new_symbol(prec_name,
9597
tag=f"{prec_name}@{mod_name}",
9698
symbol_type=DataSymbol,
9799
datatype=ScalarType.integer_type(),
98100
interface=ImportInterface(constant_mod))
101+
# Intrinsic kind symbols are imported into constants_mod but are
102+
# private to it so have to be handled separately.
103+
iso_mod = ContainerSymbol(const.FORTRAN_ISO_MOD_NAME,
104+
is_intrinsic=True)
105+
symbol_table.add(iso_mod)
106+
for prec_name in const.INTRINSIC_KINDS:
107+
symbol_table.new_symbol(prec_name,
108+
tag=f"{prec_name}@{iso_mod.name}",
109+
symbol_type=DataSymbol,
110+
datatype=ScalarType.integer_type(),
111+
interface=ImportInterface(iso_mod))
99112

100113
# -------------------------------------------------------------------------
101114
def verify_and_cleanup_psyir(self, extract_region: Node) -> None:

src/psyclone/domain/lfric/lfric_types.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,9 @@ def add_precision_symbol(table: SymbolTable,
608608
table then add it. Also ensure that the Container symbol from which it
609609
is imported is in the table.
610610
611+
Also supports Fortran intrinsic kinds imported from the
612+
iso_fortran_env module.
613+
611614
:param table: the symbol table to use.
612615
:param name: name of the LFRic precision symbol to add to table.
613616
@@ -624,7 +627,13 @@ def add_precision_symbol(table: SymbolTable,
624627
raise ValueError(f"'{name}' is not a recognised LFRic precision.")
625628

626629
const = LFRicConstants()
627-
mod_name = const.UTILITIES_MOD_MAP["constants"]["module"]
630+
if name in const.INTRINSIC_KINDS:
631+
# This is an intrinsic precision (e.g. real64)
632+
mod_name = const.FORTRAN_ISO_MOD_NAME
633+
is_intrinsic = True
634+
else:
635+
mod_name = const.UTILITIES_MOD_MAP["constants"]["module"]
636+
is_intrinsic = False
628637

629638
sym = table.lookup(name, otherwise=None)
630639

@@ -638,7 +647,8 @@ def add_precision_symbol(table: SymbolTable,
638647
return sym
639648

640649
constants_mod = table.find_or_create(mod_name,
641-
symbol_type=ContainerSymbol)
650+
symbol_type=ContainerSymbol,
651+
is_intrinsic=is_intrinsic)
642652
sym = DataSymbol(name, ScalarType.integer_type(),
643653
interface=ImportInterface(constants_mod))
644654
table.add(sym)

0 commit comments

Comments
 (0)