Reference Guide  2.5.0
shapes_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 ShapesMetadata class which captures the
37 values for the LFRic kernel GH_SHAPE metadata.
38 
39 '''
40 from fparser.two import Fortran2003
41 
42 from psyclone.domain.lfric import LFRicConstants
44  CommonDeclarationMetadata
45 
46 
48  '''Class to capture the values of the LFRic kernel GH_SHAPE metadata.
49  This class supports the creation, modification and Fortran output
50  of this metadata.
51 
52  If an LFRic kernel requires basis or differential-basis functions
53  then the metadata must also specify the set of points on which
54  these functions are required. This information is provided by the
55  GH_SHAPE component of the metadata.
56 
57  :param shapes: a list of shape values
58  :type shapes: List[str]
59 
60  '''
61  def __init__(self, shapes):
62  super().__init__()
63  self.shapesshapesshapesshapes = shapes
64 
65  def fortran_string(self):
66  '''
67  :returns: the shapes metadata as Fortran.
68  :rtype: str
69  '''
70  if len(self.shapesshapesshapesshapes) == 1:
71  return ShapesMetadata.scalar_declaration_string(
72  "INTEGER", "GH_SHAPE", self.shapesshapesshapesshapes[0])
73  return ShapesMetadata.array_declaration_string(
74  "INTEGER", "GH_SHAPE", self.shapesshapesshapesshapes)
75 
76  @staticmethod
77  def create_from_fparser2(fparser2_tree):
78  '''Create an instance of ShapesMetadata from an fparser2 tree.
79 
80  LFRic shape metadata can have a scalar and array form. Two
81  versions of the array form are supported:
82  ::
83 
84  integer :: gh_shape = gh_quadrature_face
85  integer :: gh_shape(2) = (/ gh_quadrature_face, gh_evaluator /)
86  integer, dimension(2) :: gh_shape = &
87  (/ gh_quadrature_face, gh_evaluator /)
88 
89  :param fparser2_tree: fparser2 tree capturing the shapes metadata
90  :type fparser2_tree: :py:class:`fparser.two.Fortran2003.\
91  Data_Component_Def_Stmt`
92 
93  :returns: an instance of ShapesMetadata.
94  :rtype: :py:class:`psyclone.domain.lfric.kernel.ShapesMetadata`
95 
96  '''
97  # As both scalar and array forms are supported we need the
98  # validation from both get_intrinsic_array_declaration and
99  # get_intrinsic_scalar_declaration. However, we can't call
100  # these functions separately as both might raise an exception
101  # and we won't know which exception to return. Instead we call
102  # the validation that is common to both first and then test
103  # for an array declaration to determine whether to call the
104  # array or scalar validation.
105  ShapesMetadata.validate_node(
106  fparser2_tree, Fortran2003.Data_Component_Def_Stmt)
107  ShapesMetadata.validate_name_value(
108  fparser2_tree, "GH_SHAPE")
109 
110  const = LFRicConstants()
111  valid_values = const.VALID_EVALUATOR_SHAPES
112 
113  component_decl_list = fparser2_tree.children[2]
114  gh_shape_declaration = component_decl_list.children[0]
115  if fparser2_tree.children[1] or gh_shape_declaration.children[1]:
116  # This is not the scalar form so check for the array form.
117  shapes_list = ShapesMetadata.get_intrinsic_array_declaration(
118  fparser2_tree, "INTEGER", "GH_SHAPE", valid_values)
119  else:
120  # Check for the scalar form.
121  shapes_value = ShapesMetadata.\
123  fparser2_tree, "INTEGER", "GH_SHAPE", valid_values)
124  shapes_list = [shapes_value]
125 
126  return ShapesMetadata(shapes_list)
127 
128  @property
129  def shapes(self):
130  '''
131  :returns: a list of shape values
132  :rtype: List[str]
133  '''
134  # Return a copy of the list so it can't be modified
135  # externally.
136  return self._shapes_shapes[:]
137 
138  @shapes.setter
139  def shapes(self, values):
140  '''
141  :param values: set the shapes metdata to the supplied list of \
142  values.
143  :type values: List[str]
144  '''
145  const = LFRicConstants()
146  ShapesMetadata.validate_list(values, str)
147  for value in values:
148  ShapesMetadata.validate_scalar_value(
149  value, const.VALID_EVALUATOR_SHAPES, "shape")
150  # Take a copy of the list so that it can't be modified
151  # externally. Also make all values lower case.
152  self._shapes_shapes = [value.lower() for value in values]
153 
154 
155 __all__ = ["ShapesMetadata"]