def create_structure_symbol(table):
    '''
    Utility to create a symbol of derived type and add it to the supplied
    symbol table.

    :param table: the symbol table to which to add the new symbol.
    :type table: :py:class:`psyclone.psyir.symbols.SymbolTable`

    :returns: the new DataSymbol representing a derived type.
    :rtype: :py:class:`psyclone.psyir.symbols.DataSymbol`

    '''
    region_type = symbols.StructureType.create([
        ("nx", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC),
        ("ny", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC),
        ("domain", symbols.TypeSymbol("dom_type", symbols.DeferredType()),
         symbols.Symbol.Visibility.PUBLIC)
    ])
    region_type_sym = symbols.TypeSymbol("grid_type", region_type)
    region_array_type = symbols.ArrayType(region_type_sym, [2, 2])
    grid_type = symbols.StructureType.create([
        ("dx", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC),
        ("area", region_type_sym, symbols.Symbol.Visibility.PUBLIC),
        ("levels", region_array_type, symbols.Symbol.Visibility.PUBLIC)
    ])
    grid_type_sym = symbols.TypeSymbol("grid_type", grid_type)
    grid_var = symbols.DataSymbol("grid", grid_type_sym)
    table.add(grid_type_sym)
    table.add(grid_var)
    return grid_var
Beispiel #2
0
def test_reference_accesses():
    ''' Test that the reference_accesses method does nothing. This will
    be addressed by #1028. '''
    var_access_info = VariablesAccessInfo()
    dref = nodes.StructureReference.create(
        symbols.DataSymbol(
            "grid", symbols.TypeSymbol("grid_type", symbols.DeferredType())),
        ["data"])
    dref.reference_accesses(var_access_info)
    assert var_access_info.all_signatures == []
def test_reference_accesses():
    ''' Test the reference_accesses method.
    '''
    dref = nodes.StructureReference.create(
        symbols.DataSymbol(
            "grid", symbols.DataTypeSymbol("grid_type",
                                           symbols.DeferredType())), ["data"])
    var_access_info = VariablesAccessInfo()
    dref.reference_accesses(var_access_info)

    assert var_access_info.all_signatures == [Signature(("grid", "data"))]
    # By default all accesses are marked as read
    assert str(var_access_info) == "grid%data: READ"
def test_struc_ref_create_errors():
    ''' Tests for the validation checks in the create method. '''
    with pytest.raises(TypeError) as err:
        _ = nodes.StructureReference.create(None, [])
    assert ("'symbol' argument to StructureReference.create() should be a "
            "DataSymbol but found 'NoneType'" in str(err.value))
    with pytest.raises(TypeError) as err:
        _ = nodes.StructureReference.create(
            symbols.DataSymbol("fake", symbols.INTEGER_TYPE), [])
    assert ("symbol that is (or could be) a structure, however symbol "
            "'fake' has type 'Scalar" in str(err.value))
    with pytest.raises(TypeError) as err:
        _ = nodes.StructureReference.create(
            symbols.DataSymbol("grid", symbols.DeferredType()), 1)
    assert ("'members' argument to StructureReference._create() must be a "
            "list but found 'int'" in str(err.value))
    with pytest.raises(ValueError) as err:
        _ = nodes.StructureReference.create(
            symbols.DataSymbol("grid", symbols.DeferredType()), [])
    assert ("one or more structure 'members' that are being accessed but "
            "got an empty list for symbol 'grid'" in str(err.value))
    grid_type = symbols.StructureType.create([
        ("nx", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC)
    ])
    tsymbol_known = symbols.DataTypeSymbol("grid_type", grid_type)
    with pytest.raises(TypeError) as err:
        _ = nodes.StructureReference.create(
            symbols.DataSymbol("grid", tsymbol_known), [1])
    assert ("'members' passed to StructureType._create() must consist of "
            "either 'str' or 2-tuple entries but found 'int' in the last "
            "entry while attempting to create reference to symbol 'grid'"
            in str(err.value))
    with pytest.raises(TypeError) as err:
        _ = nodes.StructureReference.create(
            symbols.DataSymbol("grid", tsymbol_known), [1, "hello"])
    assert ("'members' passed to StructureType._create() must consist of "
            "either 'str' or 2-tuple entries but found 'int' while "
            "attempting to create reference to symbol 'grid'"
            in str(err.value))
Beispiel #5
0
def test_asr_create(component_symbol):
    ''' Check the create method. '''
    int_one = nodes.Literal("1", symbols.INTEGER_TYPE)
    # Reference to scalar member of structure in array of structures
    asref = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    [int_one], ["nx"])
    assert isinstance(asref.children[0], nodes.Member)
    assert isinstance(asref.children[1], nodes.Literal)
    check_links(asref, asref.children)
    # Reference to member of structure member of structure in array of
    # structures
    asref = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    [int_one],
                                                    ["region", "startx"])
    assert isinstance(asref.children[0], nodes.StructureMember)
    assert isinstance(asref.children[0].children[0], nodes.Member)
    # Reference to range of structures
    lbound = nodes.BinaryOperation.create(
        nodes.BinaryOperation.Operator.LBOUND,
        nodes.Reference(component_symbol), int_one)
    ubound = nodes.BinaryOperation.create(
        nodes.BinaryOperation.Operator.UBOUND,
        nodes.Reference(component_symbol), int_one)
    my_range = nodes.Range.create(lbound, ubound)
    asref = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    [my_range], ["nx"])
    assert isinstance(asref.children[0], nodes.Member)
    assert isinstance(asref.children[1], nodes.Range)
    check_links(asref, asref.children)
    check_links(asref.children[1], asref.children[1].children)
    # Reference to a symbol of DeferredType
    ssym = symbols.DataSymbol("grid", symbols.DeferredType())
    asref = nodes.ArrayOfStructuresReference.create(ssym, [int_one],
                                                    ["region", "startx"])
    assert isinstance(asref.symbol.datatype, symbols.DeferredType)
    assert isinstance(asref.children[0], nodes.StructureMember)
    assert isinstance(asref.children[0].children[0], nodes.Member)
Beispiel #6
0
def test_am_is_lower_upper_bound():
    ''' Test the is_lower/upper_bound methods of ArrayMember. '''
    one = nodes.Literal("1", symbols.INTEGER_TYPE)
    two = nodes.Literal("2", symbols.INTEGER_TYPE)
    amem1 = nodes.ArrayMember.create(
        "subdomains",
        [one.copy(), nodes.Literal("2", symbols.INTEGER_TYPE)])
    assert amem1.is_lower_bound(0) is False
    assert amem1.is_upper_bound(0) is False
    grid_type = symbols.DataTypeSymbol("grid_type", symbols.DeferredType())
    sym = symbols.DataSymbol("grid_var", grid_type)
    ref = nodes.StructureReference.create(sym, ["data"])
    # Start and stop for the range are binary operators but not the right ones
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, ref.copy(),
        one.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, ref.copy(),
        one.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym, [("data", [my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is False
    assert amem2.is_upper_bound(0) is False
    # Correct binary operators but wrong types of operand
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, one.copy(),
        one.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, one.copy(),
        one.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym, [("data", [my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is False
    assert amem2.is_upper_bound(0) is False
    # Correct start and stop arguments to Range
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, ref.copy(),
        one.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, ref.copy(),
        one.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym, [("data", [my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is True
    assert amem2.is_upper_bound(0) is True
    # Range in a dimension other than the first
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, ref.copy(),
        two.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, ref.copy(),
        two.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym,
                                           [("data", [one.copy(), my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is False
    assert amem2.is_upper_bound(0) is False
    assert amem2.is_lower_bound(1) is True
    assert amem2.is_upper_bound(1) is True
Beispiel #7
0
def test_am_matching_access():
    ''' Test the _matching_access method of ArrayMember. '''
    one = nodes.Literal("1", symbols.INTEGER_TYPE)
    two = nodes.Literal("2", symbols.INTEGER_TYPE)
    amem1 = nodes.ArrayMember.create(
        "subdomains",
        [one.copy(), nodes.Literal("2", symbols.INTEGER_TYPE)])
    # Check when the ArrayMember has no parent Reference
    result = amem1._matching_access(
        nodes.Reference(symbols.DataSymbol("fake", symbols.INTEGER_TYPE)))
    assert result is False
    grid_type = symbols.DataTypeSymbol("grid_type", symbols.DeferredType())
    sym1 = symbols.DataSymbol("grid_var", grid_type)
    sym2 = symbols.DataSymbol("grid_var2", grid_type)
    ref1 = nodes.StructureReference.create(sym1, ["data"])
    # Reference is to a different symbol
    ref2 = nodes.StructureReference.create(sym2, [("data", [one.copy()])])
    assert ref2.member._matching_access(ref1) is False
    # Reference is to a different member of the same symbol
    ref2 = nodes.StructureReference.create(sym1, [("xvals", [one.copy()])])
    assert ref2.member._matching_access(ref1) is False
    ref1 = nodes.StructureReference.create(sym1, [("data", [one.copy()]),
                                                  ("xobs", [one.copy()])])
    ref2 = nodes.StructureReference.create(sym1, [("data", [one.copy()])])
    assert ref2.member._matching_access(ref1) is True
    ref2 = nodes.StructureReference.create(sym1, [("data", [one.copy()]),
                                                  ("yobs", [one.copy()])])
    amem = ref2.member.member  # "yobs"
    assert amem._matching_access(ref1) is False
    # The same 'signature' (a%b%c) but where b is an array access in one
    # case. This may not be possible in Fortran but we need to exercise
    # all conditions.
    ref1 = nodes.StructureReference.create(sym1,
                                           [("a", [one.copy()]), "b", "c"])
    ref2 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("c", [one.copy()])])
    amem = ref2.walk(nodes.ArrayMember)[0]
    assert amem._matching_access(ref1) is False
    # Same 'signature' but with one array access having more dimensions.
    ref1 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("c", [one.copy()])])
    ref2 = nodes.StructureReference.create(
        sym1, [("a", [one.copy()]), ("b", [one.copy(), one.copy()]),
               ("c", [one.copy()])])
    amem = ref2.walk(nodes.ArrayMember)[0]
    assert amem._matching_access(ref1) is False
    # Same 'signature' but with one array access having a different index.
    ref1 = nodes.StructureReference.create(
        sym1, [("a", [one.copy()]), ("b", [one.copy(), one.copy()]),
               ("c", [one.copy()])])
    ref2 = nodes.StructureReference.create(
        sym1, [("a", [one.copy()]), ("b", [one.copy(), two.copy()]),
               ("c", [one.copy()])])
    amem = ref2.walk(nodes.ArrayMember)[0]
    assert amem._matching_access(ref1) is False
    # Reference to an element of the same array
    ref1 = nodes.StructureReference.create(sym1, ["data"])
    ref2 = nodes.StructureReference.create(sym1, [("data", [one.copy()])])
    assert ref2.member._matching_access(ref1) is True
    # Reference to an ArrayOfStructures
    array_sym = symbols.DataSymbol("grids",
                                   symbols.ArrayType(grid_type, [two.copy()]))
    ref1 = nodes.ArrayOfStructuresReference.create(array_sym, [one.copy()],
                                                   ["data"])
    assert ref1._matching_access(nodes.Reference(array_sym))
    # member being compared is not at the bottom of a derived-type access
    ref1 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("d", [one.copy()])])
    ref2 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("c", [one.copy()])])
    amem = ref2.member.member
    assert amem.name == "b"
    assert amem._matching_access(ref1)