Reference Guide  2.5.0
psyclone.psyGen.DataAccess Class Reference

Public Member Functions

def __init__ (self, arg)
 
def overlaps (self, arg)
 
def reset_coverage (self)
 
def update_coverage (self, arg)
 
def covered (self)
 

Detailed Description

A helper class to simplify the determination of dependencies due to
overlapping accesses to data associated with instances of the
Argument class.

Definition at line 1973 of file psyGen.py.

Constructor & Destructor Documentation

◆ __init__()

def psyclone.psyGen.DataAccess.__init__ (   self,
  arg 
)
Store the argument associated with the instance of this class and
the Call, HaloExchange or GlobalSum (or a subclass thereof)
instance with which the argument is associated.

:param arg: the argument that we are concerned with. An \
argument can be found in a `Kern` a `HaloExchange` or a \
`GlobalSum` (or a subclass thereof)
:type arg: :py:class:`psyclone.psyGen.Argument`

Definition at line 1980 of file psyGen.py.

1980  def __init__(self, arg):
1981  '''Store the argument associated with the instance of this class and
1982  the Call, HaloExchange or GlobalSum (or a subclass thereof)
1983  instance with which the argument is associated.
1984 
1985  :param arg: the argument that we are concerned with. An \
1986  argument can be found in a `Kern` a `HaloExchange` or a \
1987  `GlobalSum` (or a subclass thereof)
1988  :type arg: :py:class:`psyclone.psyGen.Argument`
1989 
1990  '''
1991  # the `psyclone.psyGen.Argument` we are concerned with
1992  self._arg = arg
1993  # The call (Kern, HaloExchange, GlobalSum or subclass)
1994  # instance with which the argument is associated
1995  self._call = arg.call
1996  # initialise _covered and _vector_index_access to keep pylint
1997  # happy
1998  self._covered = None
1999  self._vector_index_access = None
2000  # Now actually set them to the required initial values
2001  self.reset_coverage()
2002 

References psyclone.gocean1p0.GOKernelArgument._arg, psyclone.psyGen.DataAccess._arg, psyclone.psyGen.KernelArgument._arg, psyclone.f2pygen.CallGen._call, psyclone.gocean1p0.GOKernelGridArgument._call, psyclone.psyGen.DataAccess._call, psyclone.psyGen.Argument._call, psyclone.psyGen.DataAccess._covered, psyclone.psyGen.DataAccess._vector_index_access, and psyclone.psyGen.DataAccess.reset_coverage().

Here is the call graph for this function:

Member Function Documentation

◆ covered()

def psyclone.psyGen.DataAccess.covered (   self)
Returns True if all of the data associated with this argument has
been covered by the arguments provided in update_coverage

:return bool: True if all of an argument is covered by \
previous accesses and False if not.

Definition at line 2115 of file psyGen.py.

2115  def covered(self):
2116  '''Returns True if all of the data associated with this argument has
2117  been covered by the arguments provided in update_coverage
2118 
2119  :return bool: True if all of an argument is covered by \
2120  previous accesses and False if not.
2121 
2122  '''
2123  return self._covered
2124 
2125 

References psyclone.psyGen.DataAccess._covered.

◆ overlaps()

def psyclone.psyGen.DataAccess.overlaps (   self,
  arg 
)
Determine whether the accesses to the provided argument overlap
with the accesses of the source argument. Overlap means that
the accesses share at least one memory location. For example,
the arguments both access the 1st index of the same field.

We do not currently deal with accesses to a subset of an
argument (unless it is a vector). This distinction will need
to be added once loop splitting is supported.

:param arg: the argument to compare with our internal argument
:type arg: :py:class:`psyclone.psyGen.Argument`
:return bool: True if there are overlapping accesses between \
              arguments (i.e. accesses share at least one memory \
              location) and False if not.

Definition at line 2003 of file psyGen.py.

2003  def overlaps(self, arg):
2004  '''Determine whether the accesses to the provided argument overlap
2005  with the accesses of the source argument. Overlap means that
2006  the accesses share at least one memory location. For example,
2007  the arguments both access the 1st index of the same field.
2008 
2009  We do not currently deal with accesses to a subset of an
2010  argument (unless it is a vector). This distinction will need
2011  to be added once loop splitting is supported.
2012 
2013  :param arg: the argument to compare with our internal argument
2014  :type arg: :py:class:`psyclone.psyGen.Argument`
2015  :return bool: True if there are overlapping accesses between \
2016  arguments (i.e. accesses share at least one memory \
2017  location) and False if not.
2018 
2019  '''
2020  if self._arg.name != arg.name:
2021  # the arguments are different args so do not overlap
2022  return False
2023 
2024  if isinstance(self._call, HaloExchange) and \
2025  isinstance(arg.call, HaloExchange) and \
2026  (self._arg.vector_size > 1 or arg.vector_size > 1):
2027  # This is a vector field and both accesses come from halo
2028  # exchanges. As halo exchanges only access a particular
2029  # vector, the accesses do not overlap if the vector indices
2030  # being accessed differ.
2031 
2032  # sanity check
2033  if self._arg.vector_size != arg.vector_size:
2034  raise InternalError(
2035  f"DataAccess.overlaps(): vector sizes differ for field "
2036  f"'{arg.name}' in two halo exchange calls. Found "
2037  f"'{self._arg.vector_size}' and '{arg.vector_size}'")
2038  if self._call.vector_index != arg.call.vector_index:
2039  # accesses are to different vector indices so do not overlap
2040  return False
2041  # accesses do overlap
2042  return True
2043 

References psyclone.gocean1p0.GOKernelArgument._arg, psyclone.psyGen.DataAccess._arg, psyclone.psyGen.KernelArgument._arg, psyclone.f2pygen.CallGen._call, psyclone.gocean1p0.GOKernelGridArgument._call, psyclone.psyGen.DataAccess._call, and psyclone.psyGen.Argument._call.

Here is the caller graph for this function:

◆ reset_coverage()

def psyclone.psyGen.DataAccess.reset_coverage (   self)
Reset internal state to allow re-use of the object for a different
situation.

Definition at line 2044 of file psyGen.py.

2044  def reset_coverage(self):
2045  '''Reset internal state to allow re-use of the object for a different
2046  situation.
2047 
2048  '''
2049  # False unless all data accessed by our local argument has
2050  # also been accessed by other arguments.
2051  self._covered = False
2052  # Used to store individual vector component accesses when
2053  # checking that all vector components have been accessed.
2054  self._vector_index_access = []
2055 

References psyclone.psyGen.DataAccess._covered, and psyclone.psyGen.DataAccess._vector_index_access.

Here is the caller graph for this function:

◆ update_coverage()

def psyclone.psyGen.DataAccess.update_coverage (   self,
  arg 
)
Record any overlap between accesses to the supplied argument and
the internal argument. Overlap means that the accesses to the
two arguments share at least one memory location. If the
overlap results in all of the accesses to the internal
argument being covered (either directly or as a combination
with previous arguments) then ensure that the covered() method
returns True. Covered means that all memory accesses by the
internal argument have at least one corresponding access by
the supplied arguments.

:param arg: the argument used to compare with our internal \
            argument in order to update coverage information
:type arg: :py:class:`psyclone.psyGen.Argument`

Definition at line 2056 of file psyGen.py.

2056  def update_coverage(self, arg):
2057  '''Record any overlap between accesses to the supplied argument and
2058  the internal argument. Overlap means that the accesses to the
2059  two arguments share at least one memory location. If the
2060  overlap results in all of the accesses to the internal
2061  argument being covered (either directly or as a combination
2062  with previous arguments) then ensure that the covered() method
2063  returns True. Covered means that all memory accesses by the
2064  internal argument have at least one corresponding access by
2065  the supplied arguments.
2066 
2067  :param arg: the argument used to compare with our internal \
2068  argument in order to update coverage information
2069  :type arg: :py:class:`psyclone.psyGen.Argument`
2070 
2071  '''
2072 
2073  if not self.overlaps(arg):
2074  # There is no overlap so there is nothing to update.
2075  return
2076 
2077  if isinstance(arg.call, HaloExchange) and \
2078  (hasattr(self._arg, 'vector_size') and self._arg.vector_size > 1):
2079  # The supplied argument is a vector field coming from a
2080  # halo exchange and therefore only accesses one of the
2081  # vectors
2082 
2083  if isinstance(self._call, HaloExchange):
2084  # I am also a halo exchange so only access one of the
2085  # vectors. At this point the vector indices of the two
2086  # halo exchange fields must be the same, which should
2087  # never happen due to checks in the `overlaps()`
2088  # method earlier
2089  raise InternalError(
2090  f"DataAccess:update_coverage() The halo exchange vector "
2091  f"indices for '{self._arg.name}' are the same. This "
2092  f"should never happen")
2093  else:
2094  # I am not a halo exchange so access all components of
2095  # the vector. However, the supplied argument is a halo
2096  # exchange so only accesses one of the
2097  # components. This results in partial coverage
2098  # (i.e. the overlap in accesses is partial). Therefore
2099  # record the index that is accessed and check whether
2100  # all indices are now covered (which would mean `full`
2101  # coverage).
2102  if arg.call.vector_index in self._vector_index_access:
2103  raise InternalError(
2104  "DataAccess:update_coverage() Found more than one "
2105  "dependent halo exchange with the same vector index")
2106  self._vector_index_access.append(arg.call.vector_index)
2107  if len(self._vector_index_access) != self._arg.vector_size:
2108  return
2109  # This argument is covered i.e. all accesses by the
2110  # internal argument have a corresponding access in one of the
2111  # supplied arguments.
2112  self._covered = True
2113 

References psyclone.gocean1p0.GOKernelArgument._arg, psyclone.psyGen.DataAccess._arg, psyclone.psyGen.KernelArgument._arg, psyclone.f2pygen.CallGen._call, psyclone.gocean1p0.GOKernelGridArgument._call, psyclone.psyGen.DataAccess._call, psyclone.psyGen.Argument._call, psyclone.psyGen.DataAccess._covered, psyclone.psyGen.DataAccess._vector_index_access, and psyclone.psyGen.DataAccess.overlaps().

Here is the call graph for this function:

The documentation for this class was generated from the following file: