def test_range_view(capsys): ''' Check that calling view() on an array with a child Range works as expected. ''' from psyclone.psyir.nodes import Array from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP # Create the PSyIR for 'my_array(1, 1:10)' erange = Range.create(Literal("1", INTEGER_SINGLE_TYPE), Literal("10", INTEGER_SINGLE_TYPE)) array_type = ArrayType(REAL_SINGLE_TYPE, [10, 10]) array = Array.create(DataSymbol("my_array", array_type), [Literal("1", INTEGER_SINGLE_TYPE), erange]) array.view() stdout, _ = capsys.readouterr() arrayref = colored("ArrayReference", SCHEDULE_COLOUR_MAP[array._colour_key]) literal = colored("Literal", SCHEDULE_COLOUR_MAP[array.children[0]._colour_key]) rangestr = colored("Range", SCHEDULE_COLOUR_MAP[erange._colour_key]) indent = " " assert (arrayref + "[name:'my_array']\n" + indent + literal + "[value:'1', Scalar<INTEGER, SINGLE>]\n" + indent + rangestr + "[]\n" + 2 * indent + literal + "[value:'1', Scalar<INTEGER, SINGLE>]\n" + 2 * indent + literal + "[value:'10', Scalar<INTEGER, SINGLE>]\n" + 2 * indent + literal + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" in stdout)
def test_ifblock_view_indices(capsys): ''' Check that the view method only displays indices on the nodes in the body (and else body) of an IfBlock. ''' colouredif = colored("If", IfBlock._colour) colouredreturn = colored("Return", Return._colour) colouredref = colored("Reference", Reference._colour) condition = Reference(DataSymbol('condition1', REAL_SINGLE_TYPE)) then_content = [Return()] ifblock = IfBlock.create(condition, then_content) ifblock.view() output, _ = capsys.readouterr() # Check that we only prepend child indices where it makes sense assert colouredif + "[]" in output assert "0: " + colouredreturn in output assert ": " + colouredref not in output
def test_unaryoperation_node_str(): ''' Check the view method of the UnaryOperation class.''' ref1 = Reference(DataSymbol("a", REAL_SINGLE_TYPE)) unary_operation = UnaryOperation.create(UnaryOperation.Operator.MINUS, ref1) coloredtext = colored("UnaryOperation", UnaryOperation._colour) assert coloredtext+"[operator:'MINUS']" in unary_operation.node_str()
def test_literal_node_str(): ''' Check the node_str method of the Literal class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP # scalar literal literal = Literal("1", INTEGER_SINGLE_TYPE) coloredtext = colored("Literal", SCHEDULE_COLOUR_MAP["Literal"]) assert (coloredtext + "[value:'1', Scalar<INTEGER, SINGLE>]" in literal.node_str()) # array literal array_type = ArrayType(REAL_DOUBLE_TYPE, [10, 10]) literal = Literal("1", array_type) coloredtext = colored("Literal", SCHEDULE_COLOUR_MAP["Literal"]) assert (coloredtext + "[value:'1', Array<Scalar<REAL, DOUBLE>, " "shape=[10, 10]>]" in literal.node_str())
def test_literal_node_str(): ''' Check the node_str method of the Literal class.''' # scalar literal literal = Literal("1", INTEGER_SINGLE_TYPE) coloredtext = colored("Literal", Literal._colour) assert (coloredtext + "[value:'1', Scalar<INTEGER, SINGLE>]" in literal.node_str()) # array literal array_type = ArrayType(REAL_DOUBLE_TYPE, [10, 10]) literal = Literal("1", array_type) coloredtext = colored("Literal", Literal._colour) assert (coloredtext + "[value:'1', Array<Scalar<REAL, DOUBLE>, " "shape=[Literal[value:'10', Scalar<INTEGER, UNDEFINED>], " "Literal[value:'10', Scalar<INTEGER, UNDEFINED>]]>]" in literal.node_str())
def test_unaryoperation_node_str(): ''' Check the view method of the UnaryOperation class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP ref1 = Reference(DataSymbol("a", REAL_SINGLE_TYPE)) unary_operation = UnaryOperation.create(UnaryOperation.Operator.MINUS, ref1) coloredtext = colored("UnaryOperation", SCHEDULE_COLOUR_MAP["Operation"]) assert coloredtext + "[operator:'MINUS']" in unary_operation.node_str()
def test_file_container_node_str(): '''Test that a FileContainer instance outputs the expected text for the view method. ''' file_container = FileContainer("test") coloredtext = colored("FileContainer", FileContainer._colour) assert coloredtext + "[test]" in file_container.node_str()
def test_codeblock_node_str(): ''' Check the node_str method of the Code Block class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP cblock = CodeBlock([], "dummy") coloredtext = colored("CodeBlock", SCHEDULE_COLOUR_MAP["CodeBlock"]) output = cblock.node_str() assert coloredtext + "[" in output assert "]" in output
def test_kernelfunctor_node_str(): '''Check the node_str method of the KernelFunctor class.''' symbol = DataTypeSymbol("hello", StructureType()) arg = Reference(Symbol("dummy")) klr = KernelFunctor.create(symbol, [arg]) coloredtext = colored("KernelFunctor", KernelFunctor._colour) assert klr.node_str() == coloredtext + "[name='hello']"
def test_naryoperation_node_str(): ''' Check the node_str method of the Nary Operation class.''' nary_operation = NaryOperation(NaryOperation.Operator.MAX) nary_operation.addchild(Literal("1", INTEGER_SINGLE_TYPE)) nary_operation.addchild(Literal("1", INTEGER_SINGLE_TYPE)) nary_operation.addchild(Literal("1", INTEGER_SINGLE_TYPE)) coloredtext = colored("NaryOperation", NaryOperation._colour) assert coloredtext+"[operator:'MAX']" in nary_operation.node_str()
def test_array_node_str(): ''' Check the node_str method of the ArrayReference class.''' kschedule = KernelSchedule("kname") array_type = ArrayType(INTEGER_SINGLE_TYPE, [ArrayType.Extent.ATTRIBUTE]) symbol = DataSymbol("aname", array_type) kschedule.symbol_table.add(symbol) array = ArrayReference(symbol) coloredtext = colored("ArrayReference", ArrayReference._colour) assert coloredtext + "[name:'aname']" in array.node_str()
def test_reference_node_str(): ''' Check the node_str method of the Reference class.''' kschedule = KernelSchedule("kname") symbol = DataSymbol("rname", INTEGER_SINGLE_TYPE) kschedule.symbol_table.add(symbol) assignment = Assignment(parent=kschedule) ref = Reference(symbol, assignment) coloredtext = colored("Reference", Reference._colour) assert coloredtext + "[name:'rname']" in ref.node_str()
def test_binaryoperation_node_str(): ''' Check the node_str method of the Binary Operation class.''' binary_operation = BinaryOperation(BinaryOperation.Operator.ADD) op1 = Literal("1", INTEGER_SINGLE_TYPE) op2 = Literal("1", INTEGER_SINGLE_TYPE) binary_operation.addchild(op1) binary_operation.addchild(op2) coloredtext = colored("BinaryOperation", BinaryOperation._colour) assert coloredtext+"[operator:'ADD']" in binary_operation.node_str()
def test_binaryoperation_node_str(): ''' Check the node_str method of the Binary Operation class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP binary_operation = BinaryOperation(BinaryOperation.Operator.ADD) op1 = Literal("1", INTEGER_SINGLE_TYPE, parent=binary_operation) op2 = Literal("1", INTEGER_SINGLE_TYPE, parent=binary_operation) binary_operation.addchild(op1) binary_operation.addchild(op2) coloredtext = colored("BinaryOperation", SCHEDULE_COLOUR_MAP["Operation"]) assert coloredtext + "[operator:'ADD']" in binary_operation.node_str()
def test_reference_node_str(): ''' Check the node_str method of the Reference class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP kschedule = KernelSchedule("kname") symbol = DataSymbol("rname", INTEGER_SINGLE_TYPE) kschedule.symbol_table.add(symbol) assignment = Assignment(parent=kschedule) ref = Reference(symbol, assignment) coloredtext = colored("Reference", SCHEDULE_COLOUR_MAP["Reference"]) assert coloredtext + "[name:'rname']" in ref.node_str()
def test_ifblock_node_str(): ''' Check the node_str method of the IfBlock class.''' colouredif = colored("If", IfBlock._colour) ifblock = IfBlock() output = ifblock.node_str() assert colouredif+"[]" in output ifblock = IfBlock(annotations=['was_elseif']) output = ifblock.node_str() assert colouredif+"[annotations='was_elseif']" in output
def test_array_node_str(): ''' Check the node_str method of the Array class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP kschedule = KernelSchedule("kname") array_type = ArrayType(INTEGER_SINGLE_TYPE, [ArrayType.Extent.ATTRIBUTE]) symbol = DataSymbol("aname", array_type) kschedule.symbol_table.add(symbol) assignment = Assignment(parent=kschedule) array = Array(symbol, parent=assignment) coloredtext = colored("ArrayReference", SCHEDULE_COLOUR_MAP["Reference"]) assert coloredtext + "[name:'aname']" in array.node_str()
def test_sm_node_str(): ''' Check the node_str method of the StructureMember class.''' kschedule = nodes.KernelSchedule("kname") grid_var = create_structure_symbol(kschedule.symbol_table) assignment = nodes.Assignment(parent=kschedule) grid_ref = nodes.StructureReference.create(grid_var, ['area', 'nx'], parent=assignment) # The first child of the StructureReference is itself a reference to a # structure and is therefore a StructureMember assert isinstance(grid_ref.children[0], nodes.StructureMember) coloredtext = colored("StructureMember", nodes.StructureMember._colour) assert coloredtext + "[name:'area']" in grid_ref.children[0].node_str()
def test_range_view(capsys): ''' Check that calling view() on an array with a child Range works as expected. ''' # Create the PSyIR for 'my_array(1, 1:10)' erange = Range.create(Literal("1", INTEGER_SINGLE_TYPE), Literal("10", INTEGER_SINGLE_TYPE)) array_type = ArrayType(REAL_SINGLE_TYPE, [10, 10]) array = ArrayReference.create(DataSymbol("my_array", array_type), [Literal("1", INTEGER_SINGLE_TYPE), erange]) array.view() stdout, _ = capsys.readouterr() arrayref = colored("ArrayReference", ArrayReference._colour) literal = colored("Literal", Literal._colour) rangestr = colored("Range", Range._colour) indent = " " assert (arrayref + "[name:'my_array']\n" + indent + literal + "[value:'1', Scalar<INTEGER, SINGLE>]\n" + indent + rangestr + "[]\n" + 2 * indent + literal + "[value:'1', Scalar<INTEGER, SINGLE>]\n" + 2 * indent + literal + "[value:'10', Scalar<INTEGER, SINGLE>]\n" + 2 * indent + literal + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" in stdout)
def test_ifblock_node_str(): ''' Check the node_str method of the IfBlock class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP colouredif = colored("If", SCHEDULE_COLOUR_MAP["If"]) ifblock = IfBlock() output = ifblock.node_str() assert colouredif + "[]" in output ifblock = IfBlock(annotations=['was_elseif']) output = ifblock.node_str() assert colouredif + "[annotations='was_elseif']" in output
def node_str(self, colour=True): ''' Returns the name of this node with (optional) control codes to generate coloured output in a terminal that supports it. :param bool colour: whether or not to include colour control codes. :returns: description of this node, possibly coloured. :rtype: str ''' return ("{0}[type='{1}', field_space='{2}', it_space='{3}']".format( colored("Loop", self._colour), self._loop_type, self._field_space, self.iteration_space))
def test_naryoperation_node_str(): ''' Check the node_str method of the Nary Operation class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP nary_operation = NaryOperation(NaryOperation.Operator.MAX) nary_operation.addchild( Literal("1", INTEGER_SINGLE_TYPE, parent=nary_operation)) nary_operation.addchild( Literal("1", INTEGER_SINGLE_TYPE, parent=nary_operation)) nary_operation.addchild( Literal("1", INTEGER_SINGLE_TYPE, parent=nary_operation)) coloredtext = colored("NaryOperation", SCHEDULE_COLOUR_MAP["Operation"]) assert coloredtext + "[operator:'MAX']" in nary_operation.node_str()
def test_node_str(): ''' Tests for the Node.node_str method. ''' tnode = Node() # Node is an abstract class with pytest.raises(NotImplementedError) as err: tnode.node_str() assert ("_text_name is an abstract attribute which needs to be given a " "string value in the concrete class 'Node'." in str(err.value)) # Manually set the _text_name and _colour for this node to # something that will result in coloured output (if requested # *and* termcolor is installed). tnode._text_name = "FakeName" tnode._colour = "green" assert tnode.node_str(False) == "FakeName[]" assert tnode.node_str(True) == colored("FakeName", "green") + "[]"
def test_node_coloured_name(): ''' Tests for the coloured_name method of the Node class. ''' tnode = Node() # Node is an abstract class with pytest.raises(NotImplementedError) as err: tnode.node_str() assert ("_text_name is an abstract attribute which needs to be given a " "string value in the concrete class 'Node'." in str(err.value)) # Exception as _colour has not been set tnode._text_name = "ATest" with pytest.raises(NotImplementedError) as err: _ = tnode.coloured_name() assert ("The _colour attribute is abstract so needs to be given a string " "value in the concrete class 'Node'." in str(err.value)) # Valid values tnode._colour = "white" assert tnode.coloured_name(False) == "ATest" assert tnode.coloured_name(True) == colored("ATest", "white")
def test_node_str(): ''' Tests for the Node.node_str method. ''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP tnode = Node() # Node is an abstract class with pytest.raises(NotImplementedError) as err: tnode.node_str() assert ("_text_name is an abstract attribute which needs to be given a " "string value in the concrete class 'Node'." in str(err.value)) # Manually set the _text_name and _colour_key for this node to something # that will result in coloured output (if requested *and* termcolor is # installed). tnode._text_name = "FakeName" tnode._colour_key = "Loop" assert tnode.node_str(False) == "FakeName[]" assert tnode.node_str(True) == colored("FakeName", SCHEDULE_COLOUR_MAP["Loop"]) + "[]"
def test_node_coloured_name(): ''' Tests for the coloured_name method of the Node class. ''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP tnode = Node() # Node is an abstract class with pytest.raises(NotImplementedError) as err: tnode.node_str() assert ("_text_name is an abstract attribute which needs to be given a " "string value in the concrete class 'Node'." in str(err.value)) # Check that we can change the name of the Node and the colour associated # with it tnode._text_name = "ATest" tnode._colour_key = "Schedule" assert tnode.coloured_name(False) == "ATest" assert tnode.coloured_name(True) == colored( "ATest", SCHEDULE_COLOUR_MAP["Schedule"]) # Check that an unrecognised colour-map entry gives us un-coloured text tnode._colour_key = "not-recognised" assert tnode.coloured_name(True) == "ATest"
def test_schedule_view(capsys): ''' Check the schedule view/str methods work as expected ''' _, invoke_info = get_invoke("io_in_loop.f90", api=API, idx=0) sched = invoke_info.schedule sched_str = str(sched) assert "NemoLoop[id:'', variable:'ji', loop_type:'lon']" in sched_str assert "NemoLoop[id:'', variable:'jj', loop_type:'lat']" in sched_str assert "NemoLoop[id:'', variable:'jk', loop_type:'levels']" in sched_str sched.view() output, _ = capsys.readouterr() # Have to allow for colouring of output text loop_str = colored("Loop", Loop._colour) kern_str = colored("InlinedKern", InlinedKern._colour) isched_str = colored("NemoInvokeSchedule", nemo.NemoInvokeSchedule._colour) sched_str = colored("Schedule", Schedule._colour) lit_str = colored("Literal", Literal._colour) ref_str = colored("Reference", Reference._colour) indent = " " expected_sched = ( isched_str + "[invoke='io_in_loop']\n" + indent + "0: " + loop_str + "[type='levels', field_space='None', " "it_space='None']\n" + 2*indent + lit_str + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" + 2*indent + ref_str + "[name:'jpk']\n" + 2*indent + lit_str + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" + 2*indent + sched_str + "[]\n" + 3*indent + "0: " + loop_str + "[type='lat', field_space='None', " "it_space='None']\n" + 4*indent + lit_str + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" + 4*indent + ref_str + "[name:'jpj']\n" + 4*indent + lit_str + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" + 4*indent + sched_str + "[]\n" + 5*indent + "0: " + loop_str + "[type='lon', " "field_space='None', it_space='None']\n" + 6*indent + lit_str + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" + 6*indent + ref_str + "[name:'jpi']\n" + 6*indent + lit_str + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" + 6*indent + sched_str + "[]\n" + 7*indent + "0: " + kern_str + "[]\n") assert expected_sched in output
def test_container_node_str(): '''Check the node_str method of the Container class.''' from psyclone.psyir.nodes.node import colored, SCHEDULE_COLOUR_MAP cont_stmt = Container("bin") coloredtext = colored("Container", SCHEDULE_COLOUR_MAP["Container"]) assert coloredtext + "[bin]" in cont_stmt.node_str()
def test_goschedule_view(capsys, dist_mem): ''' Test that the GOInvokeSchedule::view() method works as expected ''' _, invoke_info = parse(os.path.join(BASE_PATH, "single_invoke_two_kernels.f90"), api=API) psy = PSyFactory(API, distributed_memory=dist_mem).create(invoke_info) invoke = psy.invokes.invoke_list[0] # Ensure we check for the correct (colour) control codes in the output isched = colored("GOInvokeSchedule", GOInvokeSchedule._colour) loop = colored("Loop", Loop._colour) call = colored("CodedKern", CodedKern._colour) sched = colored("Schedule", Schedule._colour) lit = colored("Literal", Literal._colour) sref = colored("StructureReference", StructureReference._colour) smem = colored("StructureMember", StructureMember._colour) mem = colored("Member", Member._colour) bop = colored("BinaryOperation", BinaryOperation._colour) haloex = colored("HaloExchange", HaloExchange._colour) if dist_mem: # View without constant loop bounds and with distributed memory # where the p field has a stencil access. invoke.schedule.view() # The view method writes to stdout and this is captured by py.test # by default. We have to query this captured output. out, _ = capsys.readouterr() expected_output = ( isched + "[invoke='invoke_0', Constant loop bounds=False]\n" " 0: " + haloex + "[field='p_fld', type='None', depth=None, " "check_dirty=False]\n" " 1: " + loop + "[type='outer', field_space='go_cu', " "it_space='go_internal_pts']\n" " " + sref + "[name:'cu_fld']\n" " " + smem + "[name:'internal']\n" " " + mem + "[name:'ystart']\n" " " + sref + "[name:'cu_fld']\n" " " + smem + "[name:'internal']\n" " " + mem + "[name:'ystop']\n" " " + lit + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + loop + "[type='inner', field_space='go_cu', " "it_space='go_internal_pts']\n" " " + sref + "[name:'cu_fld']\n" " " + smem + "[name:'internal']\n" " " + mem + "[name:'xstart']\n" " " + sref + "[name:'cu_fld']\n" " " + smem + "[name:'internal']\n" " " + mem + "[name:'xstop']\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + call + " compute_cu_code(cu_fld,p_fld,u_fld) " "[module_inline=False]\n" " 2: " + loop + "[type='outer', field_space='go_every', " "it_space='go_internal_pts']\n" " " + lit + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" " " + bop + "[operator:'SIZE']\n" " " + sref + "[name:'uold_fld']\n" " " + mem + "[name:'data']\n" " " + lit + "[value:'2', Scalar<INTEGER, UNDEFINED>]\n" " " + lit + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + loop + "[type='inner', field_space='go_every'," " it_space='go_internal_pts']\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + bop + "[operator:'SIZE']\n" " " + sref + "[name:'uold_fld']\n" " " + mem + "[name:'data']\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + call + " time_smooth_code(u_fld,unew_fld," "uold_fld) [module_inline=False]\n") else: # View with constant loop bounds and without distributed memory invoke.schedule._const_loop_bounds = True invoke.schedule.view() # The view method writes to stdout and this is captured by py.test # by default. We have to query this captured output. out, _ = capsys.readouterr() expected_output = ( isched + "[invoke='invoke_0', Constant loop bounds=True]\n" " 0: " + loop + "[type='outer', field_space='go_cu', " "it_space='go_internal_pts']\n" " " + lit + "[value:'2', Scalar<INTEGER, UNDEFINED>]\n" " " + lit + "[value:'jstop', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + loop + "[type='inner', field_space='go_cu', " "it_space='go_internal_pts']\n" " " + lit + "[value:'2', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'istop+1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + call + " compute_cu_code(cu_fld,p_fld,u_fld) " "[module_inline=False]\n" " 1: " + loop + "[type='outer', field_space='go_every', " "it_space='go_internal_pts']\n" " " + lit + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" " " + lit + "[value:'jstop+1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'1', Scalar<INTEGER, UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + loop + "[type='inner', field_space='go_every', " "it_space='go_internal_pts']\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'istop+1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + lit + "[value:'1', Scalar<INTEGER, " "UNDEFINED>]\n" " " + sched + "[]\n" " 0: " + call + " time_smooth_code(u_fld,unew_fld," "uold_fld) [module_inline=False]\n") assert expected_output == out
def test_container_node_str(): '''Check the node_str method of the Container class.''' cont_stmt = Container("bin") coloredtext = colored("Container", Container._colour) assert coloredtext + "[bin]" in cont_stmt.node_str()