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

2460 DynamoPSy split & rename #2461

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion doc/user_guide/dynamo0p3_topclasses.dot
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ rankdir=BT
"20" [label="{LFRicInvoke|\l|arg_for_funcspace()\lfield_on_space()\lgen_code()\lis_coloured()\lunique_fss()\lunique_proxy_declarations()\l}", shape="record"];
"21" [label="{LFRicInvokeSchedule|\l|view()\l}", shape="record"];
"35" [label="{DynamoInvokes|\l|}", shape="record"];
"36" [label="{DynamoPSy|\l|}", shape="record"];
"36" [label="{LFRicPSy|\l|}", shape="record"];
"45" [label="{Invoke|\l|first_access()\lgen()\lgen_code()\lunique_declarations()\lunique_declns_by_intent()\l}", shape="record", style=filled, fillcolor="antiquewhite"];
"46" [label="{InvokeSchedule|\l|gen_code()\lview()\l}", shape="record"];
"47" [label="{Invokes|\l|gen_code()\lgen_ocl_init()\lget()\l}", shape="record", style=filled, fillcolor="antiquewhite"];
Expand Down
2 changes: 1 addition & 1 deletion doc/user_guide/dynamo0p3_topclasses.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions examples/lfric/eg14/acc_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ def trans(psy):
transformed through the addition of a routine directive.

:param psy: the PSy object containing the invokes to transform.
:type psy: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:type psy: :py:class:`psyclone.domain.lfric.LFRicPSy`

:returns: the transformed PSy object.
:rtype: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:rtype: :py:class:`psyclone.domain.lfric.LFRicPSy`

'''
const = LFRicConstants()
Expand Down
6 changes: 3 additions & 3 deletions examples/lfric/eg2/loop_fuse_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ def trans(psy):
sake of this example we use the 'same_space' option to tell the
transformation that this is safe to do.

:param psy: the PSy object that PSyclone has constructed for the \
:param psy: the PSy object that PSyclone has constructed for the
'invoke'(s) found in the Algorithm file.
:type psy: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:type psy: :py:class:`psyclone.domain.lfric.LFRicPSy`

:returns: the transformed PSy object.
:rtype: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:rtype: :py:class:`psyclone.domain.lfric.LFRicPSy`

'''
print(psy.gen)
Expand Down
6 changes: 3 additions & 3 deletions examples/lfric/eg2/module_inline_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ def trans(psy):
PSyclone transformation routine. This is an example which module-inlines
the kernel used in the second 'invoke' in the supplied PSy object.

:param psy: the PSy object that PSyclone has constructed for the \
:param psy: the PSy object that PSyclone has constructed for the
'invoke'(s) found in the Algorithm file.
:type psy: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:type psy: :py:class:`psyclone.domain.lfric.LFRicPSy`

:returns: the transformed PSy object.
:rtype: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:rtype: :py:class:`psyclone.domain.lfric.LFRicPSy`

'''
invokes = psy.invokes
Expand Down
6 changes: 3 additions & 3 deletions examples/lfric/eg2/print_psyir_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ def trans(psy):
PSyclone transformation routine. This is an example which only prints
information about the object with which it has been supplied.

:param psy: the PSy object that PSyclone has constructed for the \
:param psy: the PSy object that PSyclone has constructed for the
'invoke'(s) found in the Algorithm file.
:type psy: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:type psy: :py:class:`psyclone.domain.lfric.LFRicPSy`

:returns: the supplied PSy object unmodified.
:rtype: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:rtype: :py:class:`psyclone.domain.lfric.LFRicPSy`

'''
print("Supplied code has Invokes: ", psy.invokes.names)
Expand Down
2 changes: 2 additions & 0 deletions src/psyclone/domain/lfric/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
from psyclone.domain.lfric.lfric_scalar_args import LFRicScalarArgs
from psyclone.domain.lfric.lfric_loop_bounds import LFRicLoopBounds
from psyclone.domain.lfric.lfric_kern_metadata import LFRicKernMetadata
from psyclone.domain.lfric.lfric_psy import LFRicPSy
from psyclone.domain.lfric.lfric_invoke_schedule import LFRicInvokeSchedule
from psyclone.domain.lfric.lfric_dofmaps import LFRicDofmaps
from psyclone.domain.lfric.lfric_stencils import LFRicStencils
Expand All @@ -97,6 +98,7 @@
'LFRicKernMetadata',
'LFRicLoop',
'LFRicLoopBounds',
'LFRicPSy',
'LFRicRunTimeChecks',
'LFRicScalarArgs',
'LFRicStencils',
Expand Down
2 changes: 1 addition & 1 deletion src/psyclone/domain/lfric/lfric_invokes.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class LFRicInvokes(Invokes):
information.
:type alg_calls: List[:py:class:`psyclone.parse.algorithm.InvokeCall`]
:param psy: The PSy object containing this LFRicInvokes object.
:type psy: :py:class:`psyclone.dynamo0p3.DynamoPSy`
:type psy: :py:class:`psyclone.domain.lfric.LFRicPSy`

'''
def __init__(self, alg_calls, psy):
Expand Down
183 changes: 183 additions & 0 deletions src/psyclone/domain/lfric/lfric_psy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# -----------------------------------------------------------------------------
# BSD 3-Clause License
#
# Copyright (c) 2017-2023, Science and Technology Facilities Council.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# -----------------------------------------------------------------------------
# Authors R. W. Ford, A. R. Porter and S. Siso, STFC Daresbury Lab
# Modified I. Kavcic, A. Coughtrie, L. Turner and O. Brunt, Met Office
# Modified J. Henrichs, Bureau of Meteorology
# Modified A. B. G. Chalk and N. Nobre, STFC Daresbury Lab

''' This module creates an LFRic-specific Invokes object which controls all
the required invocation calls. It also overrides the PSy gen method so
that LFRic-specific PSy module code is generated.
'''

from collections import OrderedDict

from psyclone.configuration import Config
from psyclone.domain.lfric import (LFRicConstants, LFRicSymbolTable,
LFRicInvokes)
from psyclone.f2pygen import ModuleGen, UseGen, PSyIRGen
from psyclone.psyGen import PSy, InvokeSchedule
from psyclone.psyir.nodes import ScopingNode


class LFRicPSy(PSy):
'''
The LFRic-specific PSy class. This creates an LFRic-specific
Invokes object (which controls all the required invocation calls).
It also overrides the PSy gen method so that we generate
LFRic-specific PSy module code.

:param invoke_info: object containing the required invocation information
for code optimisation and generation.
:type invoke_info: :py:class:`psyclone.parse.algorithm.FileInfo`

'''
def __init__(self, invoke_info):
# Make sure the scoping node creates LFRicSymbolTables
# TODO #1954: Remove the protected access using a factory
ScopingNode._symbol_table_class = LFRicSymbolTable
PSy.__init__(self, invoke_info)
self._invokes = LFRicInvokes(invoke_info.calls, self)
# Initialise the dictionary that holds the names of the required
# LFRic constants, data structures and data structure proxies for
# the "use" statements in modules that contain PSy-layer routines.
const = LFRicConstants()
const_mod = const.UTILITIES_MOD_MAP["constants"]["module"]
infmod_list = [const_mod]
# Add all field and operator modules that might be used in the
# algorithm layer. These do not appear in the code unless a
# variable is added to the "only" part of the
# '_infrastructure_modules' map.
for data_type_info in const.DATA_TYPE_MAP.values():
infmod_list.append(data_type_info["module"])

# This also removes any duplicates from infmod_list
self._infrastructure_modules = OrderedDict(
(k, set()) for k in infmod_list)

kind_names = set()

# The infrastructure declares integer types with default
# precision so always add this.
api_config = Config.get().api_conf("dynamo0.3")
kind_names.add(api_config.default_kind["integer"])

# Datatypes declare precision information themselves. However,
# that is not the case for literals. Therefore deal
# with these separately here.
for invoke in self.invokes.invoke_list:
schedule = invoke.schedule
for kernel in schedule.kernels():
for arg in kernel.args:
if arg.is_literal:
kind_names.add(arg.precision)
# Add precision names to the dictionary storing the required
# LFRic constants.
self._infrastructure_modules[const_mod] = kind_names

@property
def name(self):
'''
:returns: a name for the PSy layer. This is used as the PSy module
name. We override the default value as the Met Office
prefer "_psy" to be appended, rather than prepended.
:rtype: str

'''
return self._name + "_psy"

@property
def orig_name(self):
'''
:returns: the unmodified PSy-layer name.
:rtype: str

'''
return self._name

@property
def infrastructure_modules(self):
'''
:returns: the dictionary that holds the names of the required
LFRic infrastructure modules to create "use"
statements in the PSy-layer modules.
:rtype: dict of set

'''
return self._infrastructure_modules

@property
def gen(self):
'''
Generate PSy code for the LFRic (Dynamo0.3) API.

:returns: root node of generated Fortran AST.
:rtype: :py:class:`psyir.nodes.Node`

'''
# Create an empty PSy layer module
psy_module = ModuleGen(self.name)

# If the container has a Routine that is not an InvokeSchedule
# it should also be added to the generated module.
for routine in self.container.children:
if not isinstance(routine, InvokeSchedule):
psy_module.add(PSyIRGen(psy_module, routine))

# Add all invoke-specific information
self.invokes.gen_code(psy_module)

# Include required constants and infrastructure modules. The sets of
# required LFRic data structures and their proxies are updated in
# the relevant field and operator subclasses of LFRicCollection.
# Here we sort the inputs in reverse order to have "_type" before
# "_proxy_type" and "operator_" before "columnwise_operator_".
# We also iterate through the dictionary in reverse order so the
# "use" statements for field types are before the "use" statements
# for operator types.
for infmod in reversed(self._infrastructure_modules):
if self._infrastructure_modules[infmod]:
infmod_types = sorted(
list(self._infrastructure_modules[infmod]), reverse=True)
psy_module.add(UseGen(psy_module, name=infmod,
only=True, funcnames=infmod_types))

# Return the root node of the generated code
return psy_module.root


# ---------- Documentation utils -------------------------------------------- #
# The list of module members that we wish AutoAPI to generate
# documentation for. (See https://psyclone-ref.readthedocs.io)
__all__ = ['LFRicPSy']
Loading