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))
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 __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
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
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")
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)
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
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
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)
def __init__(self, alg_calls): Schedule.__init__(self, GOKernCallFactory, GOBuiltInCallFactory, alg_calls)
def __init__(self, arg): Schedule.__init__(self, DynKernCallFactory, DynBuiltInCallFactory, arg)