How to use the psyclone.psyir.nodes.Schedule 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 / frontend / fparser2.py View on Github external
# Create if-body as second child
                ifbody = Schedule(parent=ifblock)
                ifbody.ast = node.content[start_idx + 1]
                ifbody.ast_end = node.content[end_idx - 1]
                newifblock.addchild(ifbody)
                self.process_nodes(parent=ifbody,
                                   nodes=node.content[start_idx + 1:end_idx])

                currentparent = newifblock

            elif isinstance(clause, Fortran2003.Else_Stmt):
                if not idx == num_clauses - 1:
                    raise InternalError(
                        "Else clause should only be found next to last "
                        "clause, but found {0}".format(node.content))
                elsebody = Schedule(parent=currentparent)
                currentparent.addchild(elsebody)
                elsebody.ast = node.content[start_idx]
                elsebody.ast_end = node.content[end_idx]
                self.process_nodes(parent=elsebody,
                                   nodes=node.content[start_idx + 1:end_idx])
            else:
                raise InternalError(
                    "Only fparser2 If_Then_Stmt, Else_If_Stmt and Else_Stmt "
                    "are expected, but found {0}.".format(clause))

        return ifblock
github stfc / PSyclone / src / psyclone / psyir / transformations / extract_trans.py View on Github external
for node in node_list:

            # Check that ExtractNode is not inserted between a Kernel or
            # a BuiltIn call and its parent Loop.
            if isinstance(node, (Kern, BuiltIn)) and \
               isinstance(node.parent.parent, Loop):
                raise TransformationError(
                    "Error in {0}: Extraction of a Kernel or a Built-in "
                    "call without its parent Loop is not allowed."
                    .format(str(self.name)))

            # Check that ExtractNode is not inserted between a Loop and its
            # parent Directive when optimisations are applied, as this may
            # result in including the end Directive for extraction but
            # not the beginning.
            if isinstance(node, Loop) and isinstance(node.parent, Schedule) \
               and isinstance(node.parent.parent, Directive):
                raise TransformationError(
                    "Error in {0}: Extraction of a Loop without its parent "
                    "Directive is not allowed.".format(str(self.name)))

            # Check that ExtractNode is not inserted within a thread
            # parallel region when optimisations are applied. For instance,
            # this may be between an orphaned Directive (e.g. OMPDoDirective,
            # ACCLoopDirective) and its ancestor Directive (e.g. ACC or OMP
            # Parallel Directive) or within an OMPParallelDoDirective.
            if node.ancestor((OMPParallelDirective, ACCParallelDirective)):
                raise TransformationError(
                    "Error in {0}: Extraction of Nodes enclosed within "
                    "a thread-parallel region is not allowed."
                    .format(str(self.name)))
github stfc / PSyclone / src / psyclone / nemo.py View on Github external
def _process_loopbody(self, loop_body, node):
        '''
        Specialized method to process Nemo loop bodies. If the schedule
        matches with a NemoKern, it will add a NemoKern instead of statements
        in the loop_body.

        :param loop_body: schedule representing the body of the loop.
        :type loop_body: :py:class:`psyclone.psyir.nodes.Schedule`
        :param node: fparser loop node being processed.
        :type node: \
            :py:class:`fparser.two.Fortran2003.Block_Nonlabel_Do_Construct`
        '''
        # We create a fake node because we need to parse the children
        # before we decide what to do with them.
        fakeparent = Schedule(parent=loop_body)
        self.process_nodes(parent=fakeparent, nodes=node.content[1:-1])

        if NemoKern.match(fakeparent):
            # Create a new kernel object and make it the only
            # child of this Loop node. The PSyIR of the loop body becomes
            # the schedule of this kernel.
            nemokern = NemoKern(fakeparent.children, node, parent=loop_body)
            loop_body.children.append(nemokern)
        else:
            # Otherwise just connect the new children into the tree.
            loop_body.children.extend(fakeparent.children)
            for child in fakeparent.children:
                child.parent = loop_body
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
# of the loops we've just created.
        self._array_syntax_to_indexed(ifblock.children[0], loop_vars)

        # Now construct the body of the IF using the body of the WHERE
        sched = Schedule(parent=ifblock)
        ifblock.addchild(sched)

        if not was_single_stmt:
            # Do we have an ELSE WHERE?
            for idx, child in enumerate(node.content):
                if isinstance(child, Fortran2003.Elsewhere_Stmt):
                    self.process_nodes(sched, node.content[1:idx])
                    self._array_syntax_to_indexed(sched, loop_vars)
                    # Add an else clause to the IF block for the ELSEWHERE
                    # clause
                    sched = Schedule(parent=ifblock)
                    ifblock.addchild(sched)
                    self.process_nodes(sched, node.content[idx+1:-1])
                    break
            else:
                # No elsewhere clause was found
                self.process_nodes(sched, node.content[1:-1])
        else:
            # We only had a single-statement WHERE
            self.process_nodes(sched, node.items[1:])
        # Convert all uses of array syntax to indexed accesses
        self._array_syntax_to_indexed(sched, loop_vars)
        # Return the top-level loop generated by this handler
        return root_loop
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
elsebody = Schedule(parent=currentparent)
                    currentparent.addchild(elsebody)
                    newifblock = IfBlock(parent=elsebody,
                                         annotations=['was_elseif'])
                    elsebody.addchild(newifblock)

                    # Keep pointer to fpaser2 AST
                    elsebody.ast = node.content[start_idx]
                    newifblock.ast = node.content[start_idx]

                # Create condition as first child
                self.process_nodes(parent=newifblock,
                                   nodes=[clause.items[0]])

                # Create if-body as second child
                ifbody = Schedule(parent=ifblock)
                ifbody.ast = node.content[start_idx + 1]
                ifbody.ast_end = node.content[end_idx - 1]
                newifblock.addchild(ifbody)
                self.process_nodes(parent=ifbody,
                                   nodes=node.content[start_idx + 1:end_idx])

                currentparent = newifblock

            elif isinstance(clause, Fortran2003.Else_Stmt):
                if not idx == num_clauses - 1:
                    raise InternalError(
                        "Else clause should only be found next to last "
                        "clause, but found {0}".format(node.content))
                elsebody = Schedule(parent=currentparent)
                currentparent.addchild(elsebody)
                elsebody.ast = node.content[start_idx]
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
entity_shape[idx] = ArrayType.Extent.ATTRIBUTE
                    elif not isinstance(extent, ArrayType.Extent) and \
                            allocatable:
                        # We have an allocatable array with a defined extent.
                        # This is invalid Fortran.
                        raise InternalError(
                            "Invalid Fortran: '{0}'. An array with defined "
                            "extent cannot have the ALLOCATABLE attribute.".
                            format(str(decl)))

                if initialisation:
                    if has_constant_value:
                        # If it is a parameter parse its initialization into
                        # a dummy Assignment inside a Schedule which temporally
                        # hijacks the parent's node symbol table
                        tmp_sch = Schedule(symbol_table=parent.symbol_table)
                        dummynode = Assignment(parent=tmp_sch)
                        tmp_sch.addchild(dummynode)
                        expr = initialisation.items[1]
                        self.process_nodes(parent=dummynode, nodes=[expr])
                        ct_expr = dummynode.children[0]
                    else:
                        raise NotImplementedError(
                            "Could not process {0}. Initialisations on the"
                            " declaration statements are only supported for "
                            "parameter declarations.".format(decl.items))

                if char_len is not None:
                    raise NotImplementedError(
                        "Could not process {0}. Character length "
                        "specifications are not supported."
                        "".format(decl.items))
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
:type fp2_nodes: list of :py:class:`fparser.two.utils.Base`

        :returns: a CodeBlock instance.
        :rtype: :py:class:`psyclone.CodeBlock`

        '''
        if not fp2_nodes:
            return None

        # Determine whether this code block is a statement or an
        # expression. Statements always have a `Schedule` as parent
        # and expressions do not. The only unknown at this point are
        # directives whose structure are in discussion. Therefore, for
        # the moment, an exception is raised if a directive is found
        # as a parent.
        if isinstance(parent, Schedule):
            structure = CodeBlock.Structure.STATEMENT
        elif isinstance(parent, Directive):
            raise InternalError(
                "Fparser2Reader:nodes_to_code_block: A CodeBlock with "
                "a Directive as parent is not yet supported.")
        else:
            structure = CodeBlock.Structure.EXPRESSION

        code_block = CodeBlock(fp2_nodes, structure, parent=parent)
        parent.addchild(code_block)
        del fp2_nodes[:]
        return code_block
github stfc / PSyclone / src / psyclone / psyir / nodes / node.py View on Github external
def abs_position(self):
        '''
        Find a Node's absolute position in the tree (starting with 0 if
        it is the root). Needs to be computed dynamically from the
        starting position (0) as its position may change.

        :returns: absolute position of a Node in the tree
        :rtype: int

        :raises InternalError: if the absolute position cannot be found
        '''
        from psyclone.psyir.nodes import Schedule
        if self.root == self and isinstance(self.root, Schedule):
            return self.START_POSITION
        found, position = self._find_position(self.root.children,
                                              self.START_POSITION)
        if not found:
            raise InternalError("Error in search for Node position "
                                "in the tree")
        return position
github stfc / PSyclone / src / psyclone / psyir / nodes / loop.py View on Github external
are not of the expected type.

        '''
        if not isinstance(var_name, str):
            raise GenerationError(
                "var_name argument in create method of Loop class "
                "should be a string but found '{0}'."
                "".format(type(var_name).__name__))
        if not isinstance(children, list):
            raise GenerationError(
                "children argument in create method of Loop class "
                "should be a list but found '{0}'."
                "".format(type(children).__name__))

        loop = Loop(variable_name=var_name)
        schedule = Schedule(parent=loop, children=children)
        loop.children = [start, stop, step, schedule]
        for child in children:
            child.parent = schedule
        start.parent = loop
        stop.parent = loop
        step.parent = loop
        return loop
github stfc / PSyclone / src / psyclone / psyir / frontend / fparser2.py View on Github external
start_idx = clause_indices[idx]
            end_idx = clause_indices[idx+1]
            clause = node.content[start_idx]

            if isinstance(clause, (Fortran2003.If_Then_Stmt,
                                   Fortran2003.Else_If_Stmt)):
                # If it's an 'IF' clause just create an IfBlock, otherwise
                # it is an 'ELSE' clause and it needs an IfBlock annotated
                # with 'was_elseif' inside a Schedule.
                newifblock = None
                if isinstance(clause, Fortran2003.If_Then_Stmt):
                    ifblock = IfBlock(parent=currentparent)
                    ifblock.ast = node  # Keep pointer to fpaser2 AST
                    newifblock = ifblock
                else:
                    elsebody = Schedule(parent=currentparent)
                    currentparent.addchild(elsebody)
                    newifblock = IfBlock(parent=elsebody,
                                         annotations=['was_elseif'])
                    elsebody.addchild(newifblock)

                    # Keep pointer to fpaser2 AST
                    elsebody.ast = node.content[start_idx]
                    newifblock.ast = node.content[start_idx]

                # Create condition as first child
                self.process_nodes(parent=newifblock,
                                   nodes=[clause.items[0]])

                # Create if-body as second child
                ifbody = Schedule(parent=ifblock)
                ifbody.ast = node.content[start_idx + 1]