Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _check_init(self):
'''Internal method which checks that the stencil information has been
loaded.
:raises GenerationError: if the GOStencil object has not been
initialised i.e. the load() method has not been called
'''
if not self._initialised:
raise GenerationError(
"Error in class GOStencil: the object has not yet been "
"initialised. Please ensure the load() method is called.")
:raises GenerationError: if the kernels within this loop expect \
different different grid offsets.
'''
# Our schedule holds the names to use for the loop bounds.
# Climb up the tree looking for our enclosing GOInvokeSchedule
schedule = self.ancestor(GOInvokeSchedule)
if schedule is None or not isinstance(schedule, GOInvokeSchedule):
raise GenerationError("Internal error: cannot find parent"
" GOInvokeSchedule for this Do loop")
# Walk down the tree looking for a kernel so that we can
# look-up what index-offset convention we are to use
go_kernels = self.walk(GOKern)
if not go_kernels:
raise GenerationError("Internal error: cannot find the "
"GOcean Kernel enclosed by this loop")
index_offset = go_kernels[0].index_offset
if schedule.const_loop_bounds and \
index_offset not in SUPPORTED_OFFSETS:
raise GenerationError("Constant bounds generation"
" not implemented for a grid offset "
"of {0}. Supported offsets are {1}".
format(index_offset,
SUPPORTED_OFFSETS))
# Check that all kernels enclosed by this loop expect the same
# grid offset
for kernel in go_kernels:
if kernel.index_offset != index_offset:
raise GenerationError("All Kernels must expect the same "
"grid offset but kernel {0} has offset "
"{1} which does not match {2}".
:raises GenerationError: if new_node is not an\
instance of :py:class:`psyclone.psyir.nodes.Node`.
:raises GenerationError: if position is not 'before' or 'after'.
:raises GenerationError: if self and new_node do not have the same\
parent.
:raises GenerationError: self and new_node are the same Node.
:returns: whether or not the specified location is valid for this node.
:rtype: bool
'''
# First perform correctness checks
# 1: check new_node is a Node
if not isinstance(new_node, Node):
raise GenerationError(
"In the psyir.nodes.Node.is_valid_location() method the "
"supplied argument is not a Node, it is a '{0}'.".
format(type(new_node).__name__))
# 2: check position has a valid value
valid_positions = ["before", "after"]
if position not in valid_positions:
raise GenerationError(
"The position argument in the psyGenNode.is_valid_location() "
"method must be one of {0} but found '{1}'".format(
valid_positions, position))
# 3: check self and new_node have the same parent
if not self.sameParent(new_node):
raise GenerationError(
"In the psyir.nodes.Node.is_valid_location() method "
:param operator: the CMA operator.
:type operator: :py:class:`psyclone.dynamo0p3.DynKernelArgument`
:param var_accesses: optional VariablesAccessInfo instance to store \
the information about variable accesses.
:type var_accesses: \
:py:class:`psyclone.core.access_info.VariablesAccessInfo`
:raises GenerationError: if no kernel argument is supplied.
:raises GenerationError: if the supplied kernel argument is not a \
CMA operator.
'''
if not operator:
raise GenerationError("Internal error: no CMA operator supplied.")
if operator.type != "gh_columnwise_operator":
raise GenerationError(
"Internal error: a CMA operator (gh_columnwise_operator) must "
"be supplied but got {0}".format(operator.type))
map_name = function_space.cma_indirection_map_name
self.append(map_name)
if var_accesses is not None:
var_accesses.add_access(map_name, AccessType.READ, self._kern)
# access-id-list. This is therefore invalid Fortran (which
# fparser does not catch).
current_node = stmt.parent
while current_node:
if isinstance(current_node, Fortran2003.Module):
mod_name = str(
current_node.children[0].children[1])
raise GenerationError(
"Module '{0}' contains more than one access "
"statement with an omitted access-id-list. "
"This is invalid Fortran.".format(mod_name))
current_node = current_node.parent
# Failed to find an enclosing Module. This is also invalid
# Fortran since an access statement is only permitted
# within a module.
raise GenerationError(
"Found multiple access statements with omitted access-"
"id-lists and no enclosing Module. Both of these "
"things are invalid Fortran.")
if public_stmt:
default_visibility = Symbol.Visibility.PUBLIC
else:
default_visibility = Symbol.Visibility.PRIVATE
else:
if public_stmt:
explicit_public.update(
[child.string for child in stmt.children[1].children])
else:
explicit_private.update(
[child.string for child in stmt.children[1].children])
# Sanity check the lists of symbols (because fparser2 does not
# currently do much validation)
def create():
''' Placeholder to create a GOocean-specific built-in call.
This will require us to create a doubly-nested loop and then create
the body of the particular built-in operation. '''
raise GenerationError(
"Built-ins are not supported for the GOcean 1.0 API")
'''
from psyclone.psyir.symbols import DataSymbol
if not isinstance(symbol, DataSymbol):
raise GenerationError(
"symbol argument in create method of Array class should be a "
"DataSymbol but found '{0}'.".format(type(symbol).__name__))
if not isinstance(children, list):
raise GenerationError(
"children argument in create method of Array class "
"should be a list but found '{0}'."
"".format(type(children).__name__))
if not symbol.is_array:
raise GenerationError(
"expecting the symbol to be an array, not a scalar.")
if len(symbol.shape) != len(children):
raise GenerationError(
"the symbol should have the same number of dimensions as "
"indices (provided in the 'children' argument). "
"Expecting '{0}' but found '{1}'.".format(
len(children), len(symbol.shape)))
array = Array(symbol)
array.children = children
for child in children:
child.parent = array
return array
if len(self.argument_list) < 2:
raise GenerationError(
"GOcean 1.0 API kernels should always have at least two "
"arguments representing the iteration indices but the "
"Symbol Table{0} has only {1} argument(s)."
"".format(kname_str,
str(len(self.argument_list)))
)
# Check that first 2 arguments are scalar integers
for pos, posstr in [(0, "first"), (1, "second")]:
dtype = self.argument_list[pos].datatype
shape_len = len(self.argument_list[pos].shape)
if not (isinstance(dtype, ScalarType) and
dtype.intrinsic == ScalarType.Intrinsic.INTEGER):
raise GenerationError(
"GOcean 1.0 API kernels {0} argument should be a scalar "
"integer but got '{1}'{2}."
"".format(posstr, dtype, kname_str))
if self._loop_type == "inner":
stop.addchild(Literal("1", INTEGER_TYPE, parent=stop))
elif self._loop_type == "outer":
stop.addchild(Literal("2", INTEGER_TYPE, parent=stop))
return stop
# Loop bounds are pulled from the field object which
# is more straightforward for us but provides the
# Fortran compiler with less information.
if self._iteration_space.lower() == "go_internal_pts":
key = "internal"
elif self._iteration_space.lower() == "go_all_pts":
key = "whole"
else:
raise GenerationError("Unrecognised iteration space, '{0}'. "
"Cannot generate loop bounds.".
format(self._iteration_space))
api_config = Config.get().api_conf("gocean1.0")
props = api_config.grid_properties
# key is 'internal' or 'whole', and _loop_type is either
# 'inner' or 'outer'. The four possible combinations are
# defined in the config file:
stop_format = props["go_grid_{0}_{1}_stop"
.format(key, self._loop_type)].fortran
stop = stop_format.format(self.field_name)
# TODO 363 - this needs updating once the PSyIR has support for
# Fortran derived types.
return Literal(stop, INTEGER_TYPE, self)
start = "1"
return Literal(start, INTEGER_TYPE, self)
if self.field_space == "go_every":
# Bounds are independent of the grid-offset convention in use
return Literal("1", INTEGER_TYPE, self)
# Loop bounds are pulled from the field object which is more
# straightforward for us but provides the Fortran compiler
# with less information.
if self._iteration_space.lower() == "go_internal_pts":
key = "internal"
elif self._iteration_space.lower() == "go_all_pts":
key = "whole"
else:
raise GenerationError("Unrecognised iteration space, '{0}'. "
"Cannot generate loop bounds.".
format(self._iteration_space))
api_config = Config.get().api_conf("gocean1.0")
props = api_config.grid_properties
# key is 'internal' or 'whole', and _loop_type is either
# 'inner' or 'outer'. The four possible combinations are
# defined in the config file:
start_format = props["go_grid_{0}_{1}_start"
.format(key, self._loop_type)].fortran
start = start_format.format(self.field_name)
# TODO 363 - update once the PSyIR supports derived types
return Literal(start, INTEGER_TYPE, self)