Reference Guide  2.5.0
meta_args_metadata.py
1 # -----------------------------------------------------------------------------
2 # BSD 3-Clause License
3 #
4 # Copyright (c) 2022-2024, Science and Technology Facilities Council
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
9 #
10 # * Redistributions of source code must retain the above copyright notice, this
11 # list of conditions and the following disclaimer.
12 #
13 # * Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 #
17 # * Neither the name of the copyright holder nor the names of its
18 # contributors may be used to endorse or promote products derived from
19 # this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 # -----------------------------------------------------------------------------
34 # Author R. W. Ford, STFC Daresbury Lab
35 
36 '''Module containing the MetaArgsMetadata class which captures
37 the values for the LFRic kernel meta_args metadata.
38 
39 '''
40 from fparser.two import Fortran2003
41 from fparser.two.utils import walk
42 
44  ColumnwiseOperatorArgMetadata
46  CommonMetaArgMetadata
48  CommonDeclarationMetadata
49 from psyclone.domain.lfric.kernel.field_arg_metadata import FieldArgMetadata
51  FieldVectorArgMetadata
53  InterGridArgMetadata
55  InterGridVectorArgMetadata
57  OperatorArgMetadata
58 from psyclone.domain.lfric.kernel.scalar_arg_metadata import ScalarArgMetadata
59 from psyclone.parse.utils import ParseError
60 
61 
63  '''Class to capture the values of the LFRic kernel
64  meta_args metadata. This class supports the creation,
65  modification and Fortran output of this metadata.
66 
67  meta_args metadata specifies information about data that the
68  kernel code expects to be passed to it via its argument list.
69 
70  :param meta_args_args: a list of meta_args arguments.
71  :type meta_args_args: List[:py:class:`psyclone.domain.lfric.kernel.\
72  CommonMetaArgMetadata`]
73 
74  '''
75  def __init__(self, meta_args_args):
76  super().__init__()
77  self.meta_args_argsmeta_args_argsmeta_args_argsmeta_args_args = meta_args_args
78 
79  def fortran_string(self):
80  '''
81  :returns: the meta_args metadata as Fortran.
82  :rtype: str
83  '''
84  return self.type_declaration_stringtype_declaration_string(
85  "ARG_TYPE", "META_ARGS", self._meta_args_args_meta_args_args)
86 
87  @staticmethod
88  def create_from_fparser2(fparser2_tree):
89  '''Create an instance of MetaArgsMetadata from an fparser2
90  tree.
91 
92  :param fparser2_tree: fparser2 tree capturing the meta \
93  args metadata.
94  :type fparser2_tree: :py:class:`fparser.two.Fortran2003.\
95  Data_Component_Def_Stmt`
96 
97  :returns: an instance of MetaArgsMetadata.
98  :rtype: :py:class:`psyclone.domain.lfric.kernel.\
99  MetaArgsMetadata`
100 
101  :raises ParseError: if an unknown MetaArgsArgMetadata argument \
102  is found.
103 
104  '''
105  MetaArgsMetadata.get_derived_array_declaration(
106  fparser2_tree, "ARG_TYPE", "META_ARGS")
107  args = walk(fparser2_tree, Fortran2003.Ac_Value_List)
108  meta_args_args = []
109  for meta_arg in args[0].children:
110  form = meta_arg.children[1].children[0].tostr()
111  form = form.lower()
112  if form == "gh_scalar":
113  arg = ScalarArgMetadata.create_from_fparser2(meta_arg)
114  elif form == "gh_operator":
115  arg = OperatorArgMetadata.create_from_fparser2(meta_arg)
116  elif form == "gh_columnwise_operator":
117  arg = ColumnwiseOperatorArgMetadata.create_from_fparser2(
118  meta_arg)
119  elif "gh_field" in form:
120  vector_arg = "*" in form
121  nargs = len(meta_arg.children[1].children)
122  intergrid_arg = False
123  if nargs == 5:
124  fifth_arg = meta_arg.children[1].children[4]
125  intergrid_arg = (
126  fifth_arg.children and
127  fifth_arg.children[0].string.lower() == "mesh_arg")
128 
129  if intergrid_arg and vector_arg:
130  arg = InterGridVectorArgMetadata.create_from_fparser2(
131  meta_arg)
132  elif intergrid_arg and not vector_arg:
133  arg = InterGridArgMetadata.create_from_fparser2(meta_arg)
134  elif vector_arg and not intergrid_arg:
135  arg = FieldVectorArgMetadata.create_from_fparser2(meta_arg)
136  else:
137  arg = FieldArgMetadata.create_from_fparser2(meta_arg)
138  else:
139  raise ParseError(
140  f"Expected a 'meta_arg' entry to be a "
141  f"field, a scalar or an operator, but found "
142  f"'{meta_arg}'.")
143  meta_args_args.append(arg)
144  return MetaArgsMetadata(meta_args_args)
145 
146  @property
147  def meta_args_args(self):
148  '''
149  :returns: a list of meta args argument objects.
150  :rtype: List[:py:class:`psyclone.domain.lfric.kernel.\
151  CommonArg`]
152  '''
153  return self._meta_args_args_meta_args_args[:]
154 
155  @meta_args_args.setter
156  def meta_args_args(self, values):
157  '''
158  :param values: set the meta_args metadata to the \
159  supplied list of values.
160  :type values: List[:py:class:`psyclone.domain.lfric.kernel.\
161  CommonArg`]
162 
163  '''
164  self.validate_listvalidate_list(values, CommonMetaArgMetadata)
165  # Take a copy of the list so that it can't be modified
166  # externally.
167  self._meta_args_args_meta_args_args = values[:]
168 
169 
170 __all__ = ["MetaArgsMetadata"]