Пример #1
0
def test_create_typesymbol_wrong_datatype():
    ''' Check that attempting to specify the type of a TypeSymbol with an
    invalid type results in the expected error. '''
    sym = TypeSymbol("my_type", DeferredType())
    with pytest.raises(TypeError) as err:
        sym.datatype = "integer"
    assert ("datatype of a TypeSymbol must be specified using a "
            "DataType but got: 'str'" in str(err.value))
Пример #2
0
def test_kernelfunctor_str():
    '''Check the str method of the KernelFunctor class.'''

    symbol = TypeSymbol("hello", StructureType())
    arg = Reference(Symbol("dummy"))
    klr = KernelFunctor.create(symbol, [arg])
    assert klr.__str__() == "KernelFunctor[name='hello']"
Пример #3
0
def test_create_structuretype():
    ''' Test the create() method of StructureType. '''
    # One member will have its type defined by a TypeSymbol
    tsymbol = TypeSymbol("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))
Пример #4
0
def test_create_typesymbol():
    ''' Check that a basic TypeSymbol can be created with the expected
    properties. '''
    sym = TypeSymbol("my_type", DeferredType())
    assert sym.name == "my_type"
    assert isinstance(sym.datatype, DeferredType)
    assert str(sym) == "my_type : TypeSymbol"
Пример #5
0
def test_kernelfunctor_node_str():
    '''Check the node_str method of the KernelFunctor class.'''

    symbol = TypeSymbol("hello", StructureType())
    arg = Reference(Symbol("dummy"))
    klr = KernelFunctor.create(symbol, [arg])
    coloredtext = colored("KernelFunctor", KernelFunctor._colour)
    assert klr.node_str() == coloredtext + "[name='hello']"
Пример #6
0
def test_lfrickernelfunctor():
    '''test that an instance of LFRicKernelFunctor class can be created.

    '''
    routine = TypeSymbol("hello", StructureType())
    lbc = LFRicKernelFunctor(routine)
    assert isinstance(lbc, LFRicKernelFunctor)
    assert lbc._text_name == "LFRicKernelFunctor"
Пример #7
0
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 = TypeSymbol("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
Пример #8
0
def test_kernelfunctor_parent():
    '''Check that the optional parent argument to a KernelFunctor class
    constructor is stored correctly.

    '''
    parent = Node()
    symbol = TypeSymbol("hello", StructureType())
    klr = KernelFunctor(symbol, parent=parent)
    assert klr.parent == parent
Пример #9
0
def test_arraytype_typesymbol():
    ''' Test that we can correctly create an ArrayType when the type of the
    elements is specified as a TypeSymbol. '''
    tsym = TypeSymbol("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
Пример #10
0
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 = TypeSymbol("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))
Пример #11
0
def test_kernelfunctor():
    '''Check that an instance of KernelFunctor class can be created. Also
    check that the symbol method works as expected.

    '''
    symbol = TypeSymbol("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
Пример #12
0
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 = TypeSymbol("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))
Пример #13
0
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', TypeSymbol("field_type", DeferredType())),
        DataSymbol)
Пример #14
0
def test_aic_validate_child():
    '''Check that the _validate_child method behaves as expected.'''

    kernel_functor = KernelFunctor(TypeSymbol("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]
Пример #15
0
def test_lfricalgorithminvokecall_create(cls):
    '''Check that the LFRicAlgorithmInvokeCall create method creates the
    expected object.

    '''
    routine = RoutineSymbol("hello")
    klc = LFRicKernelFunctor.create(TypeSymbol("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
Пример #16
0
def test_aic_defroutinerootname():
    '''Check that the _def_routine_root_name() internal method behaves as
    expected.

    '''
    symbol_name = "dummy"
    kernel_functor = KernelFunctor(TypeSymbol(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)
Пример #17
0
def test_kernelfunctor_create(cls):
    '''Check that the create method of KernelFunctor works as expected.

    '''
    symbol = TypeSymbol("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
Пример #18
0
def test_aic_create():
    '''Check that the create method behaves as expected.'''

    kernel_functor = KernelFunctor(TypeSymbol("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))
Пример #19
0
    def _get_symbol(call, fp2_node):
        '''Return the name of a Structure Constructor stored as a CodeBlock
        containing an fparser2 ast.

        :param code_block: the CodeBlock containing a StructureConstructor.
        :type code_block: :py:class:`psyclone.psyir.nodes.CodeBlock`
        :param fp2_node: the fparser2 Structure Constructor node.
        :type fp2_node: \
            :py:class:`fparser.two.Fortran2003.Structure_Constructor`

        :returns: the symbol capturing the name and type of the \
            StructureConstructor.
        :rtype: :py:class:`psyclone.psyir.symbols.Symbol`

        '''
        name = fp2_node.children[0].string
        symbol_table = call.scope.symbol_table
        try:
            type_symbol = symbol_table.lookup(name)
        except KeyError:
            type_symbol = TypeSymbol(name, StructureType())
            symbol_table.add(type_symbol)
        return type_symbol
Пример #20
0

# 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 = TypeSymbol("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 = TypeSymbol("other_type", DeferredType(),
                          interface=GlobalInterface(CONT))
SYMBOL_TABLE.add(DTYPE_SYMBOL)

# Create the definition of the 'field_type'
FIELD_TYPE_DEF = StructureType.create(
    [("data", ArrayType(SCALAR_TYPE, [10]), Symbol.Visibility.PUBLIC),
Пример #21
0
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 = TypeSymbol("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 = TypeSymbol("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