示例#1
0
    def gen_code(self, parent):
        ''' Generate the Fortran source for this loop '''
        # Our schedule holds the names to use for the loop bounds.
        # Climb up the tree looking for our enclosing Schedule
        schedule = self.ancestor(GOSchedule)
        if schedule is None or not isinstance(schedule, GOSchedule):
            raise GenerationError("Internal error: cannot find parent"
                                  " GOSchedule for this Do loop")

        # Walk down the tree looking for a kernel so that we can
        # look-up what index-offset convention we are to use
        go_kernels = self.walk(self.children, GOKern)
        if len(go_kernels) == 0:
            raise GenerationError("Internal error: cannot find the "
                                  "GOcean Kernel enclosed by this loop")
        index_offset = go_kernels[0].index_offset
        if schedule.const_loop_bounds and \
           index_offset not in SUPPORTED_OFFSETS:
            raise GenerationError("Constant bounds generation"
                                  " not implemented for a grid offset "
                                  "of {0}. Supported offsets are {1}".format(
                                      index_offset, SUPPORTED_OFFSETS))
        # Check that all kernels enclosed by this loop expect the same
        # grid offset
        for kernel in go_kernels:
            if kernel.index_offset != index_offset:
                raise GenerationError("All Kernels must expect the same "
                                      "grid offset but kernel {0} has offset "
                                      "{1} which does not match {2}".format(
                                          kernel.name, kernel.index_offset,
                                          index_offset))
        # Generate the upper and lower loop bounds
        self._start = self._lower_bound()
        self._stop = self._upper_bound()
        Loop.gen_code(self, parent)
示例#2
0
    def gen_code(self, parent):

        if self.field_space == "every":
            from psyclone.f2pygen import DeclGen
            dim_var = DeclGen(parent, datatype="INTEGER",
                              entity_decls=[self._variable_name])
            parent.add(dim_var)

            # loop bounds
            self._start = "1"
            if self._loop_type == "inner":
                index = "1"
            elif self._loop_type == "outer":
                index = "2"
            self._stop = ("SIZE(" + self.field_name + ", " +
                          index + ")")

        else:  # one of our spaces so use values provided by the infrastructure

            # loop bounds
            if self._loop_type == "inner":
                self._start = self.field_space + "%istart"
                self._stop = self.field_space + "%istop"
            elif self._loop_type == "outer":
                self._start = self.field_space + "%jstart"
                self._stop = self.field_space + "%jstop"

        Loop.gen_code(self, parent)
示例#3
0
    def __init__(self, parent=None,
                 topology_name="", loop_type=""):
        Loop.__init__(self, parent=parent,
                      valid_loop_types=["inner", "outer"])
        self.loop_type = loop_type

        if self._loop_type == "inner":
            self._variable_name = "i"
        elif self._loop_type == "outer":
            self._variable_name = "j"
示例#4
0
 def gen_code(self, parent):
     ''' Work out the appropriate loop bounds and then call the base
         class to generate the code '''
     self._start = "1"
     if self._loop_type == "colours":
         self._stop = "ncolour"
     elif self._loop_type == "colour":
         self._stop = "ncp_ncolour(colour)"
     else:
         self._stop = self.field_name + "%get_ncell()"
     Loop.gen_code(self, parent)
示例#5
0
 def gen_code(self, parent):
     ''' Work out the appropriate loop bounds and then call the base
         class to generate the code '''
     self.start_expr = Literal("1", parent=self)
     if self._loop_type == "colours":
         self.stop_expr = Reference("ncolour", parent=self)
     elif self._loop_type == "colour":
         self.stop_expr = ArrayReference("ncp_ncolour", parent=self)
         self.stop_expr.addchild(Reference("colour"), parent=self.stop_expr)
     else:
         self.stop_expr = Reference(self.field_name + "%get_ncell()",
                                    parent=self)
     Loop.gen_code(self, parent)
示例#6
0
    def __init__(self, parent=None, loop_type=""):
        Loop.__init__(self,
                      parent=parent,
                      valid_loop_types=["", "colours", "colour"])
        self.loop_type = loop_type

        # Work out the variable name from  the loop type
        if self._loop_type == "colours":
            self._variable_name = "colour"
        elif self._loop_type == "colour":
            self._variable_name = "cell"
        else:
            self._variable_name = "cell"
示例#7
0
    def __init__(self, parent=None,
                 topology_name="", loop_type=""):
        Loop.__init__(self, parent=parent,
                      valid_loop_types=["inner", "outer"])
        self.loop_type = loop_type

        if self._loop_type == "inner":
            self._variable_name = "i"
        elif self._loop_type == "outer":
            self._variable_name = "j"

        # Pre-initialise the Loop children  # TODO: See issue #440
        self.addchild(Literal("NOT_INITIALISED", parent=self))  # start
        self.addchild(Literal("NOT_INITIALISED", parent=self))  # stop
        self.addchild(Literal("1", parent=self))  # step
        self.addchild(Schedule(parent=self))  # loop body
示例#8
0
    def __init__(self, parent=None, loop_type=""):
        Loop.__init__(self,
                      parent=parent,
                      valid_loop_types=["", "colours", "colour"])
        self.loop_type = loop_type

        # Work out the variable name from  the loop type
        if self._loop_type == "colours":
            self._variable_name = "colour"
        elif self._loop_type == "colour":
            self._variable_name = "cell"
        else:
            self._variable_name = "cell"

        # Pre-initialise the Loop children  # TODO: See issue #440
        self.addchild(Literal("NOT_INITIALISED", parent=self))  # start
        self.addchild(Literal("NOT_INITIALISED", parent=self))  # stop
        self.addchild(Literal("1", parent=self))  # step
        self.addchild(Schedule(parent=self))  # loop body
示例#9
0
文件: nemo.py 项目: pelson/PSyclone
    def __init__(self, ast, parent=None):
        from fparser.two.Fortran2003 import Loop_Control
        Loop.__init__(self, parent=parent, valid_loop_types=VALID_LOOP_TYPES)
        NemoFparser2ASTProcessor.__init__(self)
        # Keep a ptr to the corresponding node in the AST
        self._ast = ast

        # Get the loop variable
        ctrl = walk_ast(ast.content, [Loop_Control])
        # Second element of items member of Loop Control is itself a tuple
        # containing:
        #   Loop variable, [start value expression, end value expression, step
        #   expression]
        # Loop variable will be an instance of Fortran2003.Name
        loop_var = str(ctrl[0].items[1][0])
        self._variable_name = str(loop_var)

        # Identify the type of loop
        if self._variable_name in NEMO_LOOP_TYPE_MAPPING:
            self.loop_type = NEMO_LOOP_TYPE_MAPPING[self._variable_name]
        else:
            self.loop_type = "unknown"

        # Get the loop limits. These are given in a list which is the second
        # element of a tuple which is itself the second element of the items
        # tuple:
        # (None, (Name('jk'), [Int_Literal_Constant('1', None), Name('jpk'),
        #                      Int_Literal_Constant('1', None)]), None)
        limits_list = ctrl[0].items[1][1]
        self._start = str(limits_list[0])
        self._stop = str(limits_list[1])
        if len(limits_list) == 3:
            self._step = str(limits_list[2])
        else:
            # Default loop increment is 1
            self._step = "1"

        # Is this loop body a kernel?
        if NemoKern.match(self._ast):
            self.addchild(NemoKern(self._ast, parent=self))
            return
        # It's not - walk on down the AST...
        self.process_nodes(self, self._ast.content, self._ast)
示例#10
0
    def gen_code(self, parent):

        if self.field_space == "every":
            from psyclone.f2pygen import DeclGen
            from psyclone.psyGen import BinaryOperation, Reference
            dim_var = DeclGen(parent, datatype="INTEGER",
                              entity_decls=[self._variable_name])
            parent.add(dim_var)

            # Update start loop bound
            self.start_expr = Literal("1", 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(self.field_name,
                                              parent=self.stop_expr))
            self.stop_expr.addchild(Literal(index, 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)
            elif self._loop_type == "outer":
                self.start_expr = Reference(
                    self.field_space + "%jstart", parent=self)
                self.stop_expr = Reference(
                    self.field_space + "%jstop", parent=self)

        Loop.gen_code(self, parent)
示例#11
0
    def gen_code(self, parent):

        if self.field_space == "every":
            from psyclone.f2pygen import DeclGen
            dim_var = DeclGen(parent, datatype="INTEGER",
                              entity_decls=[self._variable_name])
            parent.add(dim_var)

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

            # Update stop loop bound
            if self._loop_type == "inner":
                index = "1"
            elif self._loop_type == "outer":
                index = "2"
            # TODO: Issue 440. Implement SIZE intrinsic in PSyIR
            self.stop_expr = Literal("SIZE(" + self.field_name + "," +
                                     index + ")", parent=self)

        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)
            elif self._loop_type == "outer":
                self.start_expr = Reference(
                    self.field_space + "%jstart", parent=self)
                self.stop_expr = Reference(
                    self.field_space + "%jstop", parent=self)

        Loop.gen_code(self, parent)
示例#12
0
def test_profile_basic(capsys):
    '''Check basic functionality: node names, schedule view.
    '''
    from psyclone.psyGen import colored, SCHEDULE_COLOUR_MAP
    Profiler.set_options([Profiler.INVOKES])
    _, invoke = get_invoke("test11_different_iterates_over_one_invoke.f90",
                           "gocean1.0",
                           idx=0)

    assert isinstance(invoke.schedule.children[0], ProfileNode)

    invoke.schedule.view()
    out, _ = capsys.readouterr()

    gsched = colored("GOInvokeSchedule", SCHEDULE_COLOUR_MAP["Schedule"])
    loop = Loop().coloured_text
    profile = invoke.schedule.children[0].coloured_text

    # Do one test based on schedule view, to make sure colouring
    # and indentation is correct
    expected = (gsched + "[invoke='invoke_0', Constant loop bounds=True]\n"
                "    " + profile + "\n"
                "        " + loop + "[type='outer', field_space='go_cv', "
                "it_space='go_internal_pts']\n")

    assert expected in out

    prt = ProfileRegionTrans()

    # Insert a profile call between outer and inner loop.
    # This tests that we find the subroutine node even
    # if it is not the immediate parent.
    new_sched, _ = prt.apply(
        invoke.schedule.children[0].children[0].children[0])

    new_sched_str = str(new_sched)

    correct = ("""GOInvokeSchedule(Constant loop bounds=True):
ProfileStart[var=profile]
GOLoop[id:'', variable:'j', loop_type:'outer']
Literal[value:'2']
Literal[value:'jstop-1']
Literal[value:'1']
Schedule:
GOLoop[id:'', variable:'i', loop_type:'inner']
Literal[value:'2']
Literal[value:'istop']
Literal[value:'1']
Schedule:
kern call: compute_cv_code
End Schedule
End GOLoop
End Schedule
End GOLoop
GOLoop[id:'', variable:'j', loop_type:'outer']
Literal[value:'1']
Literal[value:'jstop+1']
Literal[value:'1']
Schedule:
GOLoop[id:'', variable:'i', loop_type:'inner']
Literal[value:'1']
Literal[value:'istop+1']
Literal[value:'1']
Schedule:
kern call: bc_ssh_code
End Schedule
End GOLoop
End Schedule
End GOLoop
ProfileEnd
End Schedule""")
    assert correct in new_sched_str

    Profiler.set_options(None)
示例#13
0
def test_psy_data_trans_basic(capsys):
    '''Check basic functionality: node names, schedule view.
    '''
    _, invoke = get_invoke("test11_different_iterates_over_one_invoke.f90",
                           "gocean1.0",
                           idx=0,
                           dist_mem=False)
    schedule = invoke.schedule
    # This test expects constant loop bounds
    schedule._const_loop_bounds = True

    data_trans = PSyDataTrans()
    assert "Create a sub-tree of the PSyIR that has a node of type " \
           "PSyDataNode at its root" in str(data_trans)

    assert data_trans.name == "PSyDataTrans"
    data_trans.apply(schedule)

    assert isinstance(invoke.schedule[0], PSyDataNode)

    schedule.view()
    out, _ = capsys.readouterr()

    gsched = colored("GOInvokeSchedule", GOInvokeSchedule._colour)
    sched = colored("Schedule", Schedule._colour)
    loop = Loop().coloured_name(True)
    data = invoke.schedule[0].coloured_name(True)

    # Do one test based on schedule view, to make sure colouring
    # and indentation is correct
    expected = (gsched + "[invoke='invoke_0', Constant loop bounds=True]\n"
                "    0: " + data + "[]\n"
                "        " + sched + "[]\n"
                "            0: " + loop +
                "[type='outer', field_space='go_cv', "
                "it_space='go_internal_pts']\n")
    assert expected in out

    # Insert a DataTrans call between outer and inner loop.
    # This tests that we find the subroutine node even
    # if it is not the immediate parent.
    data_trans.apply(invoke.schedule[0].psy_data_body[0].loop_body[0])

    new_sched_str = str(invoke.schedule)
    correct = ("""GOInvokeSchedule[invoke='invoke_0', \
Constant loop bounds=True]:
PSyDataStart[var=psy_data]
GOLoop[id:'', variable:'j', loop_type:'outer']
Literal[value:'2', Scalar<INTEGER, UNDEFINED>]
Literal[value:'jstop-1', Scalar<INTEGER, UNDEFINED>]
Literal[value:'1', Scalar<INTEGER, UNDEFINED>]
Schedule:
PSyDataStart[var=psy_data_1]
GOLoop[id:'', variable:'i', loop_type:'inner']
Literal[value:'2', Scalar<INTEGER, UNDEFINED>]
Literal[value:'istop', Scalar<INTEGER, UNDEFINED>]
Literal[value:'1', Scalar<INTEGER, UNDEFINED>]
Schedule:
kern call: compute_cv_code
End Schedule
End GOLoop
PSyDataEnd[var=psy_data_1]
End Schedule
End GOLoop
GOLoop[id:'', variable:'j', loop_type:'outer']
Literal[value:'1', Scalar<INTEGER, UNDEFINED>]
Literal[value:'jstop+1', Scalar<INTEGER, UNDEFINED>]
Literal[value:'1', Scalar<INTEGER, UNDEFINED>]
Schedule:
GOLoop[id:'', variable:'i', loop_type:'inner']
Literal[value:'1', Scalar<INTEGER, UNDEFINED>]
Literal[value:'istop+1', Scalar<INTEGER, UNDEFINED>]
Literal[value:'1', Scalar<INTEGER, UNDEFINED>]
Schedule:
kern call: bc_ssh_code
End Schedule
End GOLoop
End Schedule
End GOLoop
PSyDataEnd[var=psy_data]
End Schedule""")

    assert correct in new_sched_str
示例#14
0
def test_profile_basic(capsys):
    '''Check basic functionality: node names, schedule view.
    '''
    Profiler.set_options([Profiler.INVOKES])
    _, invoke = get_invoke("test11_different_iterates_over_one_invoke.f90",
                           "gocean1.0", idx=0)

    assert isinstance(invoke.schedule.children[0], ProfileNode)

    invoke.schedule.view()
    out, _ = capsys.readouterr()

    coloured_schedule = GOSchedule([]).coloured_text
    coloured_loop = Loop().coloured_text
    coloured_kern = GOKern().coloured_text
    coloured_profile = invoke.schedule.children[0].coloured_text

    # Do one test based on schedule view, to make sure colouring
    # and indentation is correct
    correct = (
        '''{0}[invoke='invoke_0',Constant loop bounds=True]
    {3}
        {1}[type='outer',field_space='go_cv',it_space='go_internal_pts']
            {1}[type='inner',field_space='go_cv',it_space='go_internal_pts']
                {2} compute_cv_code(cv_fld,p_fld,v_fld) '''
        '''[module_inline=False]
        {1}[type='outer',field_space='go_ct',it_space='go_all_pts']
            {1}[type='inner',field_space='go_ct',it_space='go_all_pts']
                {2} bc_ssh_code(ncycle,p_fld,tmask) '''
        '''[module_inline=False]'''.format(coloured_schedule, coloured_loop,
                                           coloured_kern, coloured_profile)
    )
    assert correct in out

    prt = ProfileRegionTrans()

    # Insert a profile call between outer and inner loop.
    # This tests that we find the subroutine node even
    # if it is not the immediate parent.
    new_sched, _ = prt.apply(invoke.schedule.children[0]
                             .children[0].children[0])

    new_sched_str = str(new_sched)

    correct = ("""GOSchedule(Constant loop bounds=True):
ProfileStart[var=profile]
Loop[]: j= lower=2,jstop-1,1
ProfileStart[var=profile_1]
Loop[]: i= lower=2,istop,1
kern call: compute_cv_code
EndLoop
ProfileEnd
EndLoop
Loop[]: j= lower=1,jstop+1,1
Loop[]: i= lower=1,istop+1,1
kern call: bc_ssh_code
EndLoop
EndLoop
ProfileEnd
End Schedule""")

    assert correct in new_sched_str

    Profiler.set_options(None)
示例#15
0
 def __init__(self, parent=None, variable_name=''):
     valid_loop_types = Config.get().api_conf("nemo").get_valid_loop_types()
     Loop.__init__(self,
                   parent=parent,
                   variable_name=variable_name,
                   valid_loop_types=valid_loop_types)
示例#16
0
    def __init__(self, parent=None, topology_name="", loop_type=""):
        Loop.__init__(self, parent=parent, valid_loop_types=VALID_LOOP_TYPES)
        self.loop_type = loop_type

        # We set the loop variable name in the constructor so that it is
        # available when we're determining which vars should be OpenMP
        # PRIVATE (which is done *before* code generation is performed)
        if self.loop_type == "inner":
            self._variable_name = "i"
        elif self.loop_type == "outer":
            self._variable_name = "j"
        else:
            raise GenerationError(
                "Invalid loop type of '{0}'. Expected one of {1}".format(
                    self._loop_type, VALID_LOOP_TYPES))

        # Create a dictionary to simplify the business of looking-up
        # loop bounds
        self._bounds_lookup = {}
        for grid_offset in SUPPORTED_OFFSETS:
            self._bounds_lookup[grid_offset] = {}
            for gridpt_type in VALID_FIELD_GRID_TYPES:
                self._bounds_lookup[grid_offset][gridpt_type] = {}
                for itspace in VALID_ITERATES_OVER:
                    self._bounds_lookup[grid_offset][gridpt_type][itspace] = {}

        # Loop bounds for a mesh with NE offset
        self._bounds_lookup['offset_ne']['ct']['all_pts'] = \
            {'inner': {'start': "1", 'stop': "+1"},
             'outer': {'start': "1", 'stop': "+1"}}
        self._bounds_lookup['offset_ne']['ct']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': ""},
             'outer': {'start': "2", 'stop': ""}}
        self._bounds_lookup['offset_ne']['cu']['all_pts'] = \
            {'inner': {'start': "1", 'stop': ""},
             'outer': {'start': "1", 'stop': "+1"}}
        self._bounds_lookup['offset_ne']['cu']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': "-1"},
             'outer': {'start': "2", 'stop': ""}}
        self._bounds_lookup['offset_ne']['cv']['all_pts'] = \
            {'inner': {'start': "1", 'stop': "+1"},
             'outer': {'start': "1", 'stop': ""}}
        self._bounds_lookup['offset_ne']['cv']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': ""},
             'outer': {'start': "2", 'stop': "-1"}}
        self._bounds_lookup['offset_ne']['cf']['all_pts'] = \
            {'inner': {'start': "1", 'stop': ""},
             'outer': {'start': "1", 'stop': ""}}
        self._bounds_lookup['offset_ne']['cf']['internal_pts'] = \
            {'inner': {'start': "1", 'stop': "-1"},
             'outer': {'start': "1", 'stop': "-1"}}
        # Loop bounds for a mesh with SE offset
        self._bounds_lookup['offset_sw']['ct']['all_pts'] = \
            {'inner': {'start': "1", 'stop': "+1"},
             'outer': {'start': "1", 'stop': "+1"}}
        self._bounds_lookup['offset_sw']['ct']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': ""},
             'outer': {'start': "2", 'stop': ""}}
        self._bounds_lookup['offset_sw']['cu']['all_pts'] = \
            {'inner': {'start': "1", 'stop': "+1"},
             'outer': {'start': "1", 'stop': "+1"}}
        self._bounds_lookup['offset_sw']['cu']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': "+1"},
             'outer': {'start': "2", 'stop': ""}}
        self._bounds_lookup['offset_sw']['cv']['all_pts'] = \
            {'inner': {'start': "1", 'stop': "+1"},
             'outer': {'start': "1", 'stop': "+1"}}
        self._bounds_lookup['offset_sw']['cv']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': ""},
             'outer': {'start': "2", 'stop': "+1"}}
        self._bounds_lookup['offset_sw']['cf']['all_pts'] = \
            {'inner': {'start': "1", 'stop': "+1"},
             'outer': {'start': "1", 'stop': "+1"}}
        self._bounds_lookup['offset_sw']['cf']['internal_pts'] = \
            {'inner': {'start': "2", 'stop': "+1"},
             'outer': {'start': "2", 'stop': "+1"}}
        # For offset 'any'
        for gridpt_type in VALID_FIELD_GRID_TYPES:
            for itspace in VALID_ITERATES_OVER:
                self._bounds_lookup['offset_any'][gridpt_type][itspace] = \
                    {'inner': {'start': "1", 'stop': ""},
                     'outer': {'start': "1", 'stop': ""}}
        # For 'every' grid-point type
        for offset in SUPPORTED_OFFSETS:
            for itspace in VALID_ITERATES_OVER:
                self._bounds_lookup[offset]['every'][itspace] = \
                    {'inner': {'start': "1", 'stop': "+1"},
                     'outer': {'start': "1", 'stop': "+1"}}
def test_fusetrans_error_not_same_parent():
    ''' Check that we reject attempts to fuse loops which don't share the
    same parent '''
    from psyclone.psyGen import Loop, Schedule, Literal
    from psyclone.transformations import LoopFuseTrans, TransformationError

    sch1 = Schedule()
    sch2 = Schedule()
    loop1 = Loop(variable_name="i", parent=sch1)
    loop2 = Loop(variable_name="j", parent=sch2)
    sch1.addchild(loop1)
    sch2.addchild(loop2)

    loop1.addchild(Literal("1", parent=loop1))  # start
    loop1.addchild(Literal("10", parent=loop1))  # stop
    loop1.addchild(Literal("1", parent=loop1))  # step
    loop1.addchild(Schedule(parent=loop1))  # loop body

    loop2.addchild(Literal("1", parent=loop2))  # start
    loop2.addchild(Literal("10", parent=loop2))  # stop
    loop2.addchild(Literal("1", parent=loop2))  # step
    loop2.addchild(Schedule(parent=loop2))  # loop body

    fuse = LoopFuseTrans()

    # Try to fuse loops with different parents
    with pytest.raises(TransformationError) as err:
        fuse.validate(loop1, loop2)
    assert "Error in LoopFuse transformation. Loops do not have the " \
        "same parent" in str(err.value)
def test_fusetrans_error_incomplete():
    ''' Check that we reject attempts to fuse loops which are incomplete. '''
    from psyclone.psyGen import Loop, Schedule, Literal, Return
    from psyclone.transformations import LoopFuseTrans, TransformationError
    sch = Schedule()
    loop1 = Loop(variable_name="i", parent=sch)
    loop2 = Loop(variable_name="j", parent=sch)
    sch.addchild(loop1)
    sch.addchild(loop2)

    fuse = LoopFuseTrans()

    # Check first loop
    with pytest.raises(TransformationError) as err:
        fuse.validate(loop1, loop2)
    assert "Error in LoopFuse transformation. The first loop does not have " \
        "4 children." in str(err.value)

    loop1.addchild(Literal("start", parent=loop1))
    loop1.addchild(Literal("stop", parent=loop1))
    loop1.addchild(Literal("step", parent=loop1))
    loop1.addchild(Schedule(parent=loop1))
    loop1.loop_body.addchild(Return(parent=loop1.loop_body))

    # Check second loop
    with pytest.raises(TransformationError) as err:
        fuse.validate(loop1, loop2)
    assert "Error in LoopFuse transformation. The second loop does not have " \
        "4 children." in str(err.value)

    loop2.addchild(Literal("start", parent=loop2))
    loop2.addchild(Literal("stop", parent=loop2))
    loop2.addchild(Literal("step", parent=loop2))
    loop2.addchild(Schedule(parent=loop2))
    loop2.loop_body.addchild(Return(parent=loop2.loop_body))

    # Validation should now pass
    fuse.validate(loop1, loop2)
示例#19
0
文件: nemo.py 项目: pelson/PSyclone
 def __init__(self, ast, parent=None):
     Loop.__init__(self, parent=parent, valid_loop_types=VALID_LOOP_TYPES)
     # Keep a ptr to the corresponding node in the AST
     self._ast = ast
示例#20
0
 def __init__(self, ast, parent=None):
     # pylint: disable=super-init-not-called, non-parent-init-called
     valid_loop_types = Config.get().api_conf("nemo").get_valid_loop_types()
     Loop.__init__(self, parent=parent, valid_loop_types=valid_loop_types)
     # Keep a ptr to the corresponding node in the AST
     self._ast = ast