Skip to content
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
6cbe966
For #1823. Add Kernel symbols when Kernel is created.
arporter Jan 21, 2026
ba8f599
#1823 first sketch of mixin [skip ci]
arporter Jan 21, 2026
5b4b68b
#1823 WIP fixing module-inlining for multiple kernel calls [skip ci]
arporter Jan 21, 2026
95b5710
#1823 WIP removing .module_inline setter and fixing tests [skip ci]
arporter Jan 22, 2026
1bb59eb
#1823 fix module-inline tests
arporter Jan 23, 2026
3811893
#1823 WIP fixing tests [skip ci]
arporter Jan 23, 2026
3082aa8
#1823 WIP fixing more tests [skip ci]
arporter Jan 26, 2026
2ae13c8
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Jan 26, 2026
564e46d
#1823 more test fixes [skip ci]
arporter Jan 26, 2026
134cd05
#1823 fix lint [skip ci]
arporter Jan 26, 2026
06341f7
#1823 WIP fixing tests [skip ci]
arporter Jan 26, 2026
0230c2f
#1823 more test fixing
arporter Jan 27, 2026
8fec073
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Jan 27, 2026
240f86d
#1823 WIP fixing examples [skip ci]
arporter Jan 27, 2026
b269f7a
#1823 add docstrings to new mixin
arporter Jan 27, 2026
5a88b29
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Feb 2, 2026
9d8ac4a
#1823 begin adding new tests [skip ci]
arporter Feb 2, 2026
1c07cb1
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Feb 4, 2026
2e0dbc1
#1823 get coverage of new mixin
arporter Feb 4, 2026
f73cd68
#1823 remove unused/unreachable code and reinstate some tests
arporter Feb 4, 2026
2eaf62c
#1823 allow for ContainerSymbol from which kernel is imported to be i…
arporter Feb 4, 2026
7d8ada3
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Feb 11, 2026
c5e1211
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Feb 19, 2026
001e8e5
#3294 update documentation
arporter Feb 19, 2026
24072f4
#3294 rm kernel-naming option from source
arporter Feb 19, 2026
7c2e8e8
#1823 updates for review
arporter Feb 19, 2026
41f84da
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Feb 19, 2026
b68c40d
#1823 rm _modified property of CodedKern
arporter Feb 19, 2026
192c0f7
#1823 update kernel-transformation documentation
arporter Feb 20, 2026
63bd9a9
#1823 fix tabs and update command-line help message
arporter Feb 20, 2026
914b67d
Merge branch 'master' into 1823_transform_inlined_kerns_only
arporter Feb 24, 2026
20401f1
#1823 update lfric practical
arporter Feb 24, 2026
80a1b91
#1823 fix lfric/eg15
arporter Feb 24, 2026
4970ecf
#1823 tighten-up checks and make general purpose
arporter Feb 24, 2026
26c1a18
#1823 rename and move mixin
arporter Feb 24, 2026
6bec686
#1823 complete renaming of class and method
arporter Feb 24, 2026
a50cd28
#1823 fix all tests after generalisation
arporter Feb 24, 2026
93413b1
#2381 revert change to GOceanOpenCLTrans and fix KernelModuleInlineTr…
arporter Feb 24, 2026
0949296
#2381 linting
arporter Feb 24, 2026
eba9f80
#1823 add test and fix issue with symbols referred to in copies of sy…
arporter Feb 25, 2026
6f9b1e0
#1823 WIP fixing imports from symbols not in table [skip ci]
arporter Feb 26, 2026
42e80bb
#1823 more work on respecting symbol object identity [skip ci]
arporter Feb 26, 2026
2dc3d80
#1823 WIP fixing tests [skip ci]
arporter Feb 27, 2026
3742d08
#1823 get all LFRic tests passing [skip ci]
arporter Feb 27, 2026
e866f1d
#1823 WIP fixing non-lfric tests [skip ci]
arporter Feb 27, 2026
fcbb368
#1823 ensure precision symbol declared for quadrature/evaluator [skip…
arporter Mar 2, 2026
bc491c6
#1823 ensure LFRic kernel stub has LFRicSymbolTable
arporter Mar 2, 2026
9022650
#1734 revert unrelated modifications
arporter Mar 2, 2026
6746f7b
#1734 fix missed mod_inline in test
arporter Mar 2, 2026
a96a1d5
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 2, 2026
e6a5247
#1734 fix merge errors
arporter Mar 2, 2026
376b7f4
#1734 fix tests affected by movement of kernel import
arporter Mar 2, 2026
5907d52
#1734 fix LFRic example
arporter Mar 2, 2026
f840c1f
#1734 tidy-up symbol table changes [skip ci]
arporter Mar 2, 2026
0a0ef9c
#1734 refine change to KernCallArgList
arporter Mar 2, 2026
8c73f9b
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 2, 2026
b0f5696
#1734 fix coverage
arporter Mar 3, 2026
bfae16c
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 3, 2026
4f7630e
#1734 tidy comment
arporter Mar 3, 2026
23b47b2
#1734 experiment with moving functionality into ScopingNode [skip ci]
arporter Mar 3, 2026
f73ea88
#1734 mv functionality into SymbolTable and test
arporter Mar 4, 2026
fb27241
#1734 revert psyGen test changes to get cov
arporter Mar 4, 2026
4e12af4
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 10, 2026
7034130
#1734 improvements for review
arporter Mar 10, 2026
5ca70e0
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 10, 2026
7c6c703
#1734 updates for review
arporter Mar 12, 2026
114204b
#1734 add test with nested scopes
arporter Mar 12, 2026
a93124b
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 12, 2026
15ba875
Merge branch 'master' into 1734_stricter_symbols
arporter Mar 19, 2026
f32d948
#1734 try adding assert in branch
arporter Mar 19, 2026
b4408d2
#1734 simplify and add more comments
arporter Mar 20, 2026
9c02c04
#1734 minor updates for review
arporter Mar 20, 2026
1116b1a
#1734 revert specification of AutomaticInterface
arporter Mar 20, 2026
2413b2c
Merge remote-tracking branch 'origin/master' into 1734_stricter_symbols
sergisiso Mar 23, 2026
a3d53d1
#1734 Update changelog and change import order
sergisiso Mar 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions examples/lfric/eg16/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@
Config.get()

# Add LFRic precision symbols and the module in which they are
# contained to the symbol table
# contained to the symbol table.
SYMBOL_TABLE = SymbolTable()
for symbol in [LFRicTypes("I_DEF"), LFRicTypes("R_DEF"),
LFRicTypes("constants_mod")]:
for symbol in [LFRicTypes("constants_mod"),
LFRicTypes("I_DEF"),
LFRicTypes("R_DEF")]:
SYMBOL_TABLE.add(symbol)

# Create LFRic ndf and undf symbols and add them to the symbol table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
and move it to psyir/transformations/.

'''
from typing import List
Comment thread
sergisiso marked this conversation as resolved.
import warnings

from psyclone.psyGen import Transformation, CodedKern
Expand Down Expand Up @@ -252,7 +251,7 @@ def _validate_schedule(self, node, kname, kern_or_call, kernel_schedule):

@staticmethod
def _prepare_code_to_inline(
routines_to_inline: List[Routine]) -> List[Routine]:
routines_to_inline: list[Routine]) -> list[Routine]:
'''Prepare the PSyIR tree to inline by bringing in to the subroutine
all referenced symbols so that the implementation is self contained.

Expand All @@ -262,7 +261,6 @@ def _prepare_code_to_inline(
:param routines_to_inline: the routine(s) to module-inline.

:returns: the updated routine(s) to module-inline.
:rtype: list[:py:class:`psyclone.psyir.node.Routine`]

'''
# pylint: disable=too-many-branches
Expand Down Expand Up @@ -291,15 +289,21 @@ def _prepare_code_to_inline(
symbols_to_bring_in = set()
for symbol in all_symbols:
if symbol.is_unresolved or symbol.is_import:
# This symbol is already in the symbol table, but adding it
# to the 'symbols_to_bring_in' will make the next step
# bring into the subroutine all modules that it could come
# from.
# This symbol may already be in the local symbol table,
# but adding it to the 'symbols_to_bring_in' will make the
# next step bring into the subroutine all modules that it
# could come from.
symbols_to_bring_in.add(symbol)

# Bring the selected symbols inside the subroutine
for symbol in symbols_to_bring_in:
if symbol.name not in code_to_inline.symbol_table:
if symbol.is_import:
# We must update its import interface (to ensure it
# references a ContainerSymbol in the correct scope)
# before it can be added to the table.
code_to_inline.symbol_table.update_import_interface(
symbol)
code_to_inline.symbol_table.add(symbol)
# And when necessary the modules where they come from
if symbol.is_unresolved:
Expand Down
30 changes: 18 additions & 12 deletions src/psyclone/domain/lfric/kern_call_arg_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
ArrayReference, Reference, StructureReference)
from psyclone.psyir.symbols import (
DataSymbol, DataTypeSymbol, UnresolvedType, ContainerSymbol,
ImportInterface, ScalarType, ArrayType, UnsupportedFortranType,
ImportInterface, ScalarType, ArrayType, Symbol, UnsupportedFortranType,
ArgumentInterface)

# psyir has classes created at runtime
Expand Down Expand Up @@ -93,20 +93,20 @@ def __init__(self, kern):
self._nqp_positions = []
self._ndf_positions = []

def get_user_type(self, module_name, user_type, name, tag=None):
def get_user_type(self, module_name: str,
user_type: str, name: str,
tag: Optional[str] = None) -> Symbol:
# pylint: disable=too-many-arguments
'''Returns the symbol for a user-defined type. If required, the
required import statements will all be generated.
source ContainerSymbols will be created too.

:param str module_name: the name of the module from which the \
:param module_name: the name of the module from which the
user-defined type must be imported.
:param str user_type: the name of the user-defined type.
:param str name: the name of the variable to be used in the Reference.
:param Optional[str] tag: tag to use for the variable, defaults to \
the name
:param user_type: the name of the user-defined type.
:param name: the name of the variable to be used in the Reference.
:param tag: tag to use for the variable, defaults to the name

:return: the symbol that is used in the reference
:rtype: :py:class:`psyclone.psyir.symbols.Symbol`

'''
if not tag:
Expand All @@ -119,12 +119,18 @@ def get_user_type(self, module_name, user_type, name, tag=None):
pass

# The symbol does not exist already. So we potentially need to
# create the import statement for the type:
# create the ContainerSymbol for the import for the type:
try:
# Check if the module is already declared:
module = self._symtab.lookup(module_name)
# Get the symbol table in which the module is declared:
mod_sym_tab = module.find_symbol_table(self._kern)
# Get the symbol table in which the module is declared. Check
# the current table first:
if module in self._symtab.symbols:
mod_sym_tab = self._symtab
Comment thread
sergisiso marked this conversation as resolved.
Outdated
else:
# Otherwise, we have to search for the table.
mod_sym_tab = module.find_symbol_table(self._symtab.node)

except KeyError:
module = self._symtab.new_symbol(module_name,
symbol_type=ContainerSymbol)
Expand Down
29 changes: 18 additions & 11 deletions src/psyclone/domain/lfric/lfric_kern.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@
from psyclone.psyir.nodes import (
Loop, Literal, Reference, KernelSchedule, Container, Routine)
from psyclone.psyir.symbols import (
DataSymbol, GenericInterfaceSymbol, ScalarType, ArrayType, DataTypeSymbol,
UnresolvedType, ContainerSymbol, INTEGER_TYPE, UnresolvedInterface,
UnsupportedFortranType)
ArgumentInterface, ArrayType, ContainerSymbol, DataSymbol, DataTypeSymbol,
GenericInterfaceSymbol, ImportInterface, ScalarType, UnresolvedType,
INTEGER_TYPE, UnsupportedFortranType)


class LFRicKern(CodedKern):
Expand Down Expand Up @@ -334,13 +334,14 @@ def _setup(self,
f"Evaluator shape(s) {list(invalid_shapes)} is/are not "
f"recognised. Must be one of {const.VALID_EVALUATOR_SHAPES}.")

# If this kernel operates into the halo then it must be passed a
# If this kernel operates into the halo and distributed-memory is
# enabled then it must be passed a
# halo depth. This is currently restricted to being either a simple
# variable name or a literal value.
freader = FortranReader()
invoke_schedule = self.ancestor(InvokeSchedule)
symtab = invoke_schedule.symbol_table if invoke_schedule else None
if "halo" in ktype.iterates_over:
if "halo" in ktype.iterates_over and Config.get().distributed_memory:
self._halo_depth = freader.psyir_from_expression(
args[-1].text.lower(), symbol_table=symtab)
if isinstance(self._halo_depth, Reference):
Expand All @@ -350,8 +351,10 @@ def _setup(self,
if not hasattr(sym, "datatype"):
self._halo_depth.symbol.specialise(
DataSymbol,
datatype=LFRicTypes("LFRicIntegerScalarDataType")())

datatype=LFRicTypes("LFRicIntegerScalarDataType")(),
interface=ArgumentInterface())
if symtab:
symtab.append_argument(self._halo_depth.symbol)
# Check that compute-annexed-dofs is False if the kernel must operate
# only on owned entities.
api_conf = Config.get().api_conf()
Expand Down Expand Up @@ -401,19 +404,21 @@ def _setup(self,

qr_arg = args[idx]
quad_map = const.QUADRATURE_TYPE_MAP[shape]

# Use the InvokeSchedule or Stub symbol_table that we obtained
# earlier to create a unique symbol name
if qr_arg.varname:
# If we have a name for the qr argument, we are dealing with
# an Invoke
mod_name = quad_map["module"]
mod_sym = symtab.find_or_create(
mod_name, symbol_type=ContainerSymbol)
tag = "AlgArgs_" + qr_arg.text
qr_sym = symtab.find_or_create(
qr_arg.varname, tag=tag, symbol_type=DataSymbol,
datatype=symtab.find_or_create(
quad_map["type"], symbol_type=DataTypeSymbol,
datatype=UnresolvedType(),
interface=UnresolvedInterface())
interface=ImportInterface(mod_sym))
)
qr_name = qr_sym.name
else:
Expand Down Expand Up @@ -758,7 +763,8 @@ def gen_stub(self) -> Container:
stub_module = Container(self._base_name+"_mod")

# Create the subroutine
stub_routine = Routine.create(self._base_name+"_code")
stub_routine = Routine.create(self._base_name+"_code",
symbol_table=LFRicSymbolTable())
stub_module.addchild(stub_routine)
self._stub_symbol_table = stub_routine.symbol_table

Expand Down Expand Up @@ -844,7 +850,8 @@ class creates the PSyIR schedule(s) on first invocation which is then
for name in names:
rt_psyir = container.find_routine_psyir(name,
allow_private=True)
routines.append(rt_psyir)
if rt_psyir:
routines.append(rt_psyir)

# Otherwise, get the PSyIR Kernel Schedule(s) from the original
# parse tree.
Expand Down
4 changes: 2 additions & 2 deletions src/psyclone/domain/lfric/lfric_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
Call, BinaryOperation, ArrayOfStructuresReference, Directive, DataNode,
Node, Routine)
from psyclone.psyir.symbols import (
DataSymbol, INTEGER_TYPE, UnresolvedType, UnresolvedInterface)
AutomaticInterface, DataSymbol, INTEGER_TYPE, UnresolvedType)


class LFRicLoop(PSyLoop):
Expand Down Expand Up @@ -951,7 +951,7 @@ def gen_mark_halos_clean_dirty(self):
field.proxy_name,
symbol_type=DataSymbol,
datatype=UnresolvedType(),
interface=UnresolvedInterface())
interface=AutomaticInterface())
# Avoid circular import
# pylint: disable=import-outside-toplevel
from psyclone.lfric import HaloWriteAccess
Expand Down
13 changes: 2 additions & 11 deletions src/psyclone/domain/lfric/lfric_psy.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,9 @@


from psyclone.configuration import Config
from psyclone.domain.lfric import (LFRicConstants, LFRicSymbolTable,
LFRicInvokes)
from psyclone.domain.lfric import LFRicSymbolTable, LFRicInvokes
from psyclone.psyGen import PSy
from psyclone.psyir.nodes import ScopingNode
from psyclone.psyir.symbols import ContainerSymbol


class LFRicPSy(PSy):
Expand All @@ -67,14 +65,7 @@ def __init__(self, invoke_info):
# TODO #1954: Remove the protected access using a factory
ScopingNode._symbol_table_class = LFRicSymbolTable
Config.get().api = "lfric"
PSy.__init__(self, invoke_info)

# Add a wildcard "constants_mod" import at the Container level
# since kinds are often disconnected.
const = LFRicConstants()
const_mod = const.UTILITIES_MOD_MAP["constants"]["module"]
self.container.symbol_table.add(
ContainerSymbol(const_mod, wildcard_import=True))
super().__init__(invoke_info)

# Then initialise the Invokes
self._invokes = LFRicInvokes(invoke_info.calls, self)
Expand Down
Loading
Loading