Exemplo n.º 1
0
def test_basegen_start_parent_loop_omp_end_dbg(capsys):
    '''Check the debug option to the start_parent_loop method when we have
    an OpenMP end directive'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dgen = DirectiveGen(sub, "omp", "end", "do", "")
    sub.add(dgen)
    loop = DoGen(sub, "it", "1", "10")
    sub.add(loop)
    call = CallGen(loop, "testcall")
    loop.add(call)
    call.start_parent_loop(debug=True)
    out, _ = capsys.readouterr()
    print out
    expected = ("Parent is a do loop so moving to the parent\n"
                "The type of the current node is now <class "
                "'fparser.one.block_statements.Do'>\n"
                "The type of parent is <class "
                "'fparser.one.block_statements.Subroutine'>\n"
                "Finding the loops position in its parent ...\n"
                "The loop's index is  1\n"
                "The type of the object at the index is <class "
                "'fparser.one.block_statements.Do'>\n"
                "If preceding node is a directive then move back one\n"
                "preceding node is a directive so find out what type ...\n")

    assert expected in out
Exemplo n.º 2
0
def test_imp_none_exception_if_wrong_parent():
    ''' test that an exception is thrown if implicit none is added
    and the parent is not a module or a subroutine '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dogen = DoGen(sub, "i", "1", "10")
    sub.add(dogen)
    with pytest.raises(Exception):
        dogen.add(ImplicitNoneGen(dogen))
Exemplo n.º 3
0
    def gen_code(self, parent):
        '''
        Generate the Fortran Loop and any associated code.

        :param parent: the node in the f2pygen AST to which to add content.
        :type parent: :py:class:`psyclone.f2pygen.SubroutineGen`

        '''
        # Avoid circular dependency
        # pylint: disable=import-outside-toplevel
        from psyclone.psyGen import zero_reduction_variables, InvokeSchedule

        def is_unit_literal(expr):
            ''' Check if the given expression is equal to the literal '1'.

            :param expr: a PSyIR expression.
            :type expr: :py:class:`psyclone.psyir.nodes.Node`

            :returns: True if it is equal to the literal '1', false otherwise.
            '''
            return isinstance(expr, Literal) and expr.value == '1'

        if not self.is_openmp_parallel():
            calls = self.reductions()
            zero_reduction_variables(calls, parent)

        invoke = self.ancestor(InvokeSchedule)
        if invoke.opencl or (is_unit_literal(self.start_expr)
                             and is_unit_literal(self.stop_expr)):
            # no need for a loop
            for child in self.loop_body:
                child.gen_code(parent)
        else:
            # Avoid circular dependency
            # pylint: disable=import-outside-toplevel
            from psyclone.psyir.backend.fortran import FortranWriter
            # start/stop/step_expr are generated with the FortranWriter
            # backend, the rest of the loop with f2pygen.
            fwriter = FortranWriter()
            if is_unit_literal(self.step_expr):
                step_str = None
            else:
                step_str = fwriter(self.step_expr)

            do_stmt = DoGen(parent,
                            self.variable.name, fwriter(self.start_expr),
                            fwriter(self.stop_expr), step_str)
            # need to add do loop before children as children may want to add
            # info outside of do loop
            parent.add(do_stmt)
            for child in self.loop_body:
                child.gen_code(do_stmt)
            my_decl = DeclGen(parent,
                              datatype="integer",
                              entity_decls=[self.variable.name])
            parent.add(my_decl)
Exemplo n.º 4
0
def test_do_loop_with_increment():
    ''' Test that we correctly generate code for a do loop with
    non-unit increment '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsub")
    module.add(sub)
    dogen = DoGen(sub, "it", "1", "10", step="2")
    sub.add(dogen)
    count = count_lines(sub.root, "DO it=1,10,2")
    assert count == 1
Exemplo n.º 5
0
def test_basegen_start_parent_loop_dbg(capsys):
    '''Check the debug option to the start_parent_loop method'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    loop = DoGen(sub, "it", "1", "10")
    sub.add(loop)
    call = CallGen(loop, "testcall")
    loop.add(call)
    call.start_parent_loop(debug=True)
    out, _ = capsys.readouterr()
    print out
    expected = ("Parent is a do loop so moving to the parent\n"
                "The type of the current node is now <class "
                "'fparser.one.block_statements.Do'>\n"
                "The type of parent is <class "
                "'fparser.one.block_statements.Subroutine'>\n"
                "Finding the loops position in its parent ...\n"
                "The loop's index is  0\n")
    assert expected in out
Exemplo n.º 6
0
def test_add_before():
    ''' add the new code before a particular object '''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module, name="testsubroutine")
    module.add(subroutine)
    loop = DoGen(subroutine, "it", "1", "10")
    subroutine.add(loop)
    call = CallGen(subroutine, "testcall")
    subroutine.add(call, position=["before", loop.root])
    lines = str(module.root).splitlines()
    # the call should be inserted before the loop
    print lines
    assert "SUBROUTINE testsubroutine" in lines[3]
    assert "CALL testcall" in lines[4]
    assert "DO it=1,10" in lines[5]
Exemplo n.º 7
0
def test_do_loop_add_after():
    ''' Test that we correctly generate code for a do loop when adding a
    child to it with position *after* '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsub")
    module.add(sub)
    dogen = DoGen(sub, "it", "1", "10", step="2")
    sub.add(dogen)
    assign1 = AssignGen(dogen, lhs="happy", rhs=".TRUE.")
    dogen.add(assign1)
    assign2 = AssignGen(dogen, lhs="sad", rhs=".FALSE.")
    dogen.add(assign2, position=["before", assign1.root])
    a1_line = line_number(sub.root, "happy = ")
    a2_line = line_number(sub.root, "sad = ")
    assert a1_line > a2_line