def test_create_datatypesymbol_wrong_datatype(): ''' Check that attempting to specify the type of a DataTypeSymbol with an invalid type results in the expected error. ''' sym = DataTypeSymbol("my_type", DeferredType()) with pytest.raises(TypeError) as err: sym.datatype = "integer" assert ("datatype of a DataTypeSymbol must be specified using a " "DataType but got: 'str'" in str(err.value))
def test_datatypesymbol_copy(): ''' Check that a DataTypeSymbol can be copied. ''' symbol = DataTypeSymbol("my_type", DeferredType(), visibility=Symbol.Visibility.PRIVATE, interface=UnresolvedInterface()) new_symbol = symbol.copy() assert new_symbol is not symbol assert new_symbol.name == "my_type" assert isinstance(new_symbol.datatype, DeferredType) assert new_symbol.visibility == Symbol.Visibility.PRIVATE assert isinstance(new_symbol.interface, UnresolvedInterface)
def test_kernelfunctor_str(): '''Check the str method of the KernelFunctor class.''' symbol = DataTypeSymbol("hello", StructureType()) arg = Reference(Symbol("dummy")) klr = KernelFunctor.create(symbol, [arg]) assert klr.__str__() == "KernelFunctor[name='hello']"
def test_create_datatypesymbol(): ''' Check that a basic DataTypeSymbol can be created with the expected properties. ''' sym = DataTypeSymbol("my_type", DeferredType()) assert sym.name == "my_type" assert isinstance(sym.datatype, DeferredType) assert str(sym) == "my_type : DataTypeSymbol"
def test_create_structuretype(): ''' Test the create() method of StructureType. ''' # One member will have its type defined by a DataTypeSymbol tsymbol = DataTypeSymbol("my_type", DeferredType()) stype = StructureType.create([ ("fred", INTEGER_TYPE, Symbol.Visibility.PUBLIC), ("george", REAL_TYPE, Symbol.Visibility.PRIVATE), ("barry", tsymbol, Symbol.Visibility.PUBLIC)]) assert len(stype.components) == 3 george = stype.lookup("george") assert isinstance(george, StructureType.ComponentType) assert george.name == "george" assert george.datatype == REAL_TYPE assert george.visibility == Symbol.Visibility.PRIVATE barry = stype.lookup("barry") assert isinstance(barry, StructureType.ComponentType) assert barry.datatype is tsymbol assert barry.visibility == Symbol.Visibility.PUBLIC with pytest.raises(TypeError) as err: StructureType.create([ ("fred", INTEGER_TYPE, Symbol.Visibility.PUBLIC), ("george", Symbol.Visibility.PRIVATE)]) assert ("Each component must be specified using a 3-tuple of (name, " "type, visibility) but found a tuple with 2 members: (" "'george', " in str(err.value))
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_lfrickernelfunctor(): '''test that an instance of LFRicKernelFunctor class can be created. ''' routine = DataTypeSymbol("hello", StructureType()) lbc = LFRicKernelFunctor(routine) assert isinstance(lbc, LFRicKernelFunctor) assert lbc._text_name == "LFRicKernelFunctor"
def test_is_not_array_range(): ''' Test that is_array_range correctly rejects things that aren't an assignment to an array range. ''' int_one = Literal("1", INTEGER_SINGLE_TYPE) one = Literal("1.0", REAL_TYPE) var = DataSymbol("x", REAL_TYPE) reference = Reference(var) # lhs is not an array assignment = Assignment.create(reference, one) assert assignment.is_array_range is False # lhs is an array reference but has no range array_type = ArrayType(REAL_TYPE, [10, 10]) symbol = DataSymbol("y", array_type) array_ref = Reference(symbol) assignment = Assignment.create(array_ref, one.copy()) assert assignment.is_array_range is False # lhs is an array reference but the single index value is obtained # using an array range, y(1, SUM(map(:), 1)) = 1.0 int_array_type = ArrayType(INTEGER_SINGLE_TYPE, [10]) map_sym = DataSymbol("map", int_array_type) start = BinaryOperation.create(BinaryOperation.Operator.LBOUND, Reference(map_sym), int_one.copy()) stop = BinaryOperation.create(BinaryOperation.Operator.UBOUND, Reference(map_sym), int_one.copy()) my_range = Range.create(start, stop) sum_op = BinaryOperation.create(BinaryOperation.Operator.SUM, ArrayReference.create(map_sym, [my_range]), int_one.copy()) assignment = Assignment.create( ArrayReference.create(symbol, [int_one.copy(), sum_op]), one.copy()) assert assignment.is_array_range is False # When the slice has two operator ancestors, one of which is a reduction # e.g y(1, SUM(ABS(map(:)), 1)) = 1.0 abs_op = UnaryOperation.create( UnaryOperation.Operator.ABS, ArrayReference.create(map_sym, [my_range.copy()])) sum_op2 = BinaryOperation.create(BinaryOperation.Operator.SUM, abs_op, int_one.copy()) assignment = Assignment.create( ArrayReference.create(symbol, [int_one.copy(), sum_op2]), one.copy()) assert assignment.is_array_range is False # lhs is a scalar member of a structure grid_type = StructureType.create([ ("dx", REAL_SINGLE_TYPE, Symbol.Visibility.PUBLIC), ("dy", REAL_SINGLE_TYPE, Symbol.Visibility.PUBLIC) ]) grid_type_symbol = DataTypeSymbol("grid_type", grid_type) grid_sym = DataSymbol("grid", grid_type_symbol) assignment = Assignment.create(StructureReference.create(grid_sym, ["dx"]), one.copy()) assert assignment.is_array_range is False
def test_kernelfunctor_parent(): '''Check that the optional parent argument to a KernelFunctor class constructor is stored correctly. ''' parent = Node() symbol = DataTypeSymbol("hello", StructureType()) klr = KernelFunctor(symbol, parent=parent) assert klr.parent == parent
def test_arraytype_datatypesymbol(): ''' Test that we can correctly create an ArrayType when the type of the elements is specified as a DataTypeSymbol. ''' tsym = DataTypeSymbol("my_type", DeferredType()) atype = ArrayType(tsym, [5]) assert isinstance(atype, ArrayType) assert len(atype.shape) == 1 assert atype.intrinsic is tsym assert atype.precision is None
def test_kernelfunctor_create_invalid_args1(): '''Check that the create method of KernelFunctor raises the expected exception if the provided 'arguments' argument is not a list. ''' symbol = DataTypeSymbol("hello", StructureType()) with pytest.raises(GenerationError) as info: _ = KernelFunctor.create(symbol, "Not a list") assert ("KernelFunctor create() arguments argument should be a list " "but found 'str'." in str(info.value))
def test_kernelfunctor_invalid_args2(): '''Check that the create method of KernelFunctor raises the expected exception if its supplied list of children are not the expected type (tests _validate_child method and _children_valid_format variable) ''' symbol = DataTypeSymbol("hello", StructureType()) with pytest.raises(GenerationError) as info: _ = KernelFunctor.create(symbol, ["hello"]) assert ("Item 'str' can't be child 0 of 'KernelFunctor'. The valid " "format is: '[DataNode]*'." in str(info.value))
def test_kernelfunctor(): '''Check that an instance of KernelFunctor class can be created. Also check that the symbol method works as expected. ''' symbol = DataTypeSymbol("hello", StructureType()) klr = KernelFunctor(symbol) assert klr._symbol == symbol assert klr.symbol == symbol assert klr._colour == "yellow" assert klr._text_name == "KernelFunctor" assert klr.parent is None
def test_datasymbol_initialisation(): '''Test that a DataSymbol instance can be created when valid arguments are given, otherwise raise relevant exceptions.''' # Test with valid arguments assert isinstance(DataSymbol('a', REAL_SINGLE_TYPE), DataSymbol) assert isinstance(DataSymbol('a', REAL_DOUBLE_TYPE), DataSymbol) assert isinstance(DataSymbol('a', REAL4_TYPE), DataSymbol) kind = DataSymbol('r_def', INTEGER_SINGLE_TYPE) real_kind_type = ScalarType(ScalarType.Intrinsic.REAL, kind) assert isinstance(DataSymbol('a', real_kind_type), DataSymbol) # real constants are not currently supported assert isinstance(DataSymbol('a', INTEGER_SINGLE_TYPE), DataSymbol) assert isinstance(DataSymbol('a', INTEGER_DOUBLE_TYPE, constant_value=0), DataSymbol) assert isinstance(DataSymbol('a', INTEGER4_TYPE), DataSymbol) assert isinstance(DataSymbol('a', CHARACTER_TYPE), DataSymbol) assert isinstance(DataSymbol('a', CHARACTER_TYPE, constant_value="hello"), DataSymbol) assert isinstance(DataSymbol('a', BOOLEAN_TYPE), DataSymbol) assert isinstance(DataSymbol('a', BOOLEAN_TYPE, constant_value=False), DataSymbol) array_type = ArrayType(REAL_SINGLE_TYPE, [ArrayType.Extent.ATTRIBUTE]) assert isinstance(DataSymbol('a', array_type), DataSymbol) array_type = ArrayType(REAL_SINGLE_TYPE, [3]) assert isinstance(DataSymbol('a', array_type), DataSymbol) array_type = ArrayType(REAL_SINGLE_TYPE, [3, ArrayType.Extent.ATTRIBUTE]) assert isinstance(DataSymbol('a', array_type), DataSymbol) assert isinstance(DataSymbol('a', REAL_SINGLE_TYPE), DataSymbol) assert isinstance(DataSymbol('a', REAL8_TYPE), DataSymbol) dim = DataSymbol('dim', INTEGER_SINGLE_TYPE, interface=UnresolvedInterface()) array_type = ArrayType(REAL_SINGLE_TYPE, [Reference(dim)]) assert isinstance(DataSymbol('a', array_type), DataSymbol) array_type = ArrayType(REAL_SINGLE_TYPE, [3, Reference(dim), ArrayType.Extent.ATTRIBUTE]) assert isinstance(DataSymbol('a', array_type), DataSymbol) assert isinstance( DataSymbol('a', REAL_SINGLE_TYPE, interface=ArgumentInterface( ArgumentInterface.Access.READWRITE)), DataSymbol) assert isinstance( DataSymbol('a', REAL_SINGLE_TYPE, visibility=Symbol.Visibility.PRIVATE), DataSymbol) assert isinstance(DataSymbol('field', DataTypeSymbol("field_type", DeferredType())), DataSymbol)
def test_lfricalgorithminvokecall_create(cls): '''Check that the LFRicAlgorithmInvokeCall create method creates the expected object. ''' routine = RoutineSymbol("hello") klc = LFRicKernelFunctor.create(DataTypeSymbol("arg", StructureType()), []) call = cls.create(routine, [klc], 0, description="describing an invoke") assert call._description == "describing an invoke" assert call.routine is routine # pylint: disable=unidiomatic-typecheck assert type(call) is cls assert len(call.children) == 1 assert call.children[0] == klc
def test_aic_validate_child(): '''Check that the _validate_child method behaves as expected.''' kernel_functor = KernelFunctor(DataTypeSymbol("dummy", REAL_TYPE)) assert AlgorithmInvokeCall._validate_child(0, kernel_functor) assert not AlgorithmInvokeCall._validate_child(0, "Invalid") routine = RoutineSymbol("hello") call = AlgorithmInvokeCall(routine, 0) with pytest.raises(GenerationError) as info: call.children = ["invalid"] assert ("Item 'str' can't be child 0 of 'AlgorithmInvokeCall'. The valid " "format is: '[KernelFunctor]*'." in str(info.value)) call.children = [kernel_functor]
def test_aic_defroutinerootname(): '''Check that the _def_routine_root_name() internal method behaves as expected. ''' symbol_name = "dummy" kernel_functor = KernelFunctor(DataTypeSymbol(symbol_name, REAL_TYPE)) routine = RoutineSymbol("hello") index = 3 call = AlgorithmInvokeCall(routine, index) call.children = [kernel_functor] assert call._def_routine_root_name() == "invoke_{0}_{1}".format( index, symbol_name) call.children.append(kernel_functor.copy()) assert call._def_routine_root_name() == "invoke_{0}".format(index)
def test_kernelfunctor_create(cls): '''Check that the create method of KernelFunctor works as expected. ''' symbol = DataTypeSymbol("hello", StructureType()) klr = cls.create(symbol, []) # pylint: disable=unidiomatic-typecheck assert type(klr) is cls assert klr._symbol == symbol assert len(klr.children) == 0 arg = Reference(Symbol("dummy")) klr = KernelFunctor.create(symbol, [arg]) assert len(klr.children) == 1 assert klr.children[0] == arg assert arg.parent == klr
def test_aic_create(): '''Check that the create method behaves as expected.''' kernel_functor = KernelFunctor(DataTypeSymbol("dummy", REAL_TYPE)) routine = RoutineSymbol("hello") index = 10 aic = AlgorithmInvokeCall.create(routine, [kernel_functor], index) assert isinstance(aic, AlgorithmInvokeCall) assert len(aic.children) == 1 assert aic.children[0] is kernel_functor assert aic._routine is routine assert aic._index == index with pytest.raises(GenerationError) as info: AlgorithmInvokeCall.create(routine, kernel_functor, index) assert ("AlgorithmInvokeCall create arguments argument should be a list " "but found 'KernelFunctor'." in str(info.value))
# Symbol table for container (container itself created after kernel) CONTAINER_SYMBOL_TABLE = SymbolTable() REAL_KIND = CONTAINER_SYMBOL_TABLE.new_symbol(root_name="RKIND", symbol_type=DataSymbol, datatype=INTEGER_TYPE, constant_value=8) # Shorthand for a scalar type with REAL_KIND precision SCALAR_TYPE = ScalarType(ScalarType.Intrinsic.REAL, REAL_KIND) # Derived-type definition in container GRID_TYPE = StructureType.create([ ("dx", SCALAR_TYPE, Symbol.Visibility.PUBLIC), ("dy", SCALAR_TYPE, Symbol.Visibility.PUBLIC) ]) GRID_TYPE_SYMBOL = DataTypeSymbol("grid_type", GRID_TYPE) CONTAINER_SYMBOL_TABLE.add(GRID_TYPE_SYMBOL) # Kernel symbol table, symbols and scalar datatypes SYMBOL_TABLE = SymbolTable() CONT = ContainerSymbol("kernel_mod") SYMBOL_TABLE.add(CONT) DTYPE_SYMBOL = DataTypeSymbol("other_type", DeferredType(), interface=GlobalInterface(CONT)) SYMBOL_TABLE.add(DTYPE_SYMBOL) # Create the definition of the 'field_type' FIELD_TYPE_DEF = StructureType.create([
def test_is_array_range(): '''test that the is_array_range method behaves as expected, returning true if the LHS of the assignment is an array range access. ''' one = Literal("1.0", REAL_TYPE) int_one = Literal("1", INTEGER_TYPE) int_ten = Literal("10", INTEGER_TYPE) # lhs is an array reference with a range array_type = ArrayType(REAL_TYPE, [10, 10]) symbol = DataSymbol("x", array_type) x_range = Range.create(int_one, int_ten.copy(), int_one.copy()) array_ref = ArrayReference.create(symbol, [x_range, int_one.copy()]) assignment = Assignment.create(array_ref, one.copy()) assert assignment.is_array_range is True # Check when lhs consists of various forms of structure access grid_type = StructureType.create([ ("dx", REAL_SINGLE_TYPE, Symbol.Visibility.PUBLIC), ("dy", REAL_SINGLE_TYPE, Symbol.Visibility.PUBLIC) ]) grid_type_symbol = DataTypeSymbol("grid_type", grid_type) # Create the definition of the 'field_type', contains array of grid_types field_type_def = StructureType.create([ ("data", ArrayType(REAL_SINGLE_TYPE, [10]), Symbol.Visibility.PUBLIC), ("sub_meshes", ArrayType(grid_type_symbol, [3]), Symbol.Visibility.PUBLIC) ]) field_type_symbol = DataTypeSymbol("field_type", field_type_def) field_symbol = DataSymbol("wind", field_type_symbol) # Array reference to component of derived type using a range lbound = BinaryOperation.create( BinaryOperation.Operator.LBOUND, StructureReference.create(field_symbol, ["data"]), int_one.copy()) ubound = BinaryOperation.create( BinaryOperation.Operator.UBOUND, StructureReference.create(field_symbol, ["data"]), int_one.copy()) my_range = Range.create(lbound, ubound) data_ref = StructureReference.create(field_symbol, [("data", [my_range])]) assign = Assignment.create(data_ref, one.copy()) assert assign.is_array_range is True # Access to slice of 'sub_meshes': wind%sub_meshes(1:3)%dx = 1.0 sub_range = Range.create(int_one.copy(), Literal("3", INTEGER_TYPE)) dx_ref = StructureReference.create(field_symbol, [("sub_meshes", [sub_range]), "dx"]) sub_assign = Assignment.create(dx_ref, one.copy()) assert sub_assign.is_array_range is True # Create an array of these derived types and assign to a slice: # chi(1:10)%data(1) = 1.0 field_bundle_symbol = DataSymbol("chi", ArrayType(field_type_symbol, [3])) fld_range = Range.create(int_one.copy(), Literal("10", INTEGER_TYPE)) fld_ref = ArrayOfStructuresReference.create(field_bundle_symbol, [fld_range], [("data", [int_one.copy()])]) fld_assign = Assignment.create(fld_ref, one.copy()) assert fld_assign.is_array_range is True # When the slice has two operator ancestors, none of which are a reduction # e.g y(1, INT(ABS(map(:, 1)))) = 1.0 int_array_type = ArrayType(INTEGER_SINGLE_TYPE, [10, 10]) map_sym = DataSymbol("map", int_array_type) lbound1 = BinaryOperation.create(BinaryOperation.Operator.LBOUND, Reference(map_sym), int_one.copy()) ubound1 = BinaryOperation.create(BinaryOperation.Operator.UBOUND, Reference(map_sym), int_one.copy()) my_range1 = Range.create(lbound1, ubound1) abs_op = UnaryOperation.create( UnaryOperation.Operator.ABS, ArrayReference.create(map_sym, [my_range1, int_one.copy()])) int_op = UnaryOperation.create(UnaryOperation.Operator.INT, abs_op) assignment = Assignment.create( ArrayReference.create(symbol, [int_one.copy(), int_op]), one.copy()) assert assignment.is_array_range is True