Esempio n. 1
0
def test_loop_navigation_properties():
    # pylint: disable=too-many-statements
    ''' Tests the start_expr, stop_expr, step_expr and loop_body
    setter and getter properties.

    '''
    loop = Loop()

    # Properties return an error if the node is incomplete
    error_str = ("Loop is incomplete. It should have exactly 4 "
                 "children, but found")
    with pytest.raises(InternalError) as err:
        _ = loop.start_expr
    assert error_str in str(err.value)

    loop.addchild(Literal("start", INTEGER_SINGLE_TYPE))
    loop.addchild(Literal("stop", INTEGER_SINGLE_TYPE))
    loop.addchild(Literal("step", INTEGER_SINGLE_TYPE))

    # If it's not fully complete, it still returns an error
    with pytest.raises(InternalError) as err:
        _ = loop.start_expr
    assert error_str in str(err.value)
    with pytest.raises(InternalError) as err:
        _ = loop.stop_expr
    assert error_str in str(err.value)
    with pytest.raises(InternalError) as err:
        _ = loop.step_expr
    assert error_str in str(err.value)
    with pytest.raises(InternalError) as err:
        _ = loop.loop_body
    assert error_str in str(err.value)
    with pytest.raises(InternalError) as err:
        loop.start_expr = Literal("invalid", INTEGER_SINGLE_TYPE)
    assert error_str in str(err.value)
    with pytest.raises(InternalError) as err:
        loop.stop_expr = Literal("invalid", INTEGER_SINGLE_TYPE)
    assert error_str in str(err.value)
    with pytest.raises(InternalError) as err:
        loop.step_expr = Literal("invalid", INTEGER_SINGLE_TYPE)
    assert error_str in str(err.value)

    # Check that Getters properties work
    loop.addchild(Schedule(parent=loop))
    loop.loop_body.addchild(Return(parent=loop.loop_body))

    assert loop.start_expr.value == "start"
    assert loop.stop_expr.value == "stop"
    assert loop.step_expr.value == "step"
    assert isinstance(loop.loop_body[0], Return)

    # Test Setters
    loop.start_expr = Literal("newstart", INTEGER_SINGLE_TYPE)
    loop.stop_expr = Literal("newstop", INTEGER_SINGLE_TYPE)
    loop.step_expr = Literal("newstep", INTEGER_SINGLE_TYPE)

    assert loop.start_expr.value == "newstart"
    assert loop.stop_expr.value == "newstop"
    assert loop.step_expr.value == "newstep"
Esempio n. 2
0
def test_regiontrans_wrong_children():
    ''' Check that the validate method raises the expected error if
        passed the wrong children of a Node. (e.g. those representing the
        bounds of a Loop.) '''
    # RegionTrans is abstract so use a concrete sub-class
    rtrans = ACCParallelTrans()
    # Construct a valid Loop in the PSyIR
    parent = Loop(parent=None)
    parent.addchild(Literal("1", INTEGER_TYPE, parent))
    parent.addchild(Literal("10", INTEGER_TYPE, parent))
    parent.addchild(Literal("1", INTEGER_TYPE, parent))
    parent.addchild(Schedule(parent=parent))
    with pytest.raises(TransformationError) as err:
        RegionTrans.validate(rtrans, parent.children)
    assert ("Cannot apply a transformation to multiple nodes when one or more "
            "is a Schedule" in str(err.value))
Esempio n. 3
0
def test_loop_children_validation():
    '''Test that children added to Loop are validated. Loop accepts
    3 DataNodes and a Schedule.

    '''
    loop = Loop()
    datanode1 = Literal("1", INTEGER_SINGLE_TYPE)
    datanode2 = Literal("2", INTEGER_SINGLE_TYPE)
    datanode3 = Literal("3", INTEGER_SINGLE_TYPE)
    schedule = Schedule(parent=loop)

    # First child
    with pytest.raises(GenerationError) as excinfo:
        loop.addchild(schedule)
    assert ("Item 'Schedule' can't be child 0 of 'Loop'. The valid format is: "
            "'DataNode, DataNode, DataNode, Schedule'." in str(excinfo.value))
    loop.addchild(datanode1)

    # Second child
    with pytest.raises(GenerationError) as excinfo:
        loop.addchild(schedule)
    assert ("Item 'Schedule' can't be child 1 of 'Loop'. The valid format is: "
            "'DataNode, DataNode, DataNode, Schedule'." in str(excinfo.value))
    loop.addchild(datanode2)

    # Third child
    with pytest.raises(GenerationError) as excinfo:
        loop.addchild(schedule)
    assert ("Item 'Schedule' can't be child 2 of 'Loop'. The valid format is: "
            "'DataNode, DataNode, DataNode, Schedule'." in str(excinfo.value))
    loop.addchild(datanode3)

    # Fourth child
    with pytest.raises(GenerationError) as excinfo:
        loop.addchild(datanode1)
    assert ("Item 'Literal' can't be child 3 of 'Loop'. The valid format is: "
            "'DataNode, DataNode, DataNode, Schedule'." in str(excinfo.value))
    loop.addchild(schedule)

    # Additional children
    with pytest.raises(GenerationError) as excinfo:
        loop.addchild(schedule)
    assert ("Item 'Schedule' can't be child 4 of 'Loop'. The valid format is: "
            "'DataNode, DataNode, DataNode, Schedule'." in str(excinfo.value))
Esempio n. 4
0
def test_fusetrans_error_incomplete():
    ''' Check that we reject attempts to fuse loops which are incomplete. '''
    sch = Schedule()
    loop1 = Loop(variable=DataSymbol("i", INTEGER_TYPE))
    loop2 = Loop(variable=DataSymbol("j", INTEGER_TYPE))
    sch.addchild(loop1)
    sch.addchild(loop2)

    fuse = LoopFuseTrans()

    # Check first loop
    with pytest.raises(TransformationError) as err:
        fuse.validate(loop1, loop2)
    assert ("Error in LoopFuseTrans transformation. The target loop must have "
            "four children but found: []" in str(err.value))

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

    # Check second loop
    with pytest.raises(TransformationError) as err:
        fuse.validate(loop1, loop2)
    assert ("Error in LoopFuseTrans transformation. The target loop must have "
            "four children but found: []" in str(err.value))

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

    # Validation should now pass
    fuse.validate(loop1, loop2)
Esempio n. 5
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.transformations import LoopFuseTrans

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

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

    loop2.addchild(Literal("1", INTEGER_TYPE, parent=loop2))  # start
    loop2.addchild(Literal("10", INTEGER_TYPE, parent=loop2))  # stop
    loop2.addchild(Literal("1", INTEGER_TYPE, 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 LoopFuseTrans transformation. Loops do not have the "
            "same parent" in str(err.value))
Esempio n. 6
0
def test_fusetrans_error_incomplete():
    ''' Check that we reject attempts to fuse loops which are incomplete. '''
    from psyclone.psyir.nodes import Return
    from psyclone.transformations import LoopFuseTrans
    sch = Schedule()
    loop1 = Loop(variable=DataSymbol("i", INTEGER_TYPE), parent=sch)
    loop2 = Loop(variable=DataSymbol("j", INTEGER_TYPE), 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", INTEGER_TYPE, parent=loop1))
    loop1.addchild(Literal("stop", INTEGER_TYPE, parent=loop1))
    loop1.addchild(Literal("step", INTEGER_TYPE, 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", INTEGER_TYPE, parent=loop2))
    loop2.addchild(Literal("stop", INTEGER_TYPE, parent=loop2))
    loop2.addchild(Literal("step", INTEGER_TYPE, parent=loop2))
    loop2.addchild(Schedule(parent=loop2))
    loop2.loop_body.addchild(Return(parent=loop2.loop_body))

    # Validation should now pass
    fuse.validate(loop1, loop2)