def test_cw_array(): '''Check the CWriter class array method correctly prints out the C representation of an array. ''' cwriter = CWriter() symbol = DataSymbol('a', REAL_TYPE) arr = Array(symbol) lit = Literal('0.0', REAL_TYPE) assignment = Assignment.create(arr, lit) # An array without any children (dimensions) should produce an error. with pytest.raises(VisitorError) as excinfo: result = cwriter(assignment) assert "Arrays must have at least 1 dimension but found node: '" \ in str(excinfo.value) # Dimensions can be references, literals or operations arr.addchild(Reference(DataSymbol('b', INTEGER_TYPE), parent=arr)) arr.addchild(Literal('1', INTEGER_TYPE, parent=arr)) uop = UnaryOperation.create(UnaryOperation.Operator.MINUS, Literal('2', INTEGER_TYPE)) uop.parent = arr arr.addchild(uop) result = cwriter(assignment) # Results is reversed and flatten (row-major 1D) # dimensions are called <name>LEN<dimension> by convention assert result == "a[(-2) * aLEN2 * aLEN1 + 1 * aLEN1 + b] = 0.0;\n"
def test_array_can_be_printed(): '''Test that an Array instance can always be printed (i.e. is initialised fully)''' kschedule = KernelSchedule("kname") symbol = DataSymbol("aname", INTEGER_SINGLE_TYPE) kschedule.symbol_table.add(symbol) assignment = Assignment(parent=kschedule) array = Array(symbol, assignment) assert "ArrayReference[name:'aname']\n" in str(array)
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_call_create(): '''Test that the create method creates a valid call with arguments''' routine = RoutineSymbol("ellie") array_type = ArrayType(INTEGER_TYPE, shape=[10, 20]) arguments = [ Reference(DataSymbol("arg1", INTEGER_TYPE)), Array(DataSymbol("arg2", array_type)) ] call = Call.create(routine, arguments) assert call.routine is routine for idx, child, in enumerate(call.children): assert child is arguments[idx] assert child.parent is call
def test_cw_size(): ''' Check the CWriter class SIZE method raises the expected error since there is no C equivalent. ''' cwriter = CWriter() arr = Array(DataSymbol('a', INTEGER_TYPE)) lit = Literal('1', INTEGER_TYPE) size = BinaryOperation.create(BinaryOperation.Operator.SIZE, arr, lit) lhs = Reference(DataSymbol('length', INTEGER_TYPE)) assignment = Assignment.create(lhs, size) with pytest.raises(VisitorError) as excinfo: cwriter(assignment) assert ("C backend does not support the 'Operator.SIZE' operator" in str(excinfo.value))
def test_bound_intrinsic_wrong_type(bound): ''' Check that attempting to create an L/UBOUND intrinsic operator with the wrong type of arguments raises the expected error. ''' with pytest.raises(TypeError) as err: # First argument must be an Array _ = BinaryOperation.create(bound, Literal("1", INTEGER_TYPE), Literal("1", INTEGER_TYPE)) assert "must be an Array but got: 'Literal" in str(err.value) with pytest.raises(TypeError) as err: # Second argument cannot be a real literal _ = BinaryOperation.create(bound, Array("array"), Literal("1.0", REAL_TYPE)) assert ("must be an integer but got a Literal of type REAL" in str(err.value))
def test_array_children_validation(): '''Test that children added to Array are validated. Array accepts DataNodes and Range children.''' array_type = ArrayType(REAL_SINGLE_TYPE, shape=[5, 5]) array = Array(DataSymbol("rname", array_type)) datanode1 = Literal("1", INTEGER_SINGLE_TYPE) erange = Range() assignment = Assignment() # Invalid child with pytest.raises(GenerationError) as excinfo: array.addchild(assignment) assert ("Item 'Assignment' can't be child 0 of 'ArrayReference'. The valid" " format is: '[DataNode | Range]*'." in str(excinfo.value)) # Valid children array.addchild(datanode1) array.addchild(erange)
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", INTEGER_TYPE, parent=self) if self._loop_type == "colours": self.stop_expr = Reference(DataSymbol("ncolour", INTEGER_TYPE), parent=self) elif self._loop_type == "colour": self.stop_expr = Array(DataSymbol("ncp_ncolour", INTEGER_TYPE), parent=self) self.stop_expr.addchild(Reference( DataSymbol("colour", INTEGER_TYPE)), parent=self.stop_expr) else: # This is a hack as the name is not a valid DataSymbol, it # is a call to a type-bound function. self.stop_expr = Reference(DataSymbol( self.field_name + "%get_ncell()", INTEGER_TYPE), parent=self) Loop.gen_code(self, parent)
def test_where_array_notation_rank(): ''' Test that the _array_notation_rank() utility raises the expected errors when passed an unsupported Array object. ''' array_type = ArrayType(REAL_TYPE, [10]) symbol = DataSymbol("my_array", array_type) my_array = Array(symbol) processor = Fparser2Reader() with pytest.raises(NotImplementedError) as err: processor._array_notation_rank(my_array) assert ("Array reference in the PSyIR must have at least one child but " "'my_array'" in str(err.value)) from psyclone.psyir.nodes import Range array_type = ArrayType(REAL_TYPE, [10]) my_array = Array.create(DataSymbol("my_array", array_type), [Range.create(Literal("1", INTEGER_TYPE), Literal("10", INTEGER_TYPE))]) with pytest.raises(NotImplementedError) as err: processor._array_notation_rank(my_array) assert ("Only array notation of the form my_array(:, :, ...) is " "supported." in str(err.value))