예제 #1
0
def test_ifblock_children_region():
    ''' Check that we reject attempts to transform the conditional part of
    an If statement or to include both the if- and else-clauses in a region
    (without their parent). '''
    from psyclone.psyGen import IfBlock, Reference, Schedule
    from psyclone.transformations import ACCParallelTrans, TransformationError
    acct = ACCParallelTrans()
    # Construct a valid IfBlock
    ifblock = IfBlock()
    # Condition
    ref1 = Reference('condition1', parent=ifblock)
    ifblock.addchild(ref1)
    # If-body
    sch = Schedule(parent=ifblock)
    ifblock.addchild(sch)
    # Else-body
    sch2 = Schedule(parent=ifblock)
    ifblock.addchild(sch2)
    # Attempt to put all of the children of the IfBlock into a region. This
    # is an error because the first child is the conditional part of the
    # IfBlock.
    with pytest.raises(TransformationError) as err:
        super(ACCParallelTrans, acct)._validate(ifblock.children)
    assert ("transformation to the conditional expression (first child"
            in str(err))
    with pytest.raises(TransformationError) as err:
        super(ACCParallelTrans, acct)._validate(ifblock.children[1:])
    assert ("Cannot enclose both the if- and else- clauses of an IfBlock by "
            in str(err))
예제 #2
0
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)
예제 #3
0
    def __init__(self, alg_calls):
        Schedule.__init__(self, GOKernCallFactory, GOBuiltInCallFactory,
                          alg_calls)

        # Configuration of this Schedule - we default to having
        # constant loop bounds. If we end up having a long list
        # of configuration member variables here we may want
        # to create a a new ScheduleConfig object to manage them.
        self._const_loop_bounds = True
예제 #4
0
    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.psyGen.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()
        self.process_nodes(parent=fakeparent,
                           nodes=node.content[1:-1],
                           nodes_parent=node)

        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
예제 #5
0
def test_cw_ifblock():
    '''Check the CWriter class ifblock method correctly prints out the
    C representation.

    '''
    from psyclone.psyGen import IfBlock

    # Try with just a IfBlock node
    ifblock = IfBlock()
    cwriter = CWriter()
    with pytest.raises(VisitorError) as err:
        _ = cwriter(ifblock)
    assert("IfBlock malformed or incomplete. It should have "
           "at least 2 children, but found 0." in str(err.value))

    # Add the if condition
    ifblock.addchild(Reference('a', parent=ifblock))
    with pytest.raises(VisitorError) as err:
        _ = cwriter(ifblock)
    assert("IfBlock malformed or incomplete. It should have "
           "at least 2 children, but found 1." in str(err.value))

    # Fill the if_body and else_body
    ifblock.addchild(Schedule(parent=ifblock))
    ifblock.addchild(Schedule(parent=ifblock))
    ifblock.if_body.addchild(Return(parent=ifblock.if_body))

    ifblock2 = IfBlock(parent=ifblock.else_body)
    ifblock2.addchild(Reference('b', parent=ifblock2))
    ifblock2.addchild(Schedule(parent=ifblock2))
    ifblock2.if_body.addchild(Return(parent=ifblock2.if_body))
    ifblock2.addchild(Schedule(parent=ifblock2))
    ifblock2.else_body.addchild(Return(parent=ifblock2.else_body))

    ifblock.else_body.addchild(ifblock2)

    result = cwriter(ifblock)
    assert result == (
        "if (a) {\n"
        "  return;\n"
        "} else {\n"
        "  if (b) {\n"
        "    return;\n"
        "  } else {\n"
        "    return;\n"
        "  }\n"
        "}\n")
예제 #6
0
def test_size(expression, parser):
    ''' Basic test that the SIZE intrinsic is recognised and represented
    in the PSyIR. '''
    from fparser.two.Fortran2003 import Execution_Part
    from psyclone.psyGen import Schedule, Assignment, BinaryOperation, \
        Reference, Literal
    fake_parent = Schedule()
    processor = Fparser2Reader()
    reader = FortranStringReader(expression)
    fp2intrinsic = Execution_Part(reader).content[0]
    processor.process_nodes(fake_parent, [fp2intrinsic], None)
    assert isinstance(fake_parent[0], Assignment)
    assert isinstance(fake_parent[0].rhs, BinaryOperation)
    assert isinstance(fake_parent[0].rhs.children[0], Reference)
    assert isinstance(fake_parent[0].rhs.children[1], Literal)
예제 #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
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)
예제 #10
0
 def __init__(self, alg_calls):
     Schedule.__init__(self, GOKernCallFactory, GOBuiltInCallFactory,
                       alg_calls)
예제 #11
0
 def __init__(self, arg):
     Schedule.__init__(self, DynKernCallFactory, DynBuiltInCallFactory, arg)