From 5a973860d9544b6dad4fac4e46b5fc4434d76733 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Mon, 11 Nov 2024 16:52:28 +0000 Subject: [PATCH 01/16] #1280 Add autodoc-skip-member handler to conf.py of RG --- doc/reference_guide/source/conf.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/reference_guide/source/conf.py b/doc/reference_guide/source/conf.py index 2f1e8cf8db..28c5421f75 100644 --- a/doc/reference_guide/source/conf.py +++ b/doc/reference_guide/source/conf.py @@ -204,9 +204,25 @@ epub_exclude_files = ['search.html'] -# -- Extension configuration ------------------------------------------------- +# -- Autodoc configuration --------------------------------------------------- -# Generate the Doxygen documentation +import collections + + +def remove_namedtuple_attrib_docstring(app, what, name, obj, skip, options): + if type(obj) is collections._tuplegetter: + return True + if "Operator" in name: + print(f"ARPDBG: skipping '{name}'") + return True + return skip + + +def setup(app): + app.connect('autodoc-skip-member', remove_namedtuple_attrib_docstring) + + +# -- Generate the Doxygen documentation -------------------------------------- subprocess.call('cd ..; doxygen doxygen.config', shell=True) # If we want to completely replace the Sphinx-generated documentation # with that constructed by Doxygen then we uncomment the line below. From 40228efa7a528819043d670844ba8e69d04e46b1 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Mon, 11 Nov 2024 16:53:00 +0000 Subject: [PATCH 02/16] #1280 comment-out __all__ from module __init__.py files --- src/psyclone/domain/lfric/__init__.py | 54 ++++++------- .../domain/lfric/algorithm/__init__.py | 15 ++-- src/psyclone/psyir/symbols/__init__.py | 81 ++++++++++--------- src/psyclone/psyir/symbols/datatypes.py | 9 ++- .../psyir/transformations/__init__.py | 79 +++++++++--------- 5 files changed, 121 insertions(+), 117 deletions(-) diff --git a/src/psyclone/domain/lfric/__init__.py b/src/psyclone/domain/lfric/__init__.py index 734bebf824..c8c468b846 100644 --- a/src/psyclone/domain/lfric/__init__.py +++ b/src/psyclone/domain/lfric/__init__.py @@ -76,30 +76,30 @@ from psyclone.domain.lfric.lfric_dofmaps import LFRicDofmaps from psyclone.domain.lfric.lfric_stencils import LFRicStencils - -__all__ = [ - 'ArgOrdering', - 'FunctionSpace', - 'KernCallAccArgList', - 'KernCallArgList', - 'KernelInterface', - 'KernStubArgList', - 'LFRicArgDescriptor', - 'LFRicCellIterators', - 'LFRicCollection', - 'LFRicConstants', - 'LFRicDofmaps', - 'LFRicExtractDriverCreator', - 'LFRicFields', - 'LFRicInvoke', - 'LFRicInvokes', - 'LFRicInvokeSchedule', - 'LFRicKern', - 'LFRicKernCallFactory', - 'LFRicKernMetadata', - 'LFRicLoop', - 'LFRicLoopBounds', - 'LFRicRunTimeChecks', - 'LFRicScalarArgs', - 'LFRicStencils', - 'LFRicSymbolTable'] +if False: + __all__ = [ + 'ArgOrdering', + 'FunctionSpace', + 'KernCallAccArgList', + 'KernCallArgList', + 'KernelInterface', + 'KernStubArgList', + 'LFRicArgDescriptor', + 'LFRicCellIterators', + 'LFRicCollection', + 'LFRicConstants', + 'LFRicDofmaps', + 'LFRicExtractDriverCreator', + 'LFRicFields', + 'LFRicInvoke', + 'LFRicInvokes', + 'LFRicInvokeSchedule', + 'LFRicKern', + 'LFRicKernCallFactory', + 'LFRicKernMetadata', + 'LFRicLoop', + 'LFRicLoopBounds', + 'LFRicRunTimeChecks', + 'LFRicScalarArgs', + 'LFRicStencils', + 'LFRicSymbolTable'] diff --git a/src/psyclone/domain/lfric/algorithm/__init__.py b/src/psyclone/domain/lfric/algorithm/__init__.py index df43cc9e86..9f993abf0f 100644 --- a/src/psyclone/domain/lfric/algorithm/__init__.py +++ b/src/psyclone/domain/lfric/algorithm/__init__.py @@ -45,10 +45,11 @@ # For AutoAPI documentation generation. -__all__ = [ - 'LFRicAlg', - 'LFRicAlgorithmInvokeCall', - 'LFRicBuiltinFunctor', - 'LFRicBuiltinFunctorFactory', - 'LFRicFunctor', - 'LFRicKernelFunctor'] +if False: + __all__ = [ + 'LFRicAlg', + 'LFRicAlgorithmInvokeCall', + 'LFRicBuiltinFunctor', + 'LFRicBuiltinFunctorFactory', + 'LFRicFunctor', + 'LFRicKernelFunctor'] diff --git a/src/psyclone/psyir/symbols/__init__.py b/src/psyclone/psyir/symbols/__init__.py index 9e93f39fbb..c01d4bd7cc 100644 --- a/src/psyclone/psyir/symbols/__init__.py +++ b/src/psyclone/psyir/symbols/__init__.py @@ -60,43 +60,44 @@ UnsupportedType, UnsupportedFortranType) # For auto documentation generation. -__all__ = ['ArgumentInterface', - 'ArrayType', - 'AutomaticInterface', - 'BOOLEAN_TYPE', - 'CHARACTER_TYPE', - 'CommonBlockInterface', - 'ContainerSymbol', - 'DataSymbol', - 'DataType', - 'DataTypeSymbol', - 'DefaultModuleInterface', - 'GenericInterfaceSymbol', - 'ImportInterface', - 'INTEGER_TYPE', - 'INTEGER_SINGLE_TYPE', - 'INTEGER_DOUBLE_TYPE', - 'INTEGER4_TYPE', - 'INTEGER8_TYPE', - 'IntrinsicSymbol', - 'NoType', - 'PreprocessorInterface', - 'REAL_TYPE', - 'REAL_SINGLE_TYPE', - 'REAL_DOUBLE_TYPE', - 'REAL4_TYPE', - 'REAL8_TYPE', - 'RoutineSymbol', - 'ScalarType', - 'StaticInterface', - 'StructureType', - 'Symbol', - 'SymbolError', - 'SymbolTable', - 'TYPE_MAP_TO_PYTHON', - 'TypedSymbol', - 'UnsupportedFortranType', - 'UnknownInterface', - 'UnsupportedType', - 'UnresolvedInterface', - 'UnresolvedType'] +#__all__ = ['ArgumentInterface', +# 'ArrayType', +# 'AutomaticInterface', +# 'BOOLEAN_TYPE', +# 'CHARACTER_TYPE', +# 'CommonBlockInterface', +# 'ContainerSymbol', +# 'DataSymbol', +# 'DataType', +# 'DataTypeSymbol', +# 'DefaultModuleInterface', +# 'GenericInterfaceSymbol', +# 'ImportInterface', +# 'INTEGER_TYPE', +# 'INTEGER_SINGLE_TYPE', +# 'INTEGER_DOUBLE_TYPE', +# 'INTEGER4_TYPE', +# 'INTEGER8_TYPE', +# 'IntrinsicSymbol', +# 'NoType', +# 'PreprocessorInterface', +# 'REAL_TYPE', +# 'REAL_SINGLE_TYPE', +# 'REAL_DOUBLE_TYPE', +# 'REAL4_TYPE', +# 'REAL8_TYPE', +# 'RoutineSymbol', +# 'ScalarType', +# 'StaticInterface', +# 'StructureType', +# 'Symbol', +# 'SymbolError', +# 'SymbolTable', +# 'TYPE_MAP_TO_PYTHON', +# 'TypedSymbol', +# 'UnsupportedFortranType', +# 'UnknownInterface', +# 'UnsupportedType', +# 'UnresolvedInterface', +# 'UnresolvedType'] +# diff --git a/src/psyclone/psyir/symbols/datatypes.py b/src/psyclone/psyir/symbols/datatypes.py index 6815aa37bf..d0b1bd05a0 100644 --- a/src/psyclone/psyir/symbols/datatypes.py +++ b/src/psyclone/psyir/symbols/datatypes.py @@ -1051,10 +1051,11 @@ def replace_symbols_using(self, table): # Mapping from PSyIR scalar data types to intrinsic Python types # ignoring precision. -TYPE_MAP_TO_PYTHON = {ScalarType.Intrinsic.INTEGER: int, - ScalarType.Intrinsic.CHARACTER: str, - ScalarType.Intrinsic.BOOLEAN: bool, - ScalarType.Intrinsic.REAL: float} +TYPE_MAP_TO_PYTHON = { + ScalarType.Intrinsic.INTEGER: int, + ScalarType.Intrinsic.CHARACTER: str, + ScalarType.Intrinsic.BOOLEAN: bool, + ScalarType.Intrinsic.REAL: float} # For automatic documentation generation diff --git a/src/psyclone/psyir/transformations/__init__.py b/src/psyclone/psyir/transformations/__init__.py index 60b55c1449..6bd87580c4 100644 --- a/src/psyclone/psyir/transformations/__init__.py +++ b/src/psyclone/psyir/transformations/__init__.py @@ -107,42 +107,43 @@ # For AutoAPI documentation generation -__all__ = ['ACCKernelsTrans', - 'ACCUpdateTrans', - 'AllArrayAccess2LoopTrans', - 'ArrayAccess2LoopTrans', - 'ArrayAssignment2LoopsTrans', - 'ChunkLoopTrans', - 'ExtractTrans', - 'FoldConditionalReturnExpressionsTrans', - 'HoistLocalArraysTrans', - 'HoistLoopBoundExprTrans', - 'HoistTrans', - 'InlineTrans', - 'Abs2CodeTrans', - 'DotProduct2CodeTrans', - 'Matmul2CodeTrans', - 'Max2CodeTrans', - 'Min2CodeTrans', - 'Sign2CodeTrans', - 'Sum2LoopTrans', - 'LoopFuseTrans', - 'LoopSwapTrans', - 'LoopTiling2DTrans', - 'LoopTrans', - 'Maxval2LoopTrans', - 'Minval2LoopTrans', - 'OMPLoopTrans', - 'OMPTargetTrans', - 'OMPTaskTrans', - 'OMPTaskwaitTrans', - 'ParallelLoopTrans', - 'Product2LoopTrans', - 'ProfileTrans', - 'PSyDataTrans', - 'ReadOnlyVerifyTrans', - 'Reference2ArrayRangeTrans', - 'RegionTrans', - 'ReplaceInductionVariablesTrans', - 'TransformationError', - 'ValueRangeCheckTrans'] +if False: + __all__ = ['ACCKernelsTrans', + 'ACCUpdateTrans', + 'AllArrayAccess2LoopTrans', + 'ArrayAccess2LoopTrans', + 'ArrayAssignment2LoopsTrans', + 'ChunkLoopTrans', + 'ExtractTrans', + 'FoldConditionalReturnExpressionsTrans', + 'HoistLocalArraysTrans', + 'HoistLoopBoundExprTrans', + 'HoistTrans', + 'InlineTrans', + 'Abs2CodeTrans', + 'DotProduct2CodeTrans', + 'Matmul2CodeTrans', + 'Max2CodeTrans', + 'Min2CodeTrans', + 'Sign2CodeTrans', + 'Sum2LoopTrans', + 'LoopFuseTrans', + 'LoopSwapTrans', + 'LoopTiling2DTrans', + 'LoopTrans', + 'Maxval2LoopTrans', + 'Minval2LoopTrans', + 'OMPLoopTrans', + 'OMPTargetTrans', + 'OMPTaskTrans', + 'OMPTaskwaitTrans', + 'ParallelLoopTrans', + 'Product2LoopTrans', + 'ProfileTrans', + 'PSyDataTrans', + 'ReadOnlyVerifyTrans', + 'Reference2ArrayRangeTrans', + 'RegionTrans', + 'ReplaceInductionVariablesTrans', + 'TransformationError', + 'ValueRangeCheckTrans'] From 10fc0d55771b9a8244c8c1af794c15127ad2cac1 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 12 Nov 2024 10:12:08 +0000 Subject: [PATCH 03/16] #1280 put back __all__ in domain/lfric/__init__.py and change namedtuple to dataclass --- src/psyclone/domain/lfric/__init__.py | 53 +++++++++---------- .../domain/lfric/kern_call_arg_list.py | 13 ++++- src/psyclone/domain/lfric/lfric_kern.py | 29 +++++----- 3 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/psyclone/domain/lfric/__init__.py b/src/psyclone/domain/lfric/__init__.py index c8c468b846..372f000f50 100644 --- a/src/psyclone/domain/lfric/__init__.py +++ b/src/psyclone/domain/lfric/__init__.py @@ -76,30 +76,29 @@ from psyclone.domain.lfric.lfric_dofmaps import LFRicDofmaps from psyclone.domain.lfric.lfric_stencils import LFRicStencils -if False: - __all__ = [ - 'ArgOrdering', - 'FunctionSpace', - 'KernCallAccArgList', - 'KernCallArgList', - 'KernelInterface', - 'KernStubArgList', - 'LFRicArgDescriptor', - 'LFRicCellIterators', - 'LFRicCollection', - 'LFRicConstants', - 'LFRicDofmaps', - 'LFRicExtractDriverCreator', - 'LFRicFields', - 'LFRicInvoke', - 'LFRicInvokes', - 'LFRicInvokeSchedule', - 'LFRicKern', - 'LFRicKernCallFactory', - 'LFRicKernMetadata', - 'LFRicLoop', - 'LFRicLoopBounds', - 'LFRicRunTimeChecks', - 'LFRicScalarArgs', - 'LFRicStencils', - 'LFRicSymbolTable'] +__all__ = [ + 'ArgOrdering', + 'FunctionSpace', + 'KernCallAccArgList', + 'KernCallArgList', + 'KernelInterface', + 'KernStubArgList', + 'LFRicArgDescriptor', + 'LFRicCellIterators', + 'LFRicCollection', + 'LFRicConstants', + 'LFRicDofmaps', + 'LFRicExtractDriverCreator', + 'LFRicFields', + 'LFRicInvoke', + 'LFRicInvokes', + 'LFRicInvokeSchedule', + 'LFRicKern', + 'LFRicKernCallFactory', + 'LFRicKernMetadata', + 'LFRicLoop', + 'LFRicLoopBounds', + 'LFRicRunTimeChecks', + 'LFRicScalarArgs', + 'LFRicStencils', + 'LFRicSymbolTable'] diff --git a/src/psyclone/domain/lfric/kern_call_arg_list.py b/src/psyclone/domain/lfric/kern_call_arg_list.py index cc3c296a7b..82702ab350 100644 --- a/src/psyclone/domain/lfric/kern_call_arg_list.py +++ b/src/psyclone/domain/lfric/kern_call_arg_list.py @@ -42,7 +42,7 @@ should be removed as we migrate to use PSyIR in LFRic. ''' -from collections import namedtuple +from dataclasses import dataclass from psyclone import psyGen from psyclone.core import AccessType, Signature @@ -73,7 +73,16 @@ class KernCallArgList(ArgOrdering): :type kern: :py:class:`psyclone.domain.lfric.LFRicKern` ''' - NdfInfo = namedtuple("NdfInfo", ["position", "function_space"]) + @dataclass(frozen=True) + class NdfInfo: + ''' + Holds information relating to the number-of-dofs kernel argument. + + :param position: the position of this argument in the argument list. + :param function_space: the function space that this argument is for. + ''' + position: int = None + function_space: str = None def __init__(self, kern): super().__init__(kern) diff --git a/src/psyclone/domain/lfric/lfric_kern.py b/src/psyclone/domain/lfric/lfric_kern.py index 422ac473f9..6e3bdecb15 100644 --- a/src/psyclone/domain/lfric/lfric_kern.py +++ b/src/psyclone/domain/lfric/lfric_kern.py @@ -39,8 +39,8 @@ ''' This module implements the PSyclone LFRic API by specialising the required base class Kern in psyGen.py ''' -# Imports -from collections import OrderedDict, namedtuple +from collections import OrderedDict +from dataclasses import dataclass from psyclone.configuration import Config from psyclone.core import AccessType @@ -66,16 +66,21 @@ class LFRicKern(CodedKern): ''' # pylint: disable=too-many-instance-attributes - # An instance of this `namedtuple` is used to store information on each of - # the quadrature rules required by a kernel. - # - # alg_name: The actual argument text specifying the QR object in the - # Alg. layer. - # psy_name: The PSy-layer variable name for the QR object. - # kernel_args: List of kernel arguments associated with this QR rule. - - QRRule = namedtuple("QRRule", - ["alg_name", "psy_name", "kernel_args"]) + + @dataclass(frozen=True) + class QRRule: + ''' + Used to store information on each of the quadrature rules required by + a kernel. + + :param alg_name: the actual argument text specifying the QR object in + the Alg. layer. + :param psy_name: the PSy-layer variable name for the QR object. + :param kernel_args: kernel arguments associated with this QR rule. + ''' + alg_name: str + psy_name: str + kernel_args: list[str] def __init__(self): # The super-init is called from the _setup() method which in turn From e732544e053d5700d11d207ac2d88cc909f496c8 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 12 Nov 2024 13:49:11 +0000 Subject: [PATCH 04/16] #1280 remove several namedtuples and update handler to exclude docs for Operator --- doc/reference_guide/source/conf.py | 6 +- src/psyclone/psyir/frontend/fparser2.py | 6 +- src/psyclone/psyir/nodes/container.py | 2 +- src/psyclone/psyir/nodes/operation.py | 7 +- src/psyclone/psyir/symbols/__init__.py | 84 +++++++++---------- src/psyclone/psyir/symbols/datasymbol.py | 3 +- src/psyclone/psyir/symbols/datatypes.py | 66 +++++++++++---- .../psyir/symbols/generic_interface_symbol.py | 19 ++++- .../tests/psyir/backend/opencl_test.py | 12 +-- 9 files changed, 126 insertions(+), 79 deletions(-) diff --git a/doc/reference_guide/source/conf.py b/doc/reference_guide/source/conf.py index 28c5421f75..2b17facb3c 100644 --- a/doc/reference_guide/source/conf.py +++ b/doc/reference_guide/source/conf.py @@ -210,10 +210,10 @@ def remove_namedtuple_attrib_docstring(app, what, name, obj, skip, options): - if type(obj) is collections._tuplegetter: - return True +# if type(obj) is collections._tuplegetter: +# return True if "Operator" in name: - print(f"ARPDBG: skipping '{name}'") + print(f"ARPDBG: skipping '{name}', type={type(obj)}, what='{what}'") return True return skip diff --git a/src/psyclone/psyir/frontend/fparser2.py b/src/psyclone/psyir/frontend/fparser2.py index 88fc6cc512..b7df264cb9 100644 --- a/src/psyclone/psyir/frontend/fparser2.py +++ b/src/psyclone/psyir/frontend/fparser2.py @@ -396,9 +396,9 @@ def _find_or_create_psyclone_internal_cmp(node): routine_symbol3 = container.symbol_table.lookup(name_f_char) symbol = GenericInterfaceSymbol( sym.name, - [(routine_symbol1, sym.routines[0][1]), - (routine_symbol2, sym.routines[1][1]), - (routine_symbol3, sym.routines[2][1])], + [(routine_symbol1, sym.routines[0].from_container), + (routine_symbol2, sym.routines[1].from_container), + (routine_symbol3, sym.routines[2].from_container)], visibility=sym.visibility ) container.symbol_table.add(symbol) diff --git a/src/psyclone/psyir/nodes/container.py b/src/psyclone/psyir/nodes/container.py index f0ad98b245..e35b706063 100644 --- a/src/psyclone/psyir/nodes/container.py +++ b/src/psyclone/psyir/nodes/container.py @@ -307,7 +307,7 @@ def resolve_routine(self, name): except KeyError: return [] if isinstance(rsym, GenericInterfaceSymbol): - return [rt[0].name.lower() for rt in rsym.routines] + return [rt.symbol.name.lower() for rt in rsym.routines] if isinstance(rsym, RoutineSymbol): return [name] if type(rsym) is Symbol and rsym.is_import: diff --git a/src/psyclone/psyir/nodes/operation.py b/src/psyclone/psyir/nodes/operation.py index 77985560e8..2de15d2e38 100644 --- a/src/psyclone/psyir/nodes/operation.py +++ b/src/psyclone/psyir/nodes/operation.py @@ -64,10 +64,11 @@ class Operation(DataNode, metaclass=ABCMeta): self.Operator. ''' - # Must be overridden in sub-class to hold an Enumeration of the Operators - # that it can represent. + #: Must be overridden in sub-class to hold an Enumeration of the Operators + #: that it can represent. + #: :meta private: Operator = object - # Colour of the node in a view tree. + #: Colour of the node in a view tree. _colour = "blue" def __init__(self, operator, parent=None): diff --git a/src/psyclone/psyir/symbols/__init__.py b/src/psyclone/psyir/symbols/__init__.py index c01d4bd7cc..5e06582c8e 100644 --- a/src/psyclone/psyir/symbols/__init__.py +++ b/src/psyclone/psyir/symbols/__init__.py @@ -56,48 +56,48 @@ ArrayType, BOOLEAN_TYPE, CHARACTER_TYPE, DataType, INTEGER4_TYPE, INTEGER8_TYPE, INTEGER_DOUBLE_TYPE, INTEGER_SINGLE_TYPE, INTEGER_TYPE, NoType, REAL4_TYPE, REAL8_TYPE, REAL_DOUBLE_TYPE, REAL_SINGLE_TYPE, - REAL_TYPE, ScalarType, StructureType, TYPE_MAP_TO_PYTHON, UnresolvedType, + REAL_TYPE, ScalarType, StructureType, UnresolvedType, UnsupportedType, UnsupportedFortranType) # For auto documentation generation. -#__all__ = ['ArgumentInterface', -# 'ArrayType', -# 'AutomaticInterface', -# 'BOOLEAN_TYPE', -# 'CHARACTER_TYPE', -# 'CommonBlockInterface', -# 'ContainerSymbol', -# 'DataSymbol', -# 'DataType', -# 'DataTypeSymbol', -# 'DefaultModuleInterface', -# 'GenericInterfaceSymbol', -# 'ImportInterface', -# 'INTEGER_TYPE', -# 'INTEGER_SINGLE_TYPE', -# 'INTEGER_DOUBLE_TYPE', -# 'INTEGER4_TYPE', -# 'INTEGER8_TYPE', -# 'IntrinsicSymbol', -# 'NoType', -# 'PreprocessorInterface', -# 'REAL_TYPE', -# 'REAL_SINGLE_TYPE', -# 'REAL_DOUBLE_TYPE', -# 'REAL4_TYPE', -# 'REAL8_TYPE', -# 'RoutineSymbol', -# 'ScalarType', -# 'StaticInterface', -# 'StructureType', -# 'Symbol', -# 'SymbolError', -# 'SymbolTable', -# 'TYPE_MAP_TO_PYTHON', -# 'TypedSymbol', -# 'UnsupportedFortranType', -# 'UnknownInterface', -# 'UnsupportedType', -# 'UnresolvedInterface', -# 'UnresolvedType'] -# +__all__ = ['ArgumentInterface', + 'ArrayType', + 'AutomaticInterface', + 'BOOLEAN_TYPE', + 'CHARACTER_TYPE', + 'CommonBlockInterface', + 'ContainerSymbol', + 'DataSymbol', + 'DataType', + 'DataTypeSymbol', + 'DefaultModuleInterface', + 'GenericInterfaceSymbol', + 'ImportInterface', + 'INTEGER_TYPE', + 'INTEGER_SINGLE_TYPE', + 'INTEGER_DOUBLE_TYPE', + 'INTEGER4_TYPE', + 'INTEGER8_TYPE', + 'IntrinsicSymbol', + 'NoType', + 'PreprocessorInterface', + 'REAL_TYPE', + 'REAL_SINGLE_TYPE', + 'REAL_DOUBLE_TYPE', + 'REAL4_TYPE', + 'REAL8_TYPE', + 'RoutineSymbol', + 'ScalarType', + 'StaticInterface', + 'StructureType', + 'Symbol', + 'SymbolError', + 'SymbolTable', + #'TYPE_MAP_TO_PYTHON', + 'TypedSymbol', + 'UnsupportedFortranType', + 'UnknownInterface', + 'UnsupportedType', + 'UnresolvedInterface', + 'UnresolvedType'] + diff --git a/src/psyclone/psyir/symbols/datasymbol.py b/src/psyclone/psyir/symbols/datasymbol.py index 70d8c89ddc..c1ddb9e20d 100644 --- a/src/psyclone/psyir/symbols/datasymbol.py +++ b/src/psyclone/psyir/symbols/datasymbol.py @@ -243,11 +243,10 @@ def initial_value(self, new_value): f"{node}") new_initial_value = new_value else: - from psyclone.psyir.symbols.datatypes import TYPE_MAP_TO_PYTHON # No need to check that self.datatype has an intrinsic # attribute as we know it is a ScalarType or ArrayType # due to an earlier test. - lookup = TYPE_MAP_TO_PYTHON[self.datatype.intrinsic] + lookup = ScalarType.TYPE_MAP_TO_PYTHON[self.datatype.intrinsic] if not isinstance(new_value, lookup): raise ValueError( f"Error setting initial value for symbol " diff --git a/src/psyclone/psyir/symbols/datatypes.py b/src/psyclone/psyir/symbols/datatypes.py index d0b1bd05a0..b04d226e99 100644 --- a/src/psyclone/psyir/symbols/datatypes.py +++ b/src/psyclone/psyir/symbols/datatypes.py @@ -40,7 +40,9 @@ import abc import copy from collections import OrderedDict, namedtuple +from dataclasses import dataclass from enum import Enum +from typing import Any from psyclone.errors import InternalError from psyclone.psyir.symbols.data_type_symbol import DataTypeSymbol @@ -310,6 +312,14 @@ class Precision(Enum): DOUBLE = 2 UNDEFINED = 3 + #: Mapping from PSyIR scalar data types to intrinsic Python types + #: ignoring precision. + TYPE_MAP_TO_PYTHON = { + Intrinsic.INTEGER: int, + Intrinsic.CHARACTER: str, + Intrinsic.BOOLEAN: bool, + Intrinsic.REAL: float} + def __init__(self, intrinsic, precision): if not isinstance(intrinsic, ScalarType.Intrinsic): raise TypeError( @@ -463,8 +473,18 @@ def copy(self): ''' return copy.copy(self) - #: namedtuple used to store lower and upper limits of an array dimension - ArrayBounds = namedtuple("ArrayBounds", ["lower", "upper"]) + @dataclass(frozen=True) + class ArrayBounds: + ''' + Class to store lower and upper limits of an array dimension + + TODO - does not enforce that the limits are PSyIR. + + :param lower: the lower bound of the array dimension. + :param upper: the upper bound of the array dimension. + ''' + lower: Any + upper: Any def __init__(self, datatype, shape): @@ -699,6 +719,9 @@ def _validate_data_node(dim_node, is_lower_bound=False): f"'{dimension}' has {len(dimension)} entries.") _validate_data_node(dimension[0], is_lower_bound=True) _validate_data_node(dimension[1]) + elif isinstance(dimension, ArrayType.ArrayBounds): + _validate_data_node(dimension.lower, is_lower_bound=True) + _validate_data_node(dimension.upper) else: _validate_data_node(dimension) @@ -716,7 +739,9 @@ def _validate_data_node(dim_node, is_lower_bound=False): for dim in extents: if not (dim == ArrayType.Extent.ATTRIBUTE or (isinstance(dim, tuple) and - dim[-1] == ArrayType.Extent.ATTRIBUTE)): + dim[-1] == ArrayType.Extent.ATTRIBUTE) or + (isinstance(dim, ArrayType.ArrayBounds) and + dim.upper == ArrayType.Extent.ATTRIBUTE)): raise TypeError( f"An assumed-shape array must have every " f"dimension unspecified (either as 'ATTRIBUTE' or " @@ -802,7 +827,8 @@ def copy(self): ''' new_shape = [] - for dim in self.shape: + current_shape = self.shape + for dim in current_shape: if isinstance(dim, ArrayType.ArrayBounds): new_bounds = ArrayType.ArrayBounds(dim.lower.copy(), dim.upper.copy()) @@ -850,7 +876,7 @@ def replace_symbols_using(self, table): # Update any Symbols referenced in the array shape for dim in self.shape: if isinstance(dim, ArrayType.ArrayBounds): - exprns = dim + exprns = [dim.lower, dim.upper] else: exprns = [dim] for bnd in exprns: @@ -870,10 +896,24 @@ class StructureType(DataType): SymbolTable functionality then this decision could be revisited. ''' - # Each member of a StructureType is represented by a ComponentType - # (named tuple). - ComponentType = namedtuple("ComponentType", [ - "name", "datatype", "visibility", "initial_value"]) + @dataclass(frozen=True) + class ComponentType: + ''' + Represents a member of a StructureType. + + :param name: the name of the member. + :param datatype: the type of the member. + :type datatype: :py:class:`psyclone.psyir.symbols.DataType` | + :py:class:`psyclone.psyir.symbols.DataTypeSymbol` + :param visibility: whether this member is public or private. + :type visibility: :py:class:`psyclone.psyir.symbols.Symbol.Visibility` + :param initial_value: the initial value of this member (if any). + :type initial_value: Optional[:py:class:`psyclone.psyir.nodes.Node`] + ''' + name: str + datatype: Any + visibility: Any + initial_value: Any def __init__(self): self._components = OrderedDict() @@ -1049,14 +1089,6 @@ def replace_symbols_using(self, table): CHARACTER_TYPE = ScalarType(ScalarType.Intrinsic.CHARACTER, ScalarType.Precision.UNDEFINED) -# Mapping from PSyIR scalar data types to intrinsic Python types -# ignoring precision. -TYPE_MAP_TO_PYTHON = { - ScalarType.Intrinsic.INTEGER: int, - ScalarType.Intrinsic.CHARACTER: str, - ScalarType.Intrinsic.BOOLEAN: bool, - ScalarType.Intrinsic.REAL: float} - # For automatic documentation generation __all__ = ["UnsupportedType", "UnsupportedFortranType", "UnresolvedType", diff --git a/src/psyclone/psyir/symbols/generic_interface_symbol.py b/src/psyclone/psyir/symbols/generic_interface_symbol.py index 169ffca59b..3dff590326 100644 --- a/src/psyclone/psyir/symbols/generic_interface_symbol.py +++ b/src/psyclone/psyir/symbols/generic_interface_symbol.py @@ -36,7 +36,9 @@ ''' This module contains the GenericInterfaceSymbol.''' -from collections import namedtuple +from dataclasses import dataclass +from typing import Any + from psyclone.psyir.symbols.routinesymbol import RoutineSymbol @@ -54,7 +56,17 @@ class GenericInterfaceSymbol(RoutineSymbol): :type kwargs: unwrapped dict. ''' - RoutineInfo = namedtuple("RoutineInfo", ["symbol", "from_container"]) + @dataclass(frozen=True) + class RoutineInfo: + ''' + Holds information on a single routine member of an interface. + + :param symbol: the symbol representing the routine. + :param from_container: whether or not this routine is from a Container + (i.e. a 'module procedure' in Fortran). + ''' + symbol: Any + from_container: bool def __init__(self, name, routines, **kwargs): super().__init__(name, **kwargs) @@ -149,7 +161,8 @@ def copy(self): ''' # The constructors for all Symbol-based classes have 'name' as the # first positional argument. - return type(self)(self.name, self.routines[:], + rt_info = [(rt.symbol, rt.from_container) for rt in self.routines] + return type(self)(self.name, rt_info, datatype=self.datatype.copy(), visibility=self.visibility, interface=self.interface.copy()) diff --git a/src/psyclone/tests/psyir/backend/opencl_test.py b/src/psyclone/tests/psyir/backend/opencl_test.py index 549f7aeec9..03b33fa585 100644 --- a/src/psyclone/tests/psyir/backend/opencl_test.py +++ b/src/psyclone/tests/psyir/backend/opencl_test.py @@ -40,10 +40,10 @@ import pytest from psyclone.psyir.backend.visitor import VisitorError from psyclone.psyir.backend.opencl import OpenCLWriter -from psyclone.psyir.nodes import Return, KernelSchedule -from psyclone.psyir.symbols import DataSymbol, SymbolTable, \ - ArgumentInterface, UnresolvedInterface, ArrayType, REAL_TYPE, \ - INTEGER_TYPE +from psyclone.psyir.nodes import Return, KernelSchedule, Literal +from psyclone.psyir.symbols import ( + DataSymbol, SymbolTable, ArgumentInterface, UnresolvedInterface, ArrayType, + REAL_TYPE, INTEGER_TYPE) def test_oclw_initialization(): @@ -117,7 +117,9 @@ def test_oclw_gen_declaration(): assert result == "__global int * restrict dummy2" # Array with a lower bound other than 1 - array_type = ArrayType(INTEGER_TYPE, [2, ArrayType.ArrayBounds(2, 5)]) + two = Literal("2", INTEGER_TYPE) + five = Literal("5", INTEGER_TYPE) + array_type = ArrayType(INTEGER_TYPE, [2, ArrayType.ArrayBounds(two, five)]) symbol = DataSymbol("dummy3", array_type) with pytest.raises(VisitorError) as err: oclwriter.gen_declaration(symbol) From 1a94caed21ebc4e90e58c2c695e64932127b57b3 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 12 Nov 2024 13:50:03 +0000 Subject: [PATCH 05/16] #1280 fix linting --- src/psyclone/psyir/symbols/datatypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/psyclone/psyir/symbols/datatypes.py b/src/psyclone/psyir/symbols/datatypes.py index b04d226e99..e9c9d1d5f6 100644 --- a/src/psyclone/psyir/symbols/datatypes.py +++ b/src/psyclone/psyir/symbols/datatypes.py @@ -39,7 +39,7 @@ import abc import copy -from collections import OrderedDict, namedtuple +from collections import OrderedDict from dataclasses import dataclass from enum import Enum from typing import Any From e7b2836a3576db5386a752b98a8cbe9217d537cc Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Thu, 14 Nov 2024 20:32:25 +0000 Subject: [PATCH 06/16] #1280 fix tests now that some things are dataclasses and not tuples --- src/psyclone/domain/lfric/lfric_kern.py | 12 +++++++----- src/psyclone/psyad/adjoint_visitor.py | 6 +++--- src/psyclone/tests/dynamo0p3_test.py | 18 ++++++++++++------ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/psyclone/domain/lfric/lfric_kern.py b/src/psyclone/domain/lfric/lfric_kern.py index 6e3bdecb15..80646b0ea5 100644 --- a/src/psyclone/domain/lfric/lfric_kern.py +++ b/src/psyclone/domain/lfric/lfric_kern.py @@ -41,6 +41,7 @@ from collections import OrderedDict from dataclasses import dataclass +from typing import List from psyclone.configuration import Config from psyclone.core import AccessType @@ -70,17 +71,18 @@ class LFRicKern(CodedKern): @dataclass(frozen=True) class QRRule: ''' - Used to store information on each of the quadrature rules required by + Used to store information on a quadrature rule required by a kernel. - :param alg_name: the actual argument text specifying the QR object in + :param alg_name: The actual argument text specifying the QR object in the Alg. layer. - :param psy_name: the PSy-layer variable name for the QR object. - :param kernel_args: kernel arguments associated with this QR rule. + :param psy_name: The PSy-layer variable name for the QR object. + :param kernel_args: Kernel arguments associated with this QR rule. + ''' alg_name: str psy_name: str - kernel_args: list[str] + kernel_args: List[str] def __init__(self): # The super-init is called from the _setup() method which in turn diff --git a/src/psyclone/psyad/adjoint_visitor.py b/src/psyclone/psyad/adjoint_visitor.py index 67a9f6b6e2..fb53a5a7f2 100644 --- a/src/psyclone/psyad/adjoint_visitor.py +++ b/src/psyclone/psyad/adjoint_visitor.py @@ -451,10 +451,10 @@ def _copy_and_process(self, node): if isinstance(symbol_obj, GenericInterfaceSymbol): new_routines = [] - for rsym, mod_pro in symbol_obj.routines: + for rinfo in symbol_obj.routines: new_routines.append(( - sym_tab.lookup(rsym.name), - mod_pro + sym_tab.lookup(rinfo.symbol.name), + rinfo.from_container )) symbol_obj.routines = new_routines diff --git a/src/psyclone/tests/dynamo0p3_test.py b/src/psyclone/tests/dynamo0p3_test.py index c2706a333d..c1ddee18c4 100644 --- a/src/psyclone/tests/dynamo0p3_test.py +++ b/src/psyclone/tests/dynamo0p3_test.py @@ -3703,9 +3703,12 @@ def test_kerncallarglist_positions_noquad(dist_mem): assert create_arg_list.nlayers_positions == [1] assert not create_arg_list.nqp_positions assert len(create_arg_list.ndf_positions) == 3 - assert create_arg_list.ndf_positions[0] == (7, "w1") - assert create_arg_list.ndf_positions[1] == (10, "w2") - assert create_arg_list.ndf_positions[2] == (13, "w3") + assert create_arg_list.ndf_positions[0].position == 7 + assert create_arg_list.ndf_positions[0].function_space == "w1" + assert create_arg_list.ndf_positions[1].position == 10 + assert create_arg_list.ndf_positions[1].function_space == "w2" + assert create_arg_list.ndf_positions[2].position == 13 + assert create_arg_list.ndf_positions[2].function_space == "w3" def test_kerncallarglist_positions_quad(dist_mem): @@ -3732,9 +3735,12 @@ def test_kerncallarglist_positions_quad(dist_mem): assert create_arg_list.nqp_positions[0]["horizontal"] == 21 assert create_arg_list.nqp_positions[0]["vertical"] == 22 assert len(create_arg_list.ndf_positions) == 3 - assert create_arg_list.ndf_positions[0] == (8, "w1") - assert create_arg_list.ndf_positions[1] == (12, "w2") - assert create_arg_list.ndf_positions[2] == (16, "w3") + assert create_arg_list.ndf_positions[0].position == 8 + assert create_arg_list.ndf_positions[0].function_space == "w1" + assert create_arg_list.ndf_positions[1].position == 12 + assert create_arg_list.ndf_positions[1].function_space == "w2" + assert create_arg_list.ndf_positions[2].position == 16 + assert create_arg_list.ndf_positions[2].function_space == "w3" # Class DynKernelArguments start From a264546b85151b0e31827067d96e7809eab36d1f Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Thu, 14 Nov 2024 21:30:08 +0000 Subject: [PATCH 07/16] #1280 skip documenting Operator enums in Ref Guide --- doc/reference_guide/source/conf.py | 27 +++++++++++++++++++-------- src/psyclone/psyir/nodes/operation.py | 3 ++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/doc/reference_guide/source/conf.py b/doc/reference_guide/source/conf.py index 2b17facb3c..2817deeefb 100644 --- a/doc/reference_guide/source/conf.py +++ b/doc/reference_guide/source/conf.py @@ -16,8 +16,9 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -import subprocess +import enum import os +import subprocess # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -206,20 +207,30 @@ # -- Autodoc configuration --------------------------------------------------- -import collections +def remove_op_enum_attrib_docstring(app, what, name, obj, skip, options): + ''' + A handler that ensures any EnumType objects named 'Operator' are *not* + documented. This is required to avoid warnings of the form: -def remove_namedtuple_attrib_docstring(app, what, name, obj, skip, options): -# if type(obj) is collections._tuplegetter: -# return True - if "Operator" in name: - print(f"ARPDBG: skipping '{name}', type={type(obj)}, what='{what}'") + psyclone/psyir/nodes/operation.py:docstring of + psyclone.psyir.nodes.operation.Operator:1: WARNING: duplicate object + description of psyclone.psyir.nodes.operation.Operator, other instance + in autogenerated/psyclone.psyir.nodes, use :no-index: for one of them + + ''' + if name.endswith("Operator") and isinstance(obj, enum.EnumType): return True return skip def setup(app): - app.connect('autodoc-skip-member', remove_namedtuple_attrib_docstring) + ''' + Add in our custom handler to avoid documentation warnings for the various + Operator members of psyir.nodes.*Operation. + + ''' + app.connect('autodoc-skip-member', remove_op_enum_attrib_docstring) # -- Generate the Doxygen documentation -------------------------------------- diff --git a/src/psyclone/psyir/nodes/operation.py b/src/psyclone/psyir/nodes/operation.py index 2de15d2e38..c076d57544 100644 --- a/src/psyclone/psyir/nodes/operation.py +++ b/src/psyclone/psyir/nodes/operation.py @@ -66,7 +66,6 @@ class Operation(DataNode, metaclass=ABCMeta): ''' #: Must be overridden in sub-class to hold an Enumeration of the Operators #: that it can represent. - #: :meta private: Operator = object #: Colour of the node in a view tree. _colour = "blue" @@ -141,6 +140,7 @@ class UnaryOperation(Operation): # Textual description of the node. _children_valid_format = "DataNode" + #: The Operators that a UnaryOperation can represent. Operator = Enum('Operator', [ # Arithmetic Operators 'MINUS', 'PLUS', @@ -210,6 +210,7 @@ class BinaryOperation(Operation): as children 0 and 1, and an attribute with the operator type. ''' + #: The Operators that a BinaryOperation can represent. Operator = Enum('Operator', [ # Arithmetic Operators. ('REM' is remainder AKA 'MOD' in Fortran.) 'ADD', 'SUB', 'MUL', 'DIV', 'REM', 'POW', From b9c90d475bb6237d6f09e628cf76263698073f10 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Thu, 14 Nov 2024 21:43:43 +0000 Subject: [PATCH 08/16] #1280 uncomment check on build of reference guide in CI --- .github/workflows/python-package.yml | 2 +- src/psyclone/domain/lfric/lfric_kern.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 2979d39d1f..6ebc56ae5a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -76,7 +76,7 @@ jobs: # Now we can check for warnings and broken links - run: cd doc/user_guide; make html SPHINXOPTS="-W --keep-going" - run: cd doc/developer_guide; make html SPHINXOPTS="-W --keep-going" - # TODO #1280: - run: cd doc/reference_guide; make html SPHINXOPTS="-W --keep-going" + - run: cd doc/reference_guide; make html SPHINXOPTS="-W --keep-going" - run: cd doc/psyad/user_guide; make html SPHINXOPTS="-W --keep-going" - run: cd doc/user_guide; make linkcheck - run: cd doc/developer_guide; make linkcheck diff --git a/src/psyclone/domain/lfric/lfric_kern.py b/src/psyclone/domain/lfric/lfric_kern.py index 96dd38ba46..e782a76263 100644 --- a/src/psyclone/domain/lfric/lfric_kern.py +++ b/src/psyclone/domain/lfric/lfric_kern.py @@ -642,8 +642,8 @@ def gen_stub(self): :rtype: :py:class:`fparser.one.block_statements.Module` :raises GenerationError: if the supplied kernel stub does not operate - on a supported subset of the domain (currently only - "*cell_column"). + on a supported subset of the domain (currently only those that + end with "cell_column"). ''' # The operates-on/iterates-over values supported by the stub generator. From 62dd40fa5234839e561ae3224f8ee9e38cb7878d Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Thu, 14 Nov 2024 21:51:36 +0000 Subject: [PATCH 09/16] #1280 rm remaining TODO --- src/psyclone/psyir/transformations/transformation_error.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/psyclone/psyir/transformations/transformation_error.py b/src/psyclone/psyir/transformations/transformation_error.py index 8c650e8e38..33e79d8fa8 100644 --- a/src/psyclone/psyir/transformations/transformation_error.py +++ b/src/psyclone/psyir/transformations/transformation_error.py @@ -44,12 +44,10 @@ class TransformationError(PSycloneError): code transformation operations. ''' def __init__(self, value): - PSycloneError.__init__(self, value) + super().__init__(value) self.value = LazyString( lambda: f"Transformation Error: {value}") -# TODO #1280: This currently causes 'more than one target for cross-reference' -# warnings when building the reference guide. # For AutoAPI documentation generation -# __all__ = ["TransformationError"] +__all__ = ["TransformationError"] From 441927f6ff239848c86a2b7dfe59ea8a1b946cb5 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Thu, 14 Nov 2024 22:37:41 +0000 Subject: [PATCH 10/16] #1280 put both original versions of __init__.py and fix warnings --- src/psyclone/domain/lfric/__init__.py | 1 + .../domain/lfric/algorithm/__init__.py | 15 ++-- .../psyir/transformations/__init__.py | 79 +++++++++---------- .../psyir/transformations/omp_loop_trans.py | 2 + src/psyclone/transformations.py | 1 - 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/psyclone/domain/lfric/__init__.py b/src/psyclone/domain/lfric/__init__.py index b365fbd225..370232699a 100644 --- a/src/psyclone/domain/lfric/__init__.py +++ b/src/psyclone/domain/lfric/__init__.py @@ -77,6 +77,7 @@ from psyclone.domain.lfric.lfric_dofmaps import LFRicDofmaps from psyclone.domain.lfric.lfric_stencils import LFRicStencils + __all__ = [ 'ArgOrdering', 'FunctionSpace', diff --git a/src/psyclone/domain/lfric/algorithm/__init__.py b/src/psyclone/domain/lfric/algorithm/__init__.py index 9f993abf0f..df43cc9e86 100644 --- a/src/psyclone/domain/lfric/algorithm/__init__.py +++ b/src/psyclone/domain/lfric/algorithm/__init__.py @@ -45,11 +45,10 @@ # For AutoAPI documentation generation. -if False: - __all__ = [ - 'LFRicAlg', - 'LFRicAlgorithmInvokeCall', - 'LFRicBuiltinFunctor', - 'LFRicBuiltinFunctorFactory', - 'LFRicFunctor', - 'LFRicKernelFunctor'] +__all__ = [ + 'LFRicAlg', + 'LFRicAlgorithmInvokeCall', + 'LFRicBuiltinFunctor', + 'LFRicBuiltinFunctorFactory', + 'LFRicFunctor', + 'LFRicKernelFunctor'] diff --git a/src/psyclone/psyir/transformations/__init__.py b/src/psyclone/psyir/transformations/__init__.py index 6bd87580c4..60b55c1449 100644 --- a/src/psyclone/psyir/transformations/__init__.py +++ b/src/psyclone/psyir/transformations/__init__.py @@ -107,43 +107,42 @@ # For AutoAPI documentation generation -if False: - __all__ = ['ACCKernelsTrans', - 'ACCUpdateTrans', - 'AllArrayAccess2LoopTrans', - 'ArrayAccess2LoopTrans', - 'ArrayAssignment2LoopsTrans', - 'ChunkLoopTrans', - 'ExtractTrans', - 'FoldConditionalReturnExpressionsTrans', - 'HoistLocalArraysTrans', - 'HoistLoopBoundExprTrans', - 'HoistTrans', - 'InlineTrans', - 'Abs2CodeTrans', - 'DotProduct2CodeTrans', - 'Matmul2CodeTrans', - 'Max2CodeTrans', - 'Min2CodeTrans', - 'Sign2CodeTrans', - 'Sum2LoopTrans', - 'LoopFuseTrans', - 'LoopSwapTrans', - 'LoopTiling2DTrans', - 'LoopTrans', - 'Maxval2LoopTrans', - 'Minval2LoopTrans', - 'OMPLoopTrans', - 'OMPTargetTrans', - 'OMPTaskTrans', - 'OMPTaskwaitTrans', - 'ParallelLoopTrans', - 'Product2LoopTrans', - 'ProfileTrans', - 'PSyDataTrans', - 'ReadOnlyVerifyTrans', - 'Reference2ArrayRangeTrans', - 'RegionTrans', - 'ReplaceInductionVariablesTrans', - 'TransformationError', - 'ValueRangeCheckTrans'] +__all__ = ['ACCKernelsTrans', + 'ACCUpdateTrans', + 'AllArrayAccess2LoopTrans', + 'ArrayAccess2LoopTrans', + 'ArrayAssignment2LoopsTrans', + 'ChunkLoopTrans', + 'ExtractTrans', + 'FoldConditionalReturnExpressionsTrans', + 'HoistLocalArraysTrans', + 'HoistLoopBoundExprTrans', + 'HoistTrans', + 'InlineTrans', + 'Abs2CodeTrans', + 'DotProduct2CodeTrans', + 'Matmul2CodeTrans', + 'Max2CodeTrans', + 'Min2CodeTrans', + 'Sign2CodeTrans', + 'Sum2LoopTrans', + 'LoopFuseTrans', + 'LoopSwapTrans', + 'LoopTiling2DTrans', + 'LoopTrans', + 'Maxval2LoopTrans', + 'Minval2LoopTrans', + 'OMPLoopTrans', + 'OMPTargetTrans', + 'OMPTaskTrans', + 'OMPTaskwaitTrans', + 'ParallelLoopTrans', + 'Product2LoopTrans', + 'ProfileTrans', + 'PSyDataTrans', + 'ReadOnlyVerifyTrans', + 'Reference2ArrayRangeTrans', + 'RegionTrans', + 'ReplaceInductionVariablesTrans', + 'TransformationError', + 'ValueRangeCheckTrans'] diff --git a/src/psyclone/psyir/transformations/omp_loop_trans.py b/src/psyclone/psyir/transformations/omp_loop_trans.py index b5d987eb7b..04c31b0485 100644 --- a/src/psyclone/psyir/transformations/omp_loop_trans.py +++ b/src/psyclone/psyir/transformations/omp_loop_trans.py @@ -43,12 +43,14 @@ from psyclone.psyir.transformations.parallel_loop_trans import \ ParallelLoopTrans +#: Mapping from simple string to actual directive class. MAP_STR_TO_LOOP_DIRECTIVES = { "do": OMPDoDirective, "paralleldo": OMPParallelDoDirective, "teamsdistributeparalleldo": OMPTeamsDistributeParallelDoDirective, "loop": OMPLoopDirective } +#: List containing the valid names for OMP directives. VALID_OMP_DIRECTIVES = list(MAP_STR_TO_LOOP_DIRECTIVES.keys()) diff --git a/src/psyclone/transformations.py b/src/psyclone/transformations.py index d37859eafc..ce9f06c3dc 100644 --- a/src/psyclone/transformations.py +++ b/src/psyclone/transformations.py @@ -2971,7 +2971,6 @@ def apply(self, node, options=None): "GOceanOMPParallelLoopTrans", "KernelImportsToArguments", "MoveTrans", - "OMPLoopTrans", "OMPMasterTrans", "OMPParallelLoopTrans", "OMPParallelTrans", From 551a9fb58774688bbf32b1fe2a15910656446532 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Thu, 14 Nov 2024 22:38:53 +0000 Subject: [PATCH 11/16] #1280 make all ref guide tests pass --- doc/reference_guide/source/conf.py | 2 ++ src/psyclone/domain/lfric/algorithm/psyir/__init__.py | 8 -------- src/psyclone/psyir/symbols/__init__.py | 2 -- src/psyclone/psyir/transformations/__init__.py | 3 ++- .../psyir/transformations/transformation_error.py | 4 ---- 5 files changed, 4 insertions(+), 15 deletions(-) diff --git a/doc/reference_guide/source/conf.py b/doc/reference_guide/source/conf.py index 2817deeefb..2936dd2c2b 100644 --- a/doc/reference_guide/source/conf.py +++ b/doc/reference_guide/source/conf.py @@ -221,6 +221,8 @@ def remove_op_enum_attrib_docstring(app, what, name, obj, skip, options): ''' if name.endswith("Operator") and isinstance(obj, enum.EnumType): return True + if name.endswith("TransformationError") and what == "class": + return True return skip diff --git a/src/psyclone/domain/lfric/algorithm/psyir/__init__.py b/src/psyclone/domain/lfric/algorithm/psyir/__init__.py index 6b07b52734..e3c87e677e 100644 --- a/src/psyclone/domain/lfric/algorithm/psyir/__init__.py +++ b/src/psyclone/domain/lfric/algorithm/psyir/__init__.py @@ -46,11 +46,3 @@ LFRicKernelFunctor) from psyclone.domain.lfric.algorithm.psyir.lfric_kernel_functor import ( LFRicBuiltinFunctorFactory) - - -# For Sphinx AutoAPI -__all__ = [ - 'LFRicAlgorithmInvokeCall', - 'LFRicKernelFunctor', - 'LFRicBuiltinFunctor', - 'LFRicBuiltinFunctorFactory'] diff --git a/src/psyclone/psyir/symbols/__init__.py b/src/psyclone/psyir/symbols/__init__.py index 5e06582c8e..10271a2e58 100644 --- a/src/psyclone/psyir/symbols/__init__.py +++ b/src/psyclone/psyir/symbols/__init__.py @@ -93,11 +93,9 @@ 'Symbol', 'SymbolError', 'SymbolTable', - #'TYPE_MAP_TO_PYTHON', 'TypedSymbol', 'UnsupportedFortranType', 'UnknownInterface', 'UnsupportedType', 'UnresolvedInterface', 'UnresolvedType'] - diff --git a/src/psyclone/psyir/transformations/__init__.py b/src/psyclone/psyir/transformations/__init__.py index 60b55c1449..6b5df8ddc9 100644 --- a/src/psyclone/psyir/transformations/__init__.py +++ b/src/psyclone/psyir/transformations/__init__.py @@ -86,7 +86,8 @@ from psyclone.psyir.transformations.loop_tiling_2d_trans \ import LoopTiling2DTrans from psyclone.psyir.transformations.loop_trans import LoopTrans -from psyclone.psyir.transformations.value_range_check_trans import ValueRangeCheckTrans +from psyclone.psyir.transformations.value_range_check_trans import ( + ValueRangeCheckTrans) from psyclone.psyir.transformations.omp_loop_trans import OMPLoopTrans from psyclone.psyir.transformations.omp_target_trans import OMPTargetTrans from psyclone.psyir.transformations.omp_taskwait_trans import OMPTaskwaitTrans diff --git a/src/psyclone/psyir/transformations/transformation_error.py b/src/psyclone/psyir/transformations/transformation_error.py index 33e79d8fa8..f64e15f14f 100644 --- a/src/psyclone/psyir/transformations/transformation_error.py +++ b/src/psyclone/psyir/transformations/transformation_error.py @@ -47,7 +47,3 @@ def __init__(self, value): super().__init__(value) self.value = LazyString( lambda: f"Transformation Error: {value}") - - -# For AutoAPI documentation generation -__all__ = ["TransformationError"] From 7ccc3476929350255e67b3f1dfe01f7a79b91280 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Fri, 15 Nov 2024 09:00:29 +0000 Subject: [PATCH 12/16] #1280 tidy up and reduce use of Any --- doc/reference_guide/source/conf.py | 2 -- src/psyclone/psyir/symbols/datatypes.py | 16 +++++++--------- .../psyir/symbols/generic_interface_symbol.py | 3 +-- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/doc/reference_guide/source/conf.py b/doc/reference_guide/source/conf.py index 2936dd2c2b..2817deeefb 100644 --- a/doc/reference_guide/source/conf.py +++ b/doc/reference_guide/source/conf.py @@ -221,8 +221,6 @@ def remove_op_enum_attrib_docstring(app, what, name, obj, skip, options): ''' if name.endswith("Operator") and isinstance(obj, enum.EnumType): return True - if name.endswith("TransformationError") and what == "class": - return True return skip diff --git a/src/psyclone/psyir/symbols/datatypes.py b/src/psyclone/psyir/symbols/datatypes.py index e9c9d1d5f6..618588e39b 100644 --- a/src/psyclone/psyir/symbols/datatypes.py +++ b/src/psyclone/psyir/symbols/datatypes.py @@ -476,20 +476,21 @@ def copy(self): @dataclass(frozen=True) class ArrayBounds: ''' - Class to store lower and upper limits of an array dimension - - TODO - does not enforce that the limits are PSyIR. + Class to store lower and upper limits of an array dimension. :param lower: the lower bound of the array dimension. + :type lower: :py:class:`psyclone.psyir.nodes.DataNode` :param upper: the upper bound of the array dimension. + :type upper: :py:class:`psyclone.psyir.nodes.DataNode` ''' + # Have to use Any here as using DataNode causes a circular dependence. lower: Any upper: Any def __init__(self, datatype, shape): # This import must be placed here to avoid circular dependencies. - # pylint: disable=import-outside-toplevel + # pylint: disable-next=import-outside-toplevel from psyclone.psyir.nodes import Literal, DataNode, Assignment def _node_from_int(var): @@ -903,16 +904,13 @@ class ComponentType: :param name: the name of the member. :param datatype: the type of the member. - :type datatype: :py:class:`psyclone.psyir.symbols.DataType` | - :py:class:`psyclone.psyir.symbols.DataTypeSymbol` :param visibility: whether this member is public or private. - :type visibility: :py:class:`psyclone.psyir.symbols.Symbol.Visibility` :param initial_value: the initial value of this member (if any). :type initial_value: Optional[:py:class:`psyclone.psyir.nodes.Node`] ''' name: str - datatype: Any - visibility: Any + datatype: DataType | DataTypeSymbol + visibility: Symbol.Visibility initial_value: Any def __init__(self): diff --git a/src/psyclone/psyir/symbols/generic_interface_symbol.py b/src/psyclone/psyir/symbols/generic_interface_symbol.py index 3dff590326..0e90e79505 100644 --- a/src/psyclone/psyir/symbols/generic_interface_symbol.py +++ b/src/psyclone/psyir/symbols/generic_interface_symbol.py @@ -37,7 +37,6 @@ ''' This module contains the GenericInterfaceSymbol.''' from dataclasses import dataclass -from typing import Any from psyclone.psyir.symbols.routinesymbol import RoutineSymbol @@ -65,7 +64,7 @@ class RoutineInfo: :param from_container: whether or not this routine is from a Container (i.e. a 'module procedure' in Fortran). ''' - symbol: Any + symbol: RoutineSymbol from_container: bool def __init__(self, name, routines, **kwargs): From d2e6113d13146aaf48379a1568706d9ce59c9b28 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Fri, 15 Nov 2024 10:37:29 +0000 Subject: [PATCH 13/16] #1280 fixes for Python 3.8 compatibility --- doc/reference_guide/source/conf.py | 3 ++- src/psyclone/psyir/symbols/datatypes.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/reference_guide/source/conf.py b/doc/reference_guide/source/conf.py index 2817deeefb..6d6a424c08 100644 --- a/doc/reference_guide/source/conf.py +++ b/doc/reference_guide/source/conf.py @@ -219,7 +219,8 @@ def remove_op_enum_attrib_docstring(app, what, name, obj, skip, options): in autogenerated/psyclone.psyir.nodes, use :no-index: for one of them ''' - if name.endswith("Operator") and isinstance(obj, enum.EnumType): + # EnumMeta is used for compatibility with Python < 3.11. + if name.endswith("Operator") and isinstance(obj, enum.EnumMeta): return True return skip diff --git a/src/psyclone/psyir/symbols/datatypes.py b/src/psyclone/psyir/symbols/datatypes.py index 618588e39b..8c89c89dff 100644 --- a/src/psyclone/psyir/symbols/datatypes.py +++ b/src/psyclone/psyir/symbols/datatypes.py @@ -42,7 +42,7 @@ from collections import OrderedDict from dataclasses import dataclass from enum import Enum -from typing import Any +from typing import Any, Union from psyclone.errors import InternalError from psyclone.psyir.symbols.data_type_symbol import DataTypeSymbol @@ -909,7 +909,8 @@ class ComponentType: :type initial_value: Optional[:py:class:`psyclone.psyir.nodes.Node`] ''' name: str - datatype: DataType | DataTypeSymbol + # Use Union for compatibility with Python < 3.10 + datatype: Union[DataType, DataTypeSymbol] visibility: Symbol.Visibility initial_value: Any From c491cb57f4abe17675d62efb38a11bf2410b1e75 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Fri, 15 Nov 2024 12:06:08 +0000 Subject: [PATCH 14/16] #1280 fix erroneous directory names from previous PR in nemo/eg5 --- examples/nemo/eg5/Makefile | 4 ++-- examples/nemo/eg5/README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/nemo/eg5/Makefile b/examples/nemo/eg5/Makefile index 29029b34aa..d0d252a52f 100644 --- a/examples/nemo/eg5/Makefile +++ b/examples/nemo/eg5/Makefile @@ -62,13 +62,13 @@ GENERATED_FILES += psy.f90 psy.o traadv-$(TYPE).exe output.dat # Pick up the right extraction library: PSYROOT=../../.. ifeq ($(TYPE), netcdf) - EXTRACT_DIR ?= $(PSYROOT)/lib/extract/netcdf/nemo + EXTRACT_DIR ?= $(PSYROOT)/lib/extract/netcdf/generic READ_DIR ?= $(PSYROOT)/lib/extract/netcdf F90FLAGS += $$(nf-config --fflags) LDFLAGS += $$(nf-config --flibs) $$(nc-config --libs) GENERATED_FILES += tra_adv-r?.nc else - EXTRACT_DIR ?= $(PSYROOT)/lib/extract/standalone/nemo + EXTRACT_DIR ?= $(PSYROOT)/lib/extract/standalone/generic READ_DIR ?= $(PSYROOT)/lib/extract/standalone GENERATED_FILES += tra_adv-r?.binary endif diff --git a/examples/nemo/eg5/README.md b/examples/nemo/eg5/README.md index 35d0157f80..fe9fe4d0e3 100644 --- a/examples/nemo/eg5/README.md +++ b/examples/nemo/eg5/README.md @@ -20,7 +20,7 @@ by supplying the `-l all` flag to PSyclone (as is done in the Makefile). The stand-alone extraction library in -``../../../lib/extract/standalone/nemo`` is used as default, and +``../../../lib/extract/standalone/generic`` is used as default, and will also be automatically compiled. You can also use the NetCDF based extraction library by setting the environment variable `TYPE` to `netcdf` when calling `make`, e.g.: @@ -29,7 +29,7 @@ when calling `make`, e.g.: This requires NetCDF to be available (including ``nf-config`` to detect installation-specific paths). The NetCDF-based extraction library in -``../../../../lib/extract/netcdf/nemo`` +``../../../../lib/extract/netcdf/generic`` will also be automatically compiled. The binary instrumented for extraction will either be called From 57b6118e404e6df101e23b4903ae1eae11776dcf Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Fri, 15 Nov 2024 13:57:35 +0000 Subject: [PATCH 15/16] #1280 fix bugs in compilation of tutorials in integration testing --- .github/workflows/compilation.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index d90b08417c..b1f75d3d6a 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -130,5 +130,5 @@ jobs: module load nvidia-hpcsdk/${NVFORTRAN_VERSION} module load hdf5/${HDF5_VERSION} netcdf_c/${NETCDF_C_VERSION} netcdf_fortran/${NETCDF_FORTRAN_VERSION} F90=nvfortran F90FLAGS="-acc -Minfo=all" make -C tutorial/practicals/LFRic compile - F90=nvfortran F90FLAGS="-acc -Minfo=all -Mnofma -O2" make -C tutorial/practicals/nemo run - make -C tutorial/practicals/nemo/4_nemo_openacc acc_test + F90=nvfortran F90FLAGS="-acc -Minfo=all -Mnofma -O2" make -C tutorial/practicals/generic run + make -C tutorial/practicals/generic/4_openacc acc_test From e22ab9b79d8fc092a39da054fc0b947953de9521 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Fri, 15 Nov 2024 16:12:03 +0000 Subject: [PATCH 16/16] #1280: Update changelog --- changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog b/changelog index afd9d35c2a..b806b6b7c8 100644 --- a/changelog +++ b/changelog @@ -279,6 +279,8 @@ 106) PR #2770 towards #2543. Improve UG introduction. + 107) PR #2776 for #1280. Fixes ref_guide warnings. + release 2.5.0 14th of February 2024 1) PR #2199 for #2189. Fix bugs with missing maps in enter data