How to use the psyclone.psyir.backend.visitor.VisitorError 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 / fortran.py View on Github external
:returns: the Fortran code as a string.
        :rtype: str

        :raises VisitorError: if an unexpected Unary op is encountered.

        '''
        content = self._visit(node.children[0])
        try:
            fort_oper = get_fortran_operator(node.operator)
            if is_fortran_intrinsic(fort_oper):
                # This is a unary intrinsic function.
                return "{0}({1})".format(fort_oper, content)
            return "{0}{1}".format(fort_oper, content)
        except KeyError:
            raise VisitorError("Unexpected unary op '{0}'.".format(
                node.operator))
github stfc / PSyclone / src / psyclone / psyir / backend / fortran.py View on Github external
:type node: :py:class:`psyclone.psyir.nodes.NaryOperation`

        :returns: the Fortran code as a string.
        :rtype: str

        :raises VisitorError: if an unexpected N-ary operator is found.

        '''
        arg_list = []
        for child in node.children:
            arg_list.append(self._visit(child))
        try:
            fort_oper = get_fortran_operator(node.operator)
            return "{0}({1})".format(fort_oper, ", ".join(arg_list))
        except KeyError:
            raise VisitorError("Unexpected N-ary op '{0}'".
                               format(node.operator))
github stfc / PSyclone / src / psyclone / psyir / backend / sir.py View on Github external
if isinstance(child, Reference):
            dims.append("0")
        elif isinstance(child, BinaryOperation):
            if isinstance(child.children[0], Reference) and \
               isinstance(child.children[1], Literal):
                if child.operator == BinaryOperation.Operator.SUB:
                    dims.append("-"+child.children[1].value)
                elif child.operator == BinaryOperation.Operator.ADD:
                    dims.append(child.children[1].value)
                else:
                    raise VisitorError(
                        "gen_stencil unsupported stencil operator found "
                        "'{0}'. Expecting '+' or '-'."
                        "".format(child.operator.name))
            else:
                raise VisitorError(
                    "gen_stencil unsupported stencil index found '{0}'."
                    "".format(str(child)))
        else:
            raise VisitorError(
                "gen_stencil unsupported (non-stencil) index found '{0}'."
                "".format(str(child)))
    return "[{0}]".format(", ".join(dims))
github stfc / PSyclone / src / psyclone / psyir / backend / fortran.py View on Github external
:raises VisitorError: if one of the symbols is a RoutineSymbol \
            and it does not have a GlobalInterface interface as this \
            is not supported by this backend.
        :raises VisitorError: if args_allowed is False and one or more \
                              argument declarations exist in symbol_table.
        :raises VisitorError: if any symbols representing variables (i.e. \
            not kind parameters) without an explicit declaration or 'use' \
            are encountered.

        '''
        declarations = ""

        if not all([isinstance(symbol.interface, GlobalInterface)
                    for symbol in symbol_table.symbols
                    if isinstance(symbol, RoutineSymbol)]):
            raise VisitorError(
                "Routine symbols without a global interface are unsupported "
                "by the Fortran back-end.")

        # Does the symbol table contain any symbols with a deferred
        # interface (i.e. we don't know how they are brought into scope) that
        # are not KIND parameters?
        unresolved_datasymbols = symbol_table.get_unresolved_datasymbols(
            ignore_precision=True)
        if unresolved_datasymbols:
            symbols_txt = ", ".join(
                ["'" + sym + "'" for sym in unresolved_datasymbols])
            raise VisitorError(
                "The following symbols are not explicitly declared or imported"
                " from a module (in the local scope) and are not KIND "
                "parameters: {0}".format(symbols_txt))
github stfc / PSyclone / src / psyclone / psyir / backend / fortran.py View on Github external
# We need brackets to enforce precedence
                        return "({0} {1} {2})".format(lhs, fort_oper, rhs)
                    if precedence(fort_oper) == precedence(parent_fort_oper):
                        # We still may need to enforce precedence
                        if (isinstance(parent, UnaryOperation) or
                                (isinstance(parent, BinaryOperation) and
                                 parent.children[1] == node)):
                            # We need brackets to enforce precedence
                            # as a) a unary operator is performed
                            # before a binary operator and b) floating
                            # point operations are not actually
                            # associative due to rounding errors.
                            return "({0} {1} {2})".format(lhs, fort_oper, rhs)
            return "{0} {1} {2}".format(lhs, fort_oper, rhs)
        except KeyError:
            raise VisitorError("Unexpected binary op '{0}'."
                               "".format(node.operator))
github stfc / PSyclone / src / psyclone / psyir / backend / sir.py View on Github external
if not (len(loop_content) == 1 and
                isinstance(loop_content[0], NemoLoop)):
            raise VisitorError("Child of loop should be a single loop.")

        # Check second loop has a single loop as a child.
        loop_content = loop_content[0].loop_body.children
        if not (len(loop_content) == 1 and
                isinstance(loop_content[0], NemoLoop)):
            raise VisitorError(
                "Child of child of loop should be a single loop.")

        # Check third loop has a single NemoKern as a child.
        loop_content = loop_content[0].loop_body.children
        if not (len(loop_content) == 1 and
                isinstance(loop_content[0], NemoKern)):
            raise VisitorError(
                "Child of child of child of loop should be a NemoKern.")

        # The interval values are hardcoded for the moment (see #470).
        result = ("{0}interval = make_interval(Interval.Start, Interval.End, "
                  "0, 0)\n".format(self._nindent))
        result += ("{0}body_ast = make_ast([\n".format(self._nindent))
        self._depth += 1
        result += self.nemokern_node(loop_content[0])
        self._depth -= 1
        # Remove the trailing comma if there is one as this is the
        # last entry in make_ast.
        result = result.rstrip(",\n") + "\n"
        result += "{0}])\n".format(self._nindent)
        # For the moment there is a hard coded assumption that the
        # vertical looping is in the forward (1..n) direction (see
        # #470).
github stfc / PSyclone / src / psyclone / psyir / backend / sir.py View on Github external
a literal (as only - is currently supported).

        '''
        # Currently only '-' is supported in the SIR mapping.
        unary_operators = {
            UnaryOperation.Operator.MINUS: '-'}
        try:
            oper = unary_operators[node.operator]
        except KeyError:
            raise VisitorError(
                "Method unaryoperation_node in class SIRWriter, unsupported "
                "operator '{0}' found.".format(str(node.operator)))
        # Currently only '-' is supported in the SIR mapping.
        if not (len(node.children) == 1 and
                isinstance(node.children[0], Literal)):
            raise VisitorError(
                "Currently, unary operators can only be applied to literals.")
        literal = node.children[0]
        if literal.datatype not in [DataType.REAL, DataType.INTEGER]:
            # The '-' operator can only be applied to REAL and INTEGER
            # datatypes.
            raise VisitorError(
                "PSyIR type '{0}' does not work with the '-' operator."
                "".format(str(literal.datatype)))
        result = literal.value
        datatype = TYPE_MAP_TO_SIR[literal.datatype]
        return ("{0}make_literal_access_expr(\"{1}{2}\", {3})"
                "".format(self._nindent, oper, result, datatype))
github stfc / PSyclone / src / psyclone / psyir / backend / sir.py View on Github external
access and return it in the form expected by the SIR as a
    string. Raise an exception if the array access is not a recognised
    stencil access.

    :param node: an array access.
    :type node: :py:class:`psyclone.psyir.nodes.Array`

    :returns: the SIR stencil access format for the array access.
    :rtype: str

    :raises VisitorError: if the node is not the expected type or the \
    array access is not in a recognised stencil form.

    '''
    if not isinstance(node, Array):
        raise VisitorError(
            "gen_stencil expected an Array as input but found '{0}'."
            "".format(type(node)))
    dims = []
    for child in node.children:
        if isinstance(child, Reference):
            dims.append("0")
        elif isinstance(child, BinaryOperation):
            if isinstance(child.children[0], Reference) and \
               isinstance(child.children[1], Literal):
                if child.operator == BinaryOperation.Operator.SUB:
                    dims.append("-"+child.children[1].value)
                elif child.operator == BinaryOperation.Operator.ADD:
                    dims.append(child.children[1].value)
                else:
                    raise VisitorError(
                        "gen_stencil unsupported stencil operator found "
github stfc / PSyclone / src / psyclone / psyir / backend / fortran.py View on Github external
precision = symbol.datatype.precision

    if isinstance(precision, int):
        if fortrantype not in ['real', 'integer', 'logical']:
            raise VisitorError("Explicit precision not supported for datatype "
                               "'{0}' in symbol '{1}' in Fortran backend."
                               "".format(fortrantype, symbol.name))
        if fortrantype == 'real' and precision not in [4, 8, 16]:
            raise VisitorError(
                "Datatype 'real' in symbol '{0}' supports fixed precision of "
                "[4, 8, 16] but found '{1}'.".format(symbol.name,
                                                     precision))
        if fortrantype in ['integer', 'logical'] and precision not in \
           [1, 2, 4, 8, 16]:
            raise VisitorError(
                "Datatype '{0}' in symbol '{1}' supports fixed precision of "
                "[1, 2, 4, 8, 16] but found '{2}'."
                "".format(fortrantype, symbol.name, precision))
        # Precision has an an explicit size. Use the "type*size" Fortran
        # extension for simplicity. We could have used
        # type(kind=selected_int|real_kind(size)) or, for Fortran 2008,
        # ISO_FORTRAN_ENV; type(type64) :: MyType.
        return "{0}*{1}".format(fortrantype, precision)

    if isinstance(precision, ScalarType.Precision):
        # The precision information is not absolute so is either
        # machine specific or is specified via the compiler. Fortran
        # only distinguishes relative precision for single and double
        # precision reals.
        if fortrantype.lower() == "real" and \
           precision == ScalarType.Precision.DOUBLE: