Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
self.stop_expr = BinaryOperation(BinaryOperation.Operator.SIZE,
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol(self.field_name, INTEGER_TYPE),
parent=self.stop_expr))
self.stop_expr.addchild(Literal(index, INTEGER_TYPE,
parent=self.stop_expr))
else: # one of our spaces so use values provided by the infrastructure
# loop bounds
# TODO: Issue 440. Implement derive types in PSyIR
if self._loop_type == "inner":
self.start_expr = Reference(
self.field_space + "%istart", parent=self)
self.stop_expr = Reference(
self.field_space + "%istop", parent=self)
elif self._loop_type == "outer":
self.start_expr = Reference(
self.field_space + "%jstart", parent=self)
self.stop_expr = Reference(
self.field_space + "%jstop", parent=self)
Loop.gen_code(self, parent)
res_var = symbol_table.new_symbol_name("res_min")
res_var_symbol = DataSymbol(res_var, DataType.REAL)
symbol_table.add(res_var_symbol)
# Create a temporary variable. Again there is an
# assumption here about the datatype - please see previous
# comment (associated issues #500 and #658).
tmp_var = symbol_table.new_symbol_name("tmp_min")
tmp_var_symbol = DataSymbol(tmp_var, DataType.REAL)
symbol_table.add(tmp_var_symbol)
# Replace operation with a temporary (res_var).
oper_parent.children[node.position] = Reference(res_var_symbol,
parent=oper_parent)
# res_var=A
lhs = Reference(res_var_symbol)
new_assignment = Assignment.create(lhs, node.children[0])
new_assignment.parent = assignment.parent
assignment.parent.children.insert(assignment.position, new_assignment)
# For each of the remaining min arguments (B,C...)
for expression in node.children[1:]:
# tmp_var=(B or C or ...)
lhs = Reference(tmp_var_symbol)
new_assignment = Assignment.create(lhs, expression)
new_assignment.parent = assignment.parent
assignment.parent.children.insert(assignment.position,
new_assignment)
# if_condition: tmp_var
elif self._loop_type == "outer":
index = "2"
self.stop_expr = BinaryOperation(BinaryOperation.Operator.SIZE,
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol(self.field_name, INTEGER_TYPE),
parent=self.stop_expr))
self.stop_expr.addchild(Literal(index, INTEGER_TYPE,
parent=self.stop_expr))
else: # one of our spaces so use values provided by the infrastructure
# loop bounds
# TODO: Issue 440. Implement derive types in PSyIR
if self._loop_type == "inner":
self.start_expr = Reference(
self.field_space + "%istart", parent=self)
self.stop_expr = Reference(
self.field_space + "%istop", parent=self)
elif self._loop_type == "outer":
self.start_expr = Reference(
self.field_space + "%jstart", parent=self)
self.stop_expr = Reference(
self.field_space + "%jstop", parent=self)
Loop.gen_code(self, parent)
'''
Transforms an fparser2 Name to the PSyIR representation. If the parent
is connected to a SymbolTable, it checks the reference has been
previously declared.
:param node: node in fparser2 AST.
:type node: :py:class:`fparser.two.Fortran2003.Name`
:param parent: Parent node of the PSyIR node we are constructing.
:type parent: :py:class:`psyclone.psyir.nodes.Node`
:returns: PSyIR representation of node
:rtype: :py:class:`psyclone.psyir.nodes.Reference`
'''
symbol = parent.find_or_create_symbol(node.string)
return Reference(symbol, parent)
''' Work out the appropriate loop bounds and then call the base
class to generate the code '''
self.start_expr = Literal("1", INTEGER_TYPE, parent=self)
if self._loop_type == "colours":
self.stop_expr = Reference(DataSymbol("ncolour", INTEGER_TYPE),
parent=self)
elif self._loop_type == "colour":
self.stop_expr = Array(DataSymbol("ncp_ncolour", INTEGER_TYPE),
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol("colour", INTEGER_TYPE)),
parent=self.stop_expr)
else:
# This is a hack as the name is not a valid DataSymbol, it
# is a call to a type-bound function.
self.stop_expr = Reference(
DataSymbol(self.field_name+"%get_ncell()", INTEGER_TYPE),
parent=self)
Loop.gen_code(self, parent)
# Create "result(i)"
result_dims = [Reference(i_loop_symbol)]
if len(result.children) > 1:
# Add any additional dimensions (in case of an array slice)
result_dims.extend(result.children[1:])
result = Array.create(result_symbol, result_dims)
# Create "vector(j)"
vector_dims = [Reference(j_loop_symbol)]
if len(vector.children) > 1:
# Add any additional dimensions (in case of an array slice)
vector_dims.extend(vector.children[1:])
vector_array_reference = Array.create(
vector.symbol, vector_dims)
# Create "matrix(i,j)"
array_dims = [Reference(i_loop_symbol), Reference(j_loop_symbol)]
if len(matrix.children) > 2:
# Add any additional dimensions (in case of an array slice)
array_dims.extend(matrix.children[2:])
matrix_array_reference = Array.create(matrix.symbol, array_dims)
# Create "matrix(i,j) * vector(j)"
multiply = BinaryOperation.create(
BinaryOperation.Operator.MUL, matrix_array_reference,
vector_array_reference)
# Create "result(i) + matrix(i,j) * vector(j)"
rhs = BinaryOperation.create(
BinaryOperation.Operator.ADD, result, multiply)
# Create "result(i) = result(i) + matrix(i,j) * vector(j)"
assign = Assignment.create(result, rhs)
# Create j loop and add the above code as a child
# Work out the bounds
lower_bound, upper_bound, step = _get_array_bound(vector, 0)
symbol_table.add(DataSymbol(loop_vars[idx-1], integer_type))
loop = Loop(parent=new_parent, variable_name=loop_vars[idx-1],
annotations=annotations)
# Point to the original WHERE statement in the parse tree.
loop.ast = node
# Add loop lower bound
loop.addchild(Literal("1", integer_type, parent=loop))
# Add loop upper bound - we use the SIZE operator to query the
# extent of the current array dimension
size_node = BinaryOperation(BinaryOperation.Operator.SIZE,
parent=loop)
loop.addchild(size_node)
symbol = size_node.find_or_create_symbol(arrays[0].name)
size_node.addchild(Reference(symbol, parent=size_node))
size_node.addchild(Literal(str(idx), integer_type,
parent=size_node))
# Add loop increment
loop.addchild(Literal("1", integer_type, parent=loop))
# Fourth child of a Loop must be a Schedule
sched = Schedule(parent=loop)
loop.addchild(sched)
# Finally, add the Loop we've constructed to its parent (but
# not into the existing PSyIR tree - that's done in
# process_nodes()).
if new_parent is not parent:
new_parent.addchild(loop)
else:
# Keep a reference to the first loop as that's what this
# handler returns
root_loop = loop
SYMBOL_TABLE.add(REAL_KIND)
# Array using precision defined by another symbol
ARRAY_NAME = SYMBOL_TABLE.new_symbol_name(root_name="a")
SCALAR_TYPE = ScalarType(ScalarType.Intrinsic.REAL, REAL_KIND)
ARRAY = DataSymbol(ARRAY_NAME, ArrayType(SCALAR_TYPE, [10]))
SYMBOL_TABLE.add(ARRAY)
# Nodes which do not have Nodes as children and (some) predefined
# scalar datatypes
ZERO = Literal("0.0", REAL_TYPE)
ONE = Literal("1.0", REAL4_TYPE)
TWO = Literal("2.0", SCALAR_TYPE)
INT_ZERO = Literal("0", INTEGER_SINGLE_TYPE)
INT_ONE = Literal("1", INTEGER8_TYPE)
TMP1 = Reference(ARG1)
TMP2 = Reference(TMP_SYMBOL)
# Unary Operation
OPER = UnaryOperation.Operator.SIN
UNARYOPERATION = UnaryOperation.create(OPER, TMP2)
# Binary Operation
OPER = BinaryOperation.Operator.ADD
BINARYOPERATION = BinaryOperation.create(OPER, ONE, UNARYOPERATION)
# Nary Operation
OPER = NaryOperation.Operator.MAX
NARYOPERATION = NaryOperation.create(OPER, [TMP1, TMP2, ONE])
# Array reference using a range
LBOUND = BinaryOperation.create(
parent=oper_parent)
# res_var=ABS(A)
lhs = Reference(res_var_symbol)
rhs = UnaryOperation.create(UnaryOperation.Operator.ABS,
node.children[0])
new_assignment = Assignment.create(lhs, rhs)
new_assignment.parent = assignment.parent
assignment.parent.children.insert(assignment.position, new_assignment)
# Replace the ABS intrinsic with inline code.
abs_trans = NemoAbsTrans()
abs_trans.apply(rhs, symbol_table)
# tmp_var=B
lhs = Reference(tmp_var_symbol)
new_assignment = Assignment.create(lhs, node.children[1])
new_assignment.parent = assignment.parent
assignment.parent.children.insert(assignment.position, new_assignment)
# if_condition: tmp_var<0.0
lhs = Reference(tmp_var_symbol)
rhs = Literal("0.0", DataType.REAL)
if_condition = BinaryOperation.create(BinaryOperation.Operator.LT,
lhs, rhs)
# then_body: res_var=res_var*-1.0
lhs = Reference(res_var_symbol)
lhs_child = Reference(res_var_symbol)
rhs_child = Literal("-1.0", DataType.REAL)
rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
lhs_child, rhs_child)
:param node: the node to check.
:type node: :py:class:`psyclone.psyir.nodes.Range`
:param operator: an lbound or ubound operator.
:type operator: either :py:class:`Operator.LBOUND` or \
:py:class:`Operator.UBOUND` from \
:py:class:`psyclone.psyir.nodes.BinaryOperation`
'''
my_range = node.parent
array = my_range.parent
array_index = array.children.index(my_range) + 1
# pylint: disable=too-many-boolean-expressions
if isinstance(node, BinaryOperation) and \
node.operator == operator and \
isinstance(node.children[0], Reference) and \
node.children[0].name == array.name and \
isinstance(node.children[1], Literal) and \
node.children[1].datatype.intrinsic == \
ScalarType.Intrinsic.INTEGER and \
node.children[1].value == str(array_index):
return True
return False