Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2711 DoF Kernel Code Generation #2712

Open
wants to merge 56 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6d7cfb7
#2711 Loops now use undf_name if dofkern
oakleybrunt Sep 16, 2024
10f8a76
#2711 Lint fix
oakleybrunt Sep 16, 2024
5885e78
#2711 dof access added
oakleybrunt Sep 19, 2024
84774d0
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Sep 19, 2024
4c4a631
Merge branch '2711-dof-kernels-code' of github.com:stfc/PSyclone into…
oakleybrunt Sep 19, 2024
ec80a29
#2711 Lint fix
oakleybrunt Sep 19, 2024
d429e90
#2711 More testing for dofkern
oakleybrunt Sep 19, 2024
66bbc6e
#2711 Lint fix
oakleybrunt Sep 19, 2024
a8a06fd
#2711 LFRicBuiltin property is_dofkern return False
oakleybrunt Sep 19, 2024
39c0211
#2711 Retracted docs specifying undf would be bare if dof kern
oakleybrunt Sep 19, 2024
0cadb92
#2711 Remove DoF Kernel notes from docs and add test for multiple writes
oakleybrunt Sep 19, 2024
c118a76
#2711 Docstring updates
oakleybrunt Sep 19, 2024
a91f9a4
#2711 Rename is_dofkern in LFRicKernMetadata to match LFRicKern
oakleybrunt Sep 19, 2024
a688572
#2711 Missed is_user_dofkern switch and updated invalid_iteration_spa…
oakleybrunt Sep 19, 2024
32457c5
Merge branch 'master' into 2711-dof-kernels-code
arporter Sep 20, 2024
23d0278
Â#2711 undf name and documentation comments
oakleybrunt Sep 20, 2024
56be42e
#2711 Removed is_dofkern property
oakleybrunt Sep 20, 2024
ef8225b
#2711 Better testing
oakleybrunt Sep 20, 2024
762fb27
#2711 Lint fix
oakleybrunt Sep 20, 2024
3ba13e6
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Sep 20, 2024
b673896
#2711 Compilation test and missed is_dofkern
oakleybrunt Sep 22, 2024
223f963
#2711 reference outside
oakleybrunt Oct 7, 2024
76155a3
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Oct 7, 2024
681f39a
#2711 Lint fix
oakleybrunt Oct 7, 2024
3f87b2e
#2711 append symbol
oakleybrunt Oct 7, 2024
19a6178
#2711 drop logging for dev
oakleybrunt Oct 7, 2024
77fbb5f
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Oct 8, 2024
f636ce8
#2711 Reverted unknown change to nlayers name
oakleybrunt Oct 8, 2024
0b2f4a3
#2711 Reinstate stubgen invalid iteration space test
oakleybrunt Oct 8, 2024
c305422
#2711 Fix testing
oakleybrunt Oct 8, 2024
a0e8598
#2711 Extra check on dof access for fields in kerncallarglist
oakleybrunt Oct 8, 2024
be372f2
#2711 Lint fix
oakleybrunt Oct 8, 2024
8622d20
#2711 remove stub gen leftovers
oakleybrunt Oct 8, 2024
81ef95c
#2711 Lint fix
oakleybrunt Oct 8, 2024
16361d6
#2711 Remove stubgen LFRicFields dofkern
oakleybrunt Oct 8, 2024
67e8fa3
#2711 Test for DynFunctionSpaces generates correct undf_name
oakleybrunt Oct 9, 2024
47f1a5e
#2711 test undf DynFunctionSpaces
oakleybrunt Oct 9, 2024
2704972
#2711 Another test for coverage
oakleybrunt Oct 9, 2024
70150d3
#2711 Fixed failing test in dofkern_test.py
oakleybrunt Oct 9, 2024
c66a272
#2711 Removed isinstance check
oakleybrunt Oct 11, 2024
c63b724
#2711 Remove unused import
oakleybrunt Oct 11, 2024
29e9f99
#2711 Compilation checks and alpha ordered imports
oakleybrunt Oct 11, 2024
f112777
#2711 Removed bare_undf only - can revert
oakleybrunt Oct 11, 2024
7240a09
#2711 Update dev guide
oakleybrunt Oct 11, 2024
5a9e09c
#2711 Lint fix
oakleybrunt Oct 11, 2024
2e024e9
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Oct 16, 2024
c835cc7
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Oct 16, 2024
0464e5a
#2711 Add field method to KernCallAccArgList
oakleybrunt Oct 16, 2024
8f09184
#2711 Restore append method for field symbol
oakleybrunt Oct 16, 2024
28ad8e6
#2711 Add undf_name property to LFRicKern
oakleybrunt Oct 17, 2024
8df39d0
#2711 Lint Fix
oakleybrunt Oct 17, 2024
42ee334
#2711 Added testing
oakleybrunt Oct 21, 2024
682bfff
#2711 Remove undf from kern args, transformation testing
oakleybrunt Oct 22, 2024
cacc273
#2711 Lint fixes
oakleybrunt Oct 22, 2024
0b80e3d
Merge branch 'master' into 2711-dof-kernels-code
oakleybrunt Oct 22, 2024
681581b
#2711 Testing transformations and multi-kernels
oakleybrunt Oct 22, 2024
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
22 changes: 6 additions & 16 deletions doc/user_guide/dynamo0p3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,6 @@ support for i-first kernels
point the looping (and associated parallelisation) will be put
back into the PSy layer.

.. note:: Support for DoF kernels have not yet been implemented in PSyclone
(see PSyclone issue #1351 for progress).

.. _lfric-user-kernel-rules:

Rules for all User-Supplied Kernels that Operate on Cell-Columns
Expand Down Expand Up @@ -981,9 +978,6 @@ on a ``CELL_COLUMN`` without CMA Operators. Specifically:
Rules for all User-Supplied Kernels that Operate on DoFs (DoF Kernels)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.. note:: Support for DoF kernels have not yet been implemented in PSyclone
(see PSyclone issue #1351 for progress).

Kernels that have ``operates_on = DOF`` and
:ref:`LFRic Built-ins<lfric-built-ins>` overlap significantly in their
scope, and the conventions that DoF Kernels must follow are influenced
Expand Down Expand Up @@ -1015,8 +1009,9 @@ The list of rules for DoF Kernels is as follows:
to do this.) Any scalar arguments must therefore be declared in the metadata
as `GH_READ` - see :ref:`below<lfric-kernel-valid-access>`

6) Kernels must be written to operate on a single DoF, such that single DoFs
can be provided to the Kernel within a loop over the DoFs of a field.
6) Kernels must be written to operate on a single DoF, such that field values
at the same dof location/index can be provided to the Kernel within a loop
over the DoFs of the function space of the field that is being updated.

.. _lfric-api-kernel-metadata:

Expand Down Expand Up @@ -1889,16 +1884,14 @@ operates_on
The fourth type of metadata provided is ``OPERATES_ON``. This
specifies that the Kernel has been written with the assumption that it
is supplied with the specified data for each field/operator argument.
For user-supplied kernels this is currently only permitted to be
``CELL_COLUMN`` or ``DOMAIN``. The possible values for ``OPERATES_ON``
and their interpretation are summarised in the following table:
The possible values for ``OPERATES_ON`` and their interpretation are
summarised in the following table:

=========== =========================================================
operates_on Data passed for each field/operator argument
=========== =========================================================
cell_column Single column of cells
dof Single DoF (currently :ref:`built-ins` only, but see PSyclone
issue #1351)
dof Single DoF
domain All columns of cells
=========== =========================================================

Expand Down Expand Up @@ -2477,9 +2470,6 @@ as the second argument to the kernel (after ``nlayers``).
Rules for DoF Kernels
#####################

.. note:: Support for DoF kernels have not yet been implemented in PSyclone
(see PSyclone issue #1351 for progress).

The rules for kernels that have ``operates_on = DOF`` are similar to those for
general-purpose kernels but, due to the restriction that only fields and
scalars can be passed to them, are much fewer. The full set of rules, along
Expand Down
7 changes: 7 additions & 0 deletions src/psyclone/domain/lfric/function_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ def undf_name(self):
'''
return "undf_" + self.mangled_name

@property
def bare_undf_name(self):
arporter marked this conversation as resolved.
Show resolved Hide resolved
''':returns: undf with no FunctionSpace object name.
:rtype: str
'''
return "undf"

def get_basis_name(self, qr_var=None, on_space=None):
'''
Returns a name for the basis function on this FunctionSpace. If
Expand Down
33 changes: 26 additions & 7 deletions src/psyclone/domain/lfric/kern_call_arg_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from psyclone.core import AccessType, Signature
from psyclone.domain.lfric import ArgOrdering, LFRicConstants
# Avoid circular import:
from psyclone.domain.lfric.lfric_builtins import LFRicBuiltIn
from psyclone.domain.lfric.lfric_types import LFRicTypes
from psyclone.errors import GenerationError, InternalError
from psyclone.psyir.nodes import ArrayReference, Reference, StructureReference
Expand Down Expand Up @@ -218,9 +219,9 @@ def mesh_height(self, var_accesses=None):
'''Add mesh height (nlayers) to the argument list and if supplied
stores this access in var_accesses.

:param var_accesses: optional VariablesAccessInfo instance to store
:param var_accesses: optional VariablesAccessInfo instance to store \
arporter marked this conversation as resolved.
Show resolved Hide resolved
the information about variable accesses.
:type var_accesses:
:type var_accesses: \
:py:class:`psyclone.core.VariablesAccessInfo`

'''
Expand Down Expand Up @@ -380,11 +381,23 @@ def field(self, arg, var_accesses=None):
# Look-up the name of the variable that stores the reference to
# the data in this field.
sym = self._symtab.lookup_with_tag(f"{arg.name}:{suffix}")
# Add the field data array as being read.
self.append(sym.name, var_accesses, var_access_name=sym.name,
mode=arg.access, metadata_posn=arg.metadata_index)

self.psyir_append(Reference(sym))
if self._kern.iterates_over == "dof" and not isinstance(
self._kern, LFRicBuiltIn):
# If dof kernel, add access to the field by dof ref
arporter marked this conversation as resolved.
Show resolved Hide resolved
dof_sym = self._symtab.find_or_create_integer_symbol(
"df", tag="dof_loop_idx")
self.append_array_reference(sym.name, [Reference(dof_sym)],
ScalarType.Intrinsic.INTEGER,
symbol=sym)
# Then append our symbol
name = f"{sym.name}({Reference(dof_sym)})"
arporter marked this conversation as resolved.
Show resolved Hide resolved
self.append(name, var_accesses, var_access_name=sym.name)
else:
# Add the field data array as being read.
self.append(sym.name, var_accesses, var_access_name=sym.name,
mode=arg.access, metadata_posn=arg.metadata_index)
self.psyir_append(Reference(sym))

def stencil_unknown_extent(self, arg, var_accesses=None):
'''Add stencil information to the argument list associated with the
Expand Down Expand Up @@ -611,7 +624,10 @@ def fs_compulsory_field(self, function_space, var_accesses=None):
:py:class:`psyclone.core.VariablesAccessInfo`

'''
sym = self.append_integer_reference(function_space.undf_name)
if self._kern.iterates_over == "dof":
sym = self.append_integer_reference(function_space.bare_undf_name)
else:
sym = self.append_integer_reference(function_space.undf_name)
self.append(sym.name, var_accesses)

map_name = function_space.map_name
Expand All @@ -621,6 +637,9 @@ def fs_compulsory_field(self, function_space, var_accesses=None):
sym = self.append_array_reference(map_name, [":", ":"],
ScalarType.Intrinsic.INTEGER)
self.append(sym.name, var_accesses, var_access_name=sym.name)
elif self._kern.iterates_over == "dof":
# Dofmaps are not required for DoF kernels
pass
else:
# Pass the dofmap for the cell column
cell_name, cell_ref = self.cell_ref_name(var_accesses)
Expand Down
1 change: 1 addition & 0 deletions src/psyclone/domain/lfric/kern_stub_arg_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ def fs_compulsory_field(self, function_space, var_accesses=None):

'''
self.append(function_space.undf_name, var_accesses)

arporter marked this conversation as resolved.
Show resolved Hide resolved
self.append(function_space.map_name, var_accesses)

def basis(self, function_space, var_accesses=None):
Expand Down
2 changes: 1 addition & 1 deletion src/psyclone/domain/lfric/lfric_kern.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,8 @@ def gen_stub(self):
const = LFRicConstants()
supported_operates_on = const.USER_KERNEL_ITERATION_SPACES[:]
# TODO #925 Add support for 'domain' kernels
# TODO #1351 Add suport for 'dof' kernels
supported_operates_on.remove("domain")
arporter marked this conversation as resolved.
Show resolved Hide resolved
# TODO #1351 Add support for 'dof' kernels
supported_operates_on.remove("dof")

# Check operates-on (iteration space) before generating code
Expand Down
3 changes: 3 additions & 0 deletions src/psyclone/domain/lfric/lfric_kern_call_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def create(call, parent=None):
# We still need a loop object though as that is where the logic
# for handling halo exchanges is currently implemented.
loop_type = "null"
elif call.ktype.iterates_over == "dof":
# Loop over dofs within a field.
loop_type = "dof"
else:
# Loop over cells, indicated by an empty string.
loop_type = ""
Expand Down
17 changes: 11 additions & 6 deletions src/psyclone/domain/lfric/lfric_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,8 @@ def load(self, kern):
# Loop bounds
self.set_lower_bound("start")
const = LFRicConstants()
if isinstance(kern, LFRicBuiltIn):
# If the kernel is a built-in/pointwise operation
# then this loop must be over DoFs
if kern.iterates_over == "dof":
# This loop must be over DoFs
if Config.get().api_conf("lfric").compute_annexed_dofs \
and Config.get().distributed_memory \
and not kern.is_reduction:
Expand Down Expand Up @@ -475,14 +474,20 @@ def _upper_bound_fortran(self):
if self._upper_bound_name in ["ndofs", "nannexed"]:
if Config.get().distributed_memory:
if self._upper_bound_name == "ndofs":
result = (f"{self.field.proxy_name_indexed}%"
f"{self.field.ref_name()}%get_last_dof_owned()")
result = (
f"{self.field.proxy_name_indexed}%"
f"{self.field.ref_name()}%get_last_dof_owned()")
else: # nannexed
result = (
f"{self.field.proxy_name_indexed}%"
f"{self.field.ref_name()}%get_last_dof_annexed()")
else:
result = self._kern.undf_name
if isinstance(self._kern, LFRicBuiltIn):
result = self._kern.undf_name
else:
# User-defined dof kernel has undf_name in a different
arporter marked this conversation as resolved.
Show resolved Hide resolved
# location
result = self._field_space.bare_undf_name
return result
if self._upper_bound_name == "ncells":
if Config.get().distributed_memory:
Expand Down
15 changes: 12 additions & 3 deletions src/psyclone/dynamo0p3.py
Original file line number Diff line number Diff line change
Expand Up @@ -1215,10 +1215,16 @@ def __init__(self, kern_or_invoke):
# field proxy and undf is not required.
if self._invoke and self._invoke.field_on_space(function_space):
if not (self._dofs_only and Config.get().distributed_memory):
self._var_list.append(function_space.undf_name)
if not self._invoke.operates_on_dofs_only:
arporter marked this conversation as resolved.
Show resolved Hide resolved
self._var_list.append(function_space.undf_name)
else:
self._var_list.append(function_space.bare_undf_name)
elif self._kernel and \
function_space.field_on_space(self._kernel.arguments):
self._var_list.append(function_space.undf_name)
if not self._kernel.iterates_over == "dof":
arporter marked this conversation as resolved.
Show resolved Hide resolved
self._var_list.append(function_space.undf_name)
else:
self._var_list.append(function_space.bare_undf_name)

def _stub_declarations(self, parent):
'''
Expand Down Expand Up @@ -1295,7 +1301,10 @@ def initialise(self, parent):
# from the field proxy and undf is not required.
if not (self._dofs_only and Config.get().distributed_memory):
if self._invoke.field_on_space(function_space):
undf_name = function_space.undf_name
if self._invoke.operates_on_dofs_only:
arporter marked this conversation as resolved.
Show resolved Hide resolved
undf_name = function_space.bare_undf_name
else:
undf_name = function_space.undf_name
parent.add(AssignGen(parent, lhs=undf_name,
rhs=name + "%" +
arg.ref_name(function_space) +
Expand Down
Loading
Loading