How to use the psyclone.psyir.nodes.BinaryOperation function in PSyclone

To help you get started, we’ve selected a few PSyclone examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github stfc / PSyclone / src / psyclone / psyir / backend / sir.py View on Github external
:param node: a BinaryOperation PSyIR node.
        :type node: :py:class:`psyclone.psyir.nodes.BinaryOperation`

        :returns: the SIR Python code.
        :rtype: str

        :raises VisitorError: if there is no mapping from the PSyIR \
        operator to SIR.

        '''
        binary_operators = {
            BinaryOperation.Operator.ADD: '+',
            BinaryOperation.Operator.SUB: '-',
            BinaryOperation.Operator.MUL: '*',
            BinaryOperation.Operator.DIV: '/',
            BinaryOperation.Operator.POW: '**',
            BinaryOperation.Operator.EQ: '==',
            BinaryOperation.Operator.NE: '!=',
            BinaryOperation.Operator.LE: '<=',
            BinaryOperation.Operator.LT: '<',
            BinaryOperation.Operator.GE: '>=',
            BinaryOperation.Operator.GT: '>',
            BinaryOperation.Operator.AND: '&&',
            BinaryOperation.Operator.OR: '||'}

        self._depth += 1
        lhs = self._visit(node.children[0])
        try:
            oper = binary_operators[node.operator]
        except KeyError:
            raise VisitorError(
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
self._iteration_space][self._loop_type]
            stop = bounds["stop"].format(start='2', stop=stop)
            # Remove all white spaces
            stop = "".join(stop.split())
            # This common case is a bit of compile-time computation
            # but it helps to fix all of the test cases.
            if stop == "2-1":
                stop = "1"
            return Literal(stop, INTEGER_TYPE, self)

        if self.field_space == "go_every":
            # Bounds are independent of the grid-offset convention in use

            # We look-up the upper bounds by enquiring about the SIZE of
            # the array itself
            stop = BinaryOperation(BinaryOperation.Operator.SIZE,
                                   self)
            # TODO 363 - needs to be updated once the PSyIR has support for
            # Fortran derived types.
            api_config = Config.get().api_conf("gocean1.0")
            # Use the data property to access the member of the field that
            # contains the actual grid points. The property value is a
            # string with a placeholder ({0}) where the name of the field
            # must go.
            data = api_config.grid_properties["go_grid_data"].fortran \
                .format(self.field_name)
            stop.addchild(Literal(data, INTEGER_TYPE, parent=stop))
            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
github stfc / PSyclone / src / psyclone / psyir / backend / fortran.py View on Github external
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

        if _full_extent(node.start, BinaryOperation.Operator.LBOUND):
            # The range starts for the first element in this
            # dimension. This is the default in Fortran so no need to
            # output anything.
            start = ""
        else:
            start = self._visit(node.start)

        if _full_extent(node.stop, BinaryOperation.Operator.UBOUND):
            # The range ends with the last element in this
            # dimension. This is the default in Fortran so no need to
            # output anything.
            stop = ""
        else:
            stop = self._visit(node.stop)
        result = "{0}:{1}".format(start, stop)
github stfc / PSyclone / src / psyclone / gocean0p1.py View on Github external
if self.field_space == "every":
            from psyclone.f2pygen import DeclGen
            from psyclone.psyir.nodes import BinaryOperation
            dim_var = DeclGen(parent, datatype="INTEGER",
                              entity_decls=[self.variable.name])
            parent.add(dim_var)

            # Update start loop bound
            self.start_expr = Literal("1", INTEGER_TYPE, parent=self)

            # Update stop loop bound
            if self._loop_type == "inner":
                index = "1"
            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)
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
# A lower limit is specified
                geop = BinaryOperation(BinaryOperation.Operator.GE,
                                       parent=new_parent)
                self.process_nodes(parent=geop, nodes=[selector])
                self.process_nodes(parent=geop, nodes=[node.items[0]])
                new_parent.addchild(geop)
            if node.items[1]:
                # An upper limit is specified
                leop = BinaryOperation(BinaryOperation.Operator.LE,
                                       parent=new_parent)
                self.process_nodes(parent=leop, nodes=[selector])
                self.process_nodes(parent=leop, nodes=[node.items[1]])
                new_parent.addchild(leop)
        else:
            # The case value is some scalar initialisation expression
            bop = BinaryOperation(BinaryOperation.Operator.EQ,
                                  parent=parent)
            parent.addchild(bop)
            self.process_nodes(parent=bop, nodes=[selector])
            self.process_nodes(parent=bop, nodes=[node])
github stfc / PSyclone / src / psyclone / psyir / backend / c.py View on Github external
def function_format(function_str, expr1, expr2):
            '''
            :param str function_str: Name of the function.
            :param str expr1: String representation of the first operand.
            :param str expr2: String representation of the second operand.

            :returns: C language binary function expression.
            :rtype: str
            '''
            return function_str + "(" + expr1 + ", " + expr2 + ")"

        # Define a map with the operator string and the formatter function
        # associated with each BinaryOperation.Operator
        from psyclone.psyir.nodes import BinaryOperation
        opmap = {
            BinaryOperation.Operator.ADD: ("+", operator_format),
            BinaryOperation.Operator.SUB: ("-", operator_format),
            BinaryOperation.Operator.MUL: ("*", operator_format),
            BinaryOperation.Operator.DIV: ("/", operator_format),
            BinaryOperation.Operator.REM: ("%", operator_format),
            BinaryOperation.Operator.POW: ("pow", function_format),
            BinaryOperation.Operator.EQ: ("==", operator_format),
            BinaryOperation.Operator.NE: ("!=", operator_format),
            BinaryOperation.Operator.LT: ("<", operator_format),
            BinaryOperation.Operator.LE: ("<=", operator_format),
            BinaryOperation.Operator.GT: (">", operator_format),
            BinaryOperation.Operator.GE: (">=", operator_format),
            BinaryOperation.Operator.AND: ("&&", operator_format),
            BinaryOperation.Operator.OR: ("||", operator_format),
            BinaryOperation.Operator.SIGN: ("copysign", function_format),
            }
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
arg_nodes = node.items[1].items
            if len(arg_nodes) != 2:
                raise InternalError(
                    "Binary operator should have exactly two arguments but "
                    "found {0} for '{1}'.".format(len(arg_nodes), str(node)))
        else:
            operator_str = node.items[1].lower()
            arg_nodes = [node.items[0], node.items[2]]

        try:
            operator = Fparser2Reader.binary_operators[operator_str]
        except KeyError:
            # Operator not supported, it will produce a CodeBlock instead
            raise NotImplementedError(operator_str)

        binary_op = BinaryOperation(operator, parent=parent)
        self.process_nodes(parent=binary_op, nodes=[arg_nodes[0]])
        self.process_nodes(parent=binary_op, nodes=[arg_nodes[1]])

        return binary_op
github stfc / PSyclone / examples / psyir / create.py View on Github external
# 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(
    BinaryOperation.Operator.LBOUND,
    Reference(ARRAY), INT_ONE)
UBOUND = BinaryOperation.create(
    BinaryOperation.Operator.UBOUND,
    Reference(ARRAY), INT_ONE)
MY_RANGE = Range.create(LBOUND, UBOUND)
TMPARRAY = Array.create(ARRAY, [MY_RANGE])
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
'''
        if isinstance(node, Fortran2003.Case_Value_Range):
            # The case value is a range (e.g. lim1:lim2)
            if node.items[0] and node.items[1]:
                # Have lower and upper limits so need a parent AND
                aop = BinaryOperation(BinaryOperation.Operator.AND,
                                      parent=parent)
                parent.addchild(aop)
                new_parent = aop
            else:
                # No need to create new parent node
                new_parent = parent

            if node.items[0]:
                # A lower limit is specified
                geop = BinaryOperation(BinaryOperation.Operator.GE,
                                       parent=new_parent)
                self.process_nodes(parent=geop, nodes=[selector])
                self.process_nodes(parent=geop, nodes=[node.items[0]])
                new_parent.addchild(geop)
            if node.items[1]:
                # An upper limit is specified
                leop = BinaryOperation(BinaryOperation.Operator.LE,
                                       parent=new_parent)
                self.process_nodes(parent=leop, nodes=[selector])
                self.process_nodes(parent=leop, nodes=[node.items[1]])
                new_parent.addchild(leop)
        else:
            # The case value is some scalar initialisation expression
            bop = BinaryOperation(BinaryOperation.Operator.EQ,
                                  parent=parent)
            parent.addchild(bop)