Esempio n. 1
0
 def gen_code(self, parent):
     ''' Generates GOcean specific invocation code (the subroutine called
         by the associated invoke call in the algorithm layer). This
         consists of the PSy invocation subroutine and the declaration of
         its arguments.'''
     from psyclone.f2pygen import SubroutineGen, DeclGen, TypeDeclGen
     # create the subroutine
     invoke_sub = SubroutineGen(parent, name=self.name,
                                args=self.psy_unique_var_names)
     parent.add(invoke_sub)
     self.schedule.gen_code(invoke_sub)
     # add the subroutine argument declarations for arrays
     if len(self.unique_args_arrays) > 0:
         my_decl_arrays = DeclGen(invoke_sub, datatype="REAL",
                                  intent="inout", kind="go_wp",
                                  entity_decls=self.unique_args_arrays,
                                  dimension=":,:")
         invoke_sub.add(my_decl_arrays)
     # add the subroutine argument declarations for scalars
     if len(self.unique_args_scalars) > 0:
         my_decl_scalars = \
             TypeDeclGen(invoke_sub,
                         datatype="scalar_field_type",
                         entity_decls=self.unique_args_scalars,
                         intent="inout")
         invoke_sub.add(my_decl_scalars)
Esempio n. 2
0
def test_imp_none_in_subroutine():
    ''' test that implicit none can be added to a subroutine '''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module, name="testsubroutine")
    module.add(subroutine)
    subroutine.add(ImplicitNoneGen(subroutine))
    assert 'IMPLICIT NONE' in str(subroutine.root)
Esempio n. 3
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
Esempio n. 4
0
def test_basegen_append():
    '''Check that we can append an object to the tree'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(CommentGen(sub, " hello"), position=["append"])
    cindex = line_number(sub.root, "hello")
    assert cindex == 3
Esempio n. 5
0
def test_basegen_first():
    '''Check that we can insert an object as the first child'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(CommentGen(sub, " hello"), position=["first"])
    cindex = line_number(sub.root, "hello")
    assert cindex == 1
Esempio n. 6
0
def test_progunitgen_multiple_use1():
    '''Check that we correctly handle the case where duplicate use statements
    are added but one is specific'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(UseGen(sub, name="fred"))
    sub.add(UseGen(sub, name="fred", only=True, funcnames=["astaire"]))
    assert count_lines(sub.root, "USE fred") == 1
Esempio n. 7
0
def test_progunitgen_multiple_generic_use():
    '''Check that we correctly handle the case where duplicate use statements
    are added'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(UseGen(sub, name="fred"))
    sub.add(UseGen(sub, name="fred"))
    assert count_lines(sub.root, "USE fred") == 1
Esempio n. 8
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
Esempio n. 9
0
def test_imp_none_in_subroutine_already_exists():
    ''' test that implicit none is not added to a subroutine when
    one already exists'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine", implicitnone=True)
    module.add(sub)
    sub.add(ImplicitNoneGen(sub))
    count = count_lines(sub.root, "IMPLICIT NONE")
    assert count == 1, \
        "There should only be one instance of IMPLICIT NONE"
Esempio n. 10
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))
Esempio n. 11
0
def test_basegen_start_parent_loop_no_loop_dbg():
    '''Check the debug option to the start_parent_loop method when we have
    no loop'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dgen = DirectiveGen(sub, "omp", "end", "do", "")
    sub.add(dgen)
    call = CallGen(sub, name="testcall", args=["a", "b"])
    sub.add(call)
    with pytest.raises(RuntimeError) as err:
        call.start_parent_loop(debug=True)
    assert "This node has no enclosing Do loop" in str(err)
Esempio n. 12
0
def test_basegen_after_index():
    '''Check that we can insert an object using "after_index"'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var2"]))
    sub.add(CommentGen(sub, " hello"), position=["after_index", 1])
    # The code checked by line_number() *includes* the SUBROUTINE
    # statement (which is obviously not a child of the SubroutineGen
    # object) and therefore the index it returns is 1 greater than we
    # might expect.
    assert line_number(sub.root, "hello") == 3
Esempio n. 13
0
def test_basegen_before_error():
    '''Check that we raise an error when attempting to insert an object
    before another object that is not present in the tree'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var2"]))
    # Create an object but do not add it as a child of sub
    dgen = DeclGen(sub, datatype="real", entity_decls=["rvar1"])
    # Try to add an object before the orphan dgen
    with pytest.raises(RuntimeError) as err:
        sub.add(CommentGen(sub, " hello"), position=["before", dgen])
    assert "Failed to find supplied object" in str(err)
Esempio n. 14
0
def test_typeselectiongen():
    ''' Check that SelectionGen works as expected for a type '''
    from psyclone.f2pygen import SelectionGen
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sgen = SelectionGen(sub, expr="my_var=>another_var", typeselect=True)
    sub.add(sgen)
    agen = AssignGen(sgen, lhs="happy", rhs=".TRUE.")
    sgen.addcase("fspace", [agen])
    sgen.adddefault()
    gen = str(sub.root)
    print gen
    assert "SELECT TYPE ( my_var=>another_var )" in gen
    assert "TYPE IS ( fspace )" in gen
Esempio n. 15
0
def test_subroutine_var_with_implicit_none():
    ''' test that a variable is added after an implicit none
    statement in a subroutine'''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module,
                               name="testsubroutine",
                               implicitnone=True)
    module.add(subroutine)
    subroutine.add(
        DeclGen(subroutine, datatype="integer", entity_decls=["var1"]))
    idx_var = line_number(subroutine.root, "INTEGER var1")
    idx_imp_none = line_number(subroutine.root, "IMPLICIT NONE")
    print str(module.root)
    assert idx_var - idx_imp_none == 1, \
        "variable declation must be after implicit none"
Esempio n. 16
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
Esempio n. 17
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]
Esempio n. 18
0
def test_selectiongen_addcase():
    ''' Check that SelectionGen.addcase() works as expected when no
    content is supplied'''
    from psyclone.f2pygen import SelectionGen
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sgen = SelectionGen(sub, expr="my_var")
    sub.add(sgen)
    sgen.addcase("1")
    gen = str(sub.root)
    print gen
    expected = ("      SELECT CASE ( my_var )\n"
                "        CASE ( 1 )\n"
                "      END SELECT")
    assert expected in gen
Esempio n. 19
0
def test_imp_none_in_subroutine_with_use_and_decs_and_comments():
    ''' test that implicit none is added after any use statements
    and before any declarations in a subroutine in the presence of
    comments when auto (the default) is used for insertion'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(TypeDeclGen(sub, datatype="my_type", entity_decls=["type1"]))
    sub.add(UseGen(sub, "fred"))
    for idx in [0, 1, 2, 3]:
        sub.add(CommentGen(sub, " hello " + str(idx)),
                position=["before_index", 2 * idx])
    sub.add(ImplicitNoneGen(sub))
    in_idx = line_number(sub.root, "IMPLICIT NONE")
    assert in_idx == 3
Esempio n. 20
0
def test_decl_no_replication_scalars():
    '''Check that the same scalar variable will only get declared once in
    a module and a subroutine'''
    variable_name = "arg_name"
    datatype = "integer"
    module = ModuleGen(name="testmodule")
    module.add(DeclGen(module, datatype=datatype,
                       entity_decls=[variable_name]))
    module.add(DeclGen(module, datatype=datatype,
                       entity_decls=[variable_name]))
    subroutine = SubroutineGen(module, name="testsubroutine")
    module.add(subroutine)
    subroutine.add(
        DeclGen(subroutine, datatype=datatype, entity_decls=[variable_name]))
    subroutine.add(
        DeclGen(subroutine, datatype=datatype, entity_decls=[variable_name]))
    generated_code = str(module.root)
    assert generated_code.count(variable_name) == 2
Esempio n. 21
0
 def gen_code(self, parent):
     ''' Generates Dynamo specific invocation code (the subroutine called
         by the associated invoke call in the algorithm layer). This
         consists of the PSy invocation subroutine and the declaration of
         its arguments.'''
     from psyclone.f2pygen import SubroutineGen, TypeDeclGen
     # create the subroutine
     invoke_sub = SubroutineGen(parent,
                                name=self.name,
                                args=self.psy_unique_var_names)
     self.schedule.gen_code(invoke_sub)
     parent.add(invoke_sub)
     # add the subroutine argument declarations
     my_typedecl = TypeDeclGen(invoke_sub,
                               datatype="field_type",
                               entity_decls=self.psy_unique_var_names,
                               intent="inout")
     invoke_sub.add(my_typedecl)
Esempio n. 22
0
def test_subroutine_var_intent_in_with_directive():
    ''' test that a variable declared as intent in is added before
    a directive in a subroutine'''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module,
                               name="testsubroutine",
                               implicitnone=False)
    module.add(subroutine)
    subroutine.add(DirectiveGen(subroutine, "omp", "begin", "parallel", ""))
    subroutine.add(
        DeclGen(subroutine,
                datatype="integer",
                intent="in",
                entity_decls=["var1"]))
    idx_par = line_number(subroutine.root, "!$omp parallel")
    idx_var = line_number(subroutine.root, "INTEGER, intent(in) :: var1")
    print str(module.root)
    assert idx_par - idx_var == 1, \
        "variable declaration must be before directive"
Esempio n. 23
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