Esempio n. 1
0
def test_oclw_gen_declaration():
    '''Check the OpenCLWriter class gen_declaration method produces
    the expected declarations.

    '''
    oclwriter = OpenCLWriter()

    # Basic entry - Scalar are passed by value and don't have additional
    # qualifiers.
    symbol = DataSymbol("dummy1", INTEGER_TYPE)
    result = oclwriter.gen_declaration(symbol)
    assert result == "int dummy1"

    # Array argument has a memory qualifier (only __global for now)
    array_type = ArrayType(INTEGER_TYPE, [2, ArrayType.Extent.ATTRIBUTE, 2])
    symbol = DataSymbol("dummy2", array_type)
    result = oclwriter.gen_declaration(symbol)
    assert result == "__global int * restrict dummy2"

    # Array with unknown intent
    array_type = ArrayType(INTEGER_TYPE, [2, ArrayType.Extent.ATTRIBUTE, 2])
    symbol = DataSymbol("dummy2",
                        array_type,
                        interface=ArgumentInterface(
                            ArgumentInterface.Access.UNKNOWN))
    result = oclwriter.gen_declaration(symbol)
    assert result == "__global int * restrict dummy2"
Esempio n. 2
0
def create_expr(symbol_table):
    '''Utility routine that creates and returns an expression containing a
    number of array references containing range nodes. The expression
    looks like the following (using Fortran array notation):

    x(2:n:2)*z(1,2:n:2)+a(1)

    :param symbol_table: the symbol table to which we add the array \
        symbols.
    :type symbol_table: :py:class:`psyclone.psyir.symbol.SymbolTable`

    :returns: an expression containing 3 array references, 2 of which \
        contain ranges.
    :rtype: :py:class:`psyclone.psyir.nodes.BinaryOperation`

    '''
    array_symbol = DataSymbol("x", ArrayType(REAL_TYPE, [10]))
    symbol_table.add(array_symbol)
    symbol_n = symbol_table.lookup("n")
    array_x = Array.create(array_symbol, [create_stepped_range(symbol_n)])
    array_symbol = DataSymbol("z", ArrayType(REAL_TYPE, [10, 10]))
    symbol_table.add(array_symbol)
    array_z = Array.create(
        array_symbol,
        [Literal("1", INTEGER_TYPE),
         create_stepped_range(symbol_n)])
    array_symbol = DataSymbol("a", ArrayType(REAL_TYPE, [10]))
    array_a = Array.create(array_symbol, [Literal("1", INTEGER_TYPE)])
    symbol_table.add(array_symbol)
    mult = BinaryOperation.create(BinaryOperation.Operator.MUL, array_x,
                                  array_z)
    add = BinaryOperation.create(BinaryOperation.Operator.ADD, mult, array_a)
    return add
Esempio n. 3
0
def test_array_range_with_reduction():
    ''' Test that we correctly identify an array range when it is the result
        of a reduction from an array, e.g x(1, INT(SUM(map(:, :), 1))) = 1.0

    '''
    one = Literal("1.0", REAL_TYPE)
    int_one = Literal("1", INTEGER_TYPE)
    int_two = Literal("2", INTEGER_TYPE)
    int_array_type = ArrayType(INTEGER_SINGLE_TYPE, [10, 10])
    map_sym = DataSymbol("map", int_array_type)
    array_type = ArrayType(REAL_TYPE, [10, 10])
    symbol = DataSymbol("x", 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)
    lbound2 = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                     Reference(map_sym), int_two.copy())
    ubound2 = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                     Reference(map_sym), int_two.copy())
    my_range2 = Range.create(lbound2, ubound2)
    bsum_op = BinaryOperation.create(
        BinaryOperation.Operator.SUM,
        ArrayReference.create(map_sym, [my_range1, my_range2]), int_one.copy())
    int_op2 = UnaryOperation.create(UnaryOperation.Operator.INT, bsum_op)
    assignment = Assignment.create(
        ArrayReference.create(symbol, [int_one.copy(), int_op2]), one.copy())
    assert assignment.is_array_range is True
Esempio n. 4
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 = 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
Esempio n. 5
0
def test_arraytype_immutable():
    '''Test that the scalartype attributes can't be modified'''
    scalar_type = ScalarType(ScalarType.Intrinsic.REAL, 4)
    data_type = ArrayType(scalar_type, [10, 10])
    with pytest.raises(AttributeError):
        data_type.intrinsic = ScalarType.Intrinsic.INTEGER
    with pytest.raises(AttributeError):
        data_type.precision = 8
    with pytest.raises(AttributeError):
        data_type.shape = []
Esempio n. 6
0
def test_datasymbol_copy():
    '''Test that the DataSymbol copy method produces a faithful separate copy
    of the original symbol.

    '''
    array_type = ArrayType(REAL_SINGLE_TYPE, [1, 2])
    symbol = DataSymbol("myname",
                        array_type,
                        constant_value=None,
                        interface=ArgumentInterface(
                            ArgumentInterface.Access.READWRITE))
    new_symbol = symbol.copy()

    # Check the new symbol has the same properties as the original
    assert symbol.name == new_symbol.name
    assert symbol.datatype == new_symbol.datatype
    assert symbol.shape == new_symbol.shape
    assert symbol.constant_value == new_symbol.constant_value
    assert symbol.interface == new_symbol.interface

    # Change the properties of the new symbol and check the original
    # is not affected. Can't check constant_value yet as we have a
    # shape value
    new_symbol._name = "new"
    new_symbol.datatype = ArrayType(
        ScalarType(ScalarType.Intrinsic.INTEGER, ScalarType.Precision.DOUBLE),
        [3, 4])
    new_symbol._interface = LocalInterface()

    assert symbol.name == "myname"
    assert symbol.datatype.intrinsic == ScalarType.Intrinsic.REAL
    assert symbol.datatype.precision == ScalarType.Precision.SINGLE
    assert len(symbol.shape) == 2
    assert isinstance(symbol.shape[0], Literal)
    assert symbol.shape[0].value == "1"
    assert symbol.shape[0].datatype.intrinsic == ScalarType.Intrinsic.INTEGER
    assert symbol.shape[0].datatype.precision == ScalarType.Precision.UNDEFINED
    assert isinstance(symbol.shape[1], Literal)
    assert symbol.shape[1].value == "2"
    assert symbol.shape[1].datatype.intrinsic == ScalarType.Intrinsic.INTEGER
    assert symbol.shape[1].datatype.precision == ScalarType.Precision.UNDEFINED
    assert not symbol.constant_value

    # Now check constant_value
    new_symbol.constant_value = 3

    assert isinstance(symbol.shape[0], Literal)
    assert symbol.shape[0].value == "1"
    assert symbol.shape[0].datatype.intrinsic == ScalarType.Intrinsic.INTEGER
    assert symbol.shape[0].datatype.precision == ScalarType.Precision.UNDEFINED
    assert isinstance(symbol.shape[1], Literal)
    assert symbol.shape[1].value == "2"
    assert symbol.shape[1].datatype.intrinsic == ScalarType.Intrinsic.INTEGER
    assert symbol.shape[1].datatype.precision == ScalarType.Precision.UNDEFINED
    assert not symbol.constant_value
Esempio n. 7
0
def test_get_array_bound_error():
    '''Test that the _get_array_bound() utility function raises the
    expected exception if the shape of the array's symbol is not
    supported.'''
    array_type = ArrayType(REAL_TYPE, [10])
    array_symbol = DataSymbol("x", array_type)
    reference = Reference(array_symbol)
    array_type._shape = [0.2]
    with pytest.raises(TransformationError) as excinfo:
        _get_array_bound(reference, 0)
    assert ("Transformation Error: Unsupported index type 'float' found for "
            "dimension 1 of array 'x'." in str(excinfo.value))
Esempio n. 8
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', DataTypeSymbol("field_type",
                                                         DeferredType())),
                      DataSymbol)
Esempio n. 9
0
def test_arraytype_str_invalid():
    '''Test that the ArrayType class str method raises an exception if an
    unsupported dimension type is found.

    '''
    scalar_type = ScalarType(ScalarType.Intrinsic.INTEGER, 4)
    array_type = ArrayType(scalar_type, [10])
    # Make one of the array dimensions an unsupported type
    array_type._shape = [None]
    with pytest.raises(InternalError) as excinfo:
        _ = str(array_type)
    assert ("PSyclone internal error: ArrayType shape list elements can only "
            "be 'DataNode', or 'ArrayType.Extent', but found 'NoneType'."
            in str(excinfo.value))
Esempio n. 10
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 and
    false otherwise.

    '''
    one = Literal("1.0", REAL_TYPE)
    int_one = Literal("1", INTEGER_TYPE)
    var = DataSymbol("x", REAL_TYPE)
    reference = Reference(var)

    # lhs is not an array
    assignment = Assignment.create(reference, one)
    assert not assignment.is_array_range

    # lhs is an array reference but has no range
    array_type = ArrayType(REAL_TYPE, [10, 10])
    symbol = DataSymbol("x", array_type)
    array_ref = ArrayReference(symbol, [1, 3])
    assignment = Assignment.create(array_ref, one)
    assert not assignment.is_array_range

    # lhs is an array reference with a range
    my_range = Range.create(int_one, int_one, int_one)
    array_ref = ArrayReference.create(symbol, [my_range, int_one])
    assignment = Assignment.create(array_ref, one)
    assert assignment.is_array_range
Esempio n. 11
0
def test_check_variable():
    '''Test the _check_variable utility method behaves as expected'''

    with pytest.raises(GenerationError) as info:
        Loop._check_variable(None)
    assert ("variable property in Loop class should be a DataSymbol but "
            "found 'NoneType'." in str(info.value))

    with pytest.raises(GenerationError) as info:
        Loop._check_variable("hello")
    assert ("variable property in Loop class should be a DataSymbol but "
            "found 'str'." in str(info.value))

    array_type = ArrayType(INTEGER_TYPE, shape=[10, 20])
    array_symbol = DataSymbol("my_array", array_type)
    with pytest.raises(GenerationError) as info:
        Loop._check_variable(array_symbol)
    assert ("variable property in Loop class should be a ScalarType but "
            "found 'ArrayType'." in str(info.value))

    scalar_symbol = DataSymbol("my_array", REAL_TYPE)
    with pytest.raises(GenerationError) as info:
        Loop._check_variable(scalar_symbol)
    assert ("variable property in Loop class should be a scalar integer but "
            "found 'REAL'." in str(info.value))

    scalar_symbol = DataSymbol("my_array", INTEGER_TYPE)
    assert Loop._check_variable(scalar_symbol) is None
Esempio n. 12
0
def test_literal_init():
    '''Test the initialisation Literal object with ScalarType and
    ArrayType and different precisions.

    '''
    array_type = ArrayType(REAL_DOUBLE_TYPE, [10, 10])
    literal = Literal("1", array_type)
    assert literal.value == "1"
    assert isinstance(literal.datatype, ArrayType)
    assert literal.datatype.intrinsic == ScalarType.Intrinsic.REAL
    assert literal.datatype.precision == ScalarType.Precision.DOUBLE
    assert len(literal.datatype.shape) == 2
    assert isinstance(literal.datatype.shape[0], Literal)
    assert literal.datatype.shape[0].value == '10'
    assert (literal.datatype.shape[0].datatype.intrinsic ==
            ScalarType.Intrinsic.INTEGER)
    assert (literal.datatype.shape[0].datatype.precision ==
            ScalarType.Precision.UNDEFINED)
    assert isinstance(literal.datatype.shape[1], Literal)
    assert literal.datatype.shape[1].value == '10'
    assert (literal.datatype.shape[1].datatype.intrinsic ==
            ScalarType.Intrinsic.INTEGER)
    assert (literal.datatype.shape[1].datatype.precision ==
            ScalarType.Precision.UNDEFINED)

    literal = Literal("true", BOOLEAN_TYPE)
    assert literal.value == "true"
    assert literal.datatype.intrinsic == ScalarType.Intrinsic.BOOLEAN
    assert literal.datatype.precision == ScalarType.Precision.UNDEFINED

    literal = Literal("false", BOOLEAN_TYPE)
    assert literal.value == "false"
    assert literal.datatype.intrinsic == ScalarType.Intrinsic.BOOLEAN
    assert literal.datatype.precision == ScalarType.Precision.UNDEFINED
Esempio n. 13
0
def test_arraytype():
    '''Test that the ArrayType class __init__ works as expected. Test the
    different dimension datatypes that are supported.'''
    scalar_type = ScalarType(ScalarType.Intrinsic.INTEGER, 4)
    data_symbol = DataSymbol("var", scalar_type, constant_value=30)
    one = Literal("1", scalar_type)
    var_plus_1 = BinaryOperation.create(
        BinaryOperation.Operator.ADD, Reference(data_symbol), one)
    literal = Literal("20", scalar_type)
    array_type = ArrayType(
        scalar_type, [10, literal, var_plus_1, Reference(data_symbol),
                      ArrayType.Extent.DEFERRED, ArrayType.Extent.ATTRIBUTE])
    assert isinstance(array_type, ArrayType)
    assert len(array_type.shape) == 6
    # Provided as an int but stored as a Literal
    shape0 = array_type.shape[0]
    assert isinstance(shape0, Literal)
    assert shape0.value == "10"
    assert shape0.datatype.intrinsic == ScalarType.Intrinsic.INTEGER
    assert shape0.datatype.precision == ScalarType.Precision.UNDEFINED
    # Provided and stored as a Literal (DataNode)
    assert array_type.shape[1] is literal
    # Provided and stored as an Operator (DataNode)
    assert array_type.shape[2] is var_plus_1
    # Provided and stored as a Reference to a DataSymbol
    assert isinstance(array_type.shape[3], Reference)
    assert array_type.shape[3].symbol is data_symbol
    # Provided and stored as a deferred extent
    assert array_type.shape[4] == ArrayType.Extent.DEFERRED
    # Provided as an attribute extent
    assert array_type.shape[5] == ArrayType.Extent.ATTRIBUTE
Esempio n. 14
0
def test_datasymbol_can_be_printed():
    '''Test that a DataSymbol instance can always be printed. (i.e. is
    initialised fully.)'''
    symbol = DataSymbol("sname", REAL_SINGLE_TYPE)
    assert "sname: <Scalar<REAL, SINGLE>, Local>" in str(symbol)

    sym1 = DataSymbol("s1",
                      INTEGER_SINGLE_TYPE,
                      interface=UnresolvedInterface())
    assert "s1: <Scalar<INTEGER, SINGLE>, Unresolved>" in str(sym1)

    array_type = ArrayType(REAL_SINGLE_TYPE,
                           [ArrayType.Extent.ATTRIBUTE, 2,
                            Reference(sym1)])
    sym2 = DataSymbol("s2", array_type)
    assert ("s2: <Array<Scalar<REAL, SINGLE>, shape=['ATTRIBUTE', "
            "Literal[value:'2', Scalar<INTEGER, UNDEFINED>], "
            "Reference[name:'s1']]>, Local>" in str(sym2))

    my_mod = ContainerSymbol("my_mod")
    sym3 = DataSymbol("s3",
                      REAL_SINGLE_TYPE,
                      interface=GlobalInterface(my_mod))
    assert ("s3: <Scalar<REAL, SINGLE>, Global(container='my_mod')>"
            in str(sym3))

    sym3 = DataSymbol("s3", INTEGER_SINGLE_TYPE, constant_value=12)
    assert ("s3: <Scalar<INTEGER, SINGLE>, Local, "
            "constant_value=Literal"
            "[value:'12', Scalar<INTEGER, SINGLE>]>" in str(sym3))

    sym4 = DataSymbol("s4",
                      INTEGER_SINGLE_TYPE,
                      interface=UnresolvedInterface())
    assert "s4: <Scalar<INTEGER, SINGLE>, Unresolved>" in str(sym4)
Esempio n. 15
0
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)
Esempio n. 16
0
def test_datasymbol_copy_properties():
    '''Test that the DataSymbol copy_properties method works as expected.'''
    array_type = ArrayType(REAL_SINGLE_TYPE, [1, 2])
    symbol = DataSymbol("myname",
                        array_type,
                        constant_value=None,
                        interface=ArgumentInterface(
                            ArgumentInterface.Access.READWRITE))

    # Check an exception is raised if an incorrect argument is passed in
    with pytest.raises(TypeError) as excinfo:
        symbol.copy_properties(None)
    assert ("Argument should be of type 'DataSymbol' but found 'NoneType'."
            "") in str(excinfo.value)

    new_symbol = DataSymbol("other_name",
                            INTEGER_SINGLE_TYPE,
                            constant_value=7)

    symbol.copy_properties(new_symbol)

    assert symbol.name == "myname"
    assert symbol.datatype.intrinsic == ScalarType.Intrinsic.INTEGER
    assert symbol.datatype.precision == ScalarType.Precision.SINGLE
    assert symbol.is_local
    assert isinstance(symbol.constant_value, Literal)
    assert symbol.constant_value.value == "7"
    assert (
        symbol.constant_value.datatype.intrinsic == symbol.datatype.intrinsic)
    assert (
        symbol.constant_value.datatype.precision == symbol.datatype.precision)
Esempio n. 17
0
def test_reference_accesses_bounds(operator_type):
    '''Test that the reference_accesses method behaves as expected when
    the reference is the first argument to either the lbound or ubound
    intrinsic as that is simply looking up the array bounds (therefore
    var_access_info should be empty) and when the reference is the
    second argument of either the lbound or ubound intrinsic (in which
    case the access should be a read).

    '''
    # Note, one would usually expect UBOUND to provide the upper bound
    # of a range but to simplify the test both LBOUND and UBOUND are
    # used for the lower bound. This does not affect the test.
    one = Literal("1", INTEGER_TYPE)
    array_symbol = DataSymbol("test", ArrayType(REAL_TYPE, [10]))
    array_ref1 = Reference(array_symbol)
    array_ref2 = Reference(array_symbol)
    array_access = Array.create(array_symbol, [one])

    # test when first or second argument to LBOUND or UBOUND is an
    # array reference
    operator = BinaryOperation.create(operator_type, array_ref1, array_ref2)
    array_access.children[0] = Range.create(operator, one, one)
    var_access_info = VariablesAccessInfo()
    array_ref1.reference_accesses(var_access_info)
    assert str(var_access_info) == ""
    var_access_info = VariablesAccessInfo()
    array_ref2.reference_accesses(var_access_info)
    assert str(var_access_info) == "test: READ"
Esempio n. 18
0
def test_literal_can_be_printed():
    '''Test that a Literal instance can always be printed (i.e. is
    initialised fully)'''
    array_type = ArrayType(REAL_DOUBLE_TYPE, [10, 10])
    literal = Literal("1", array_type)
    assert ("Literal[value:'1', Array<Scalar<REAL, DOUBLE>, "
            "shape=[10, 10]>]" in str(literal))
Esempio n. 19
0
def test_arraytype():
    '''Test that the ArrayType class __init__ works as expected.'''
    datatype = ScalarType(ScalarType.Intrinsic.INTEGER, 4)
    shape = [10, 10]
    array_type = ArrayType(datatype, shape)
    assert isinstance(array_type, ArrayType)
    assert array_type.shape == shape
    assert array_type._datatype == datatype
Esempio n. 20
0
def create_matmul():
    '''Utility function that creates a valid matmul node for use with
    subsequent tests.

    '''
    symbol_table = SymbolTable()
    one = Literal("1", INTEGER_TYPE)
    two = Literal("2", INTEGER_TYPE)
    index = DataSymbol("idx", INTEGER_TYPE, constant_value=3)
    symbol_table.add(index)
    array_type = ArrayType(REAL_TYPE, [5, 10, 15])
    mat_symbol = DataSymbol("x", array_type)
    symbol_table.add(mat_symbol)
    lbound1 = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                     Reference(mat_symbol), one.copy())
    ubound1 = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                     Reference(mat_symbol), one.copy())
    my_mat_range1 = Range.create(lbound1, ubound1, one.copy())
    lbound2 = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                     Reference(mat_symbol), two.copy())
    ubound2 = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                     Reference(mat_symbol), two.copy())
    my_mat_range2 = Range.create(lbound2, ubound2, one.copy())
    matrix = ArrayReference.create(
        mat_symbol, [my_mat_range1, my_mat_range2,
                     Reference(index)])
    array_type = ArrayType(REAL_TYPE, [10, 20])
    vec_symbol = DataSymbol("y", array_type)
    symbol_table.add(vec_symbol)
    lbound = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                    Reference(vec_symbol), one.copy())
    ubound = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                    Reference(vec_symbol), one.copy())
    my_vec_range = Range.create(lbound, ubound, one.copy())
    vector = ArrayReference.create(
        vec_symbol, [my_vec_range, Reference(index)])
    matmul = BinaryOperation.create(BinaryOperation.Operator.MATMUL, matrix,
                                    vector)
    lhs_type = ArrayType(REAL_TYPE, [10])
    lhs_symbol = DataSymbol("result", lhs_type)
    symbol_table.add(lhs_symbol)
    lhs = Reference(lhs_symbol)
    assign = Assignment.create(lhs, matmul)
    KernelSchedule.create("my_kern", symbol_table, [assign])
    return matmul
Esempio n. 21
0
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
Esempio n. 22
0
def test_arraytype_invalid_datatype():
    '''Test that the ArrayType class raises an exception when the datatype
    argument is the wrong type.

    '''
    with pytest.raises(TypeError) as excinfo:
        _ = ArrayType(None, None)
    assert ("ArrayType expected 'datatype' argument to be of type DataType "
            "or DataTypeSymbol but found 'NoneType'." in str(excinfo.value))
Esempio n. 23
0
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()
Esempio n. 24
0
def test_cw_gen_declaration():
    '''Check the CWriter class gen_declaration method produces
    the expected declarations.

    '''
    cwriter = CWriter()

    # Basic entries
    symbol = DataSymbol("dummy1", INTEGER_TYPE)
    result = cwriter.gen_declaration(symbol)
    assert result == "int dummy1"

    symbol = DataSymbol("dummy1", CHARACTER_TYPE)
    result = cwriter.gen_declaration(symbol)
    assert result == "char dummy1"

    symbol = DataSymbol("dummy1", BOOLEAN_TYPE)
    result = cwriter.gen_declaration(symbol)
    assert result == "bool dummy1"

    # Array argument
    array_type = ArrayType(REAL_TYPE, [2, ArrayType.Extent.ATTRIBUTE, 2])
    symbol = DataSymbol("dummy2",
                        array_type,
                        interface=ArgumentInterface(
                            ArgumentInterface.Access.READ))
    result = cwriter.gen_declaration(symbol)
    assert result == "double * restrict dummy2"

    # Array with unknown access
    array_type = ArrayType(INTEGER_TYPE, [2, ArrayType.Extent.ATTRIBUTE, 2])
    symbol = DataSymbol("dummy2",
                        array_type,
                        interface=ArgumentInterface(
                            ArgumentInterface.Access.UNKNOWN))
    result = cwriter.gen_declaration(symbol)
    assert result == "int * restrict dummy2"

    # Check invalid datatype produces and error
    symbol._datatype = "invalid"
    with pytest.raises(NotImplementedError) as error:
        _ = cwriter.gen_declaration(symbol)
    assert "Could not generate the C definition for the variable 'dummy2', " \
        "type 'invalid' is currently not supported." in str(error.value)
Esempio n. 25
0
def test_array_is_lower_bound():
    '''Test that the is_lower_bound method in the Array Node works as
    expected.

    '''
    one = Literal("1", INTEGER_TYPE)
    array = ArrayReference.create(DataSymbol("test",
                                             ArrayType(REAL_TYPE, [10])),
                                  [one])
    with pytest.raises(TypeError) as info:
        array.is_lower_bound("hello")
    assert ("The index argument should be an integer but found 'str'."
            in str(info.value))

    # not a range node at index 0
    assert not array.is_lower_bound(0)

    # range node does not have a binary operator for its start value
    array.children[0] = Range.create(one, one, one)
    assert not array.is_lower_bound(0)

    # range node lbound references a different array
    array2 = ArrayReference.create(DataSymbol("test2",
                                              ArrayType(REAL_TYPE, [10])),
                                   [one])
    operator = BinaryOperation.create(
        BinaryOperation.Operator.LBOUND, array2,
        Literal("1", INTEGER_TYPE))
    array.children[0] = Range.create(operator, one, one)
    assert not array.is_lower_bound(0)

    # range node lbound references a different index
    operator = BinaryOperation.create(
        BinaryOperation.Operator.LBOUND, array,
        Literal("2", INTEGER_TYPE))
    array.children[0] = Range.create(operator, one, one)
    assert not array.is_lower_bound(0)

    # all is well
    operator = BinaryOperation.create(
        BinaryOperation.Operator.LBOUND, array, one)
    array.children[0] = Range.create(operator, one, one)
    assert array.is_lower_bound(0)
Esempio n. 26
0
def test_validate3():
    '''Check that the Matmul2Code validate method raises the expected
    exception when the supplied node is a MATMUL binary operation but
    doesn't have an assignment as an ancestor.

    '''
    trans = Matmul2CodeTrans()
    vector_type = ArrayType(REAL_TYPE, [10])
    array_type = ArrayType(REAL_TYPE, [10, 10])
    vector = Reference(DataSymbol("x", vector_type))
    array = Reference(DataSymbol("y", array_type))
    matmul = BinaryOperation.create(BinaryOperation.Operator.MATMUL, array,
                                    vector)
    with pytest.raises(TransformationError) as excinfo:
        trans.validate(matmul)
    assert ("Transformation Error: Error in Matmul2CodeTrans transformation. "
            "This transformation requires the operator to be part of an "
            "assignment statement, but no such assignment was found."
            in str(excinfo.value))
Esempio n. 27
0
def test_arraytype_invalid_shape():
    '''Test that the ArrayType class raises an exception when the shape
    argument is the wrong type.

    '''
    scalar_type = ScalarType(ScalarType.Intrinsic.REAL, 4)
    with pytest.raises(TypeError) as excinfo:
        _ = ArrayType(scalar_type, None)
    assert ("ArrayType 'shape' must be of type list but "
            "found 'NoneType'." in str(excinfo.value))
Esempio n. 28
0
def test_arraytype_datatypesymbol_only():
    ''' Test that we currently refuse to make an ArrayType with an intrinsic
    type of StructureType. (This limitation is the subject of #1031.) '''
    with pytest.raises(NotImplementedError) as err:
        _ = ArrayType(StructureType.create(
            [("nx", INTEGER_TYPE, Symbol.Visibility.PUBLIC)]),
                      [5])
    assert ("When creating an array of structures, the type of those "
            "structures must be supplied as a DataTypeSymbol but got a "
            "StructureType instead." in str(err.value))
Esempio n. 29
0
def test_arraytype_str():
    '''Test that the ArrayType class str method works as expected.'''
    scalar_type = ScalarType(ScalarType.Intrinsic.INTEGER,
                             ScalarType.Precision.UNDEFINED)
    data_symbol = DataSymbol("var", scalar_type)
    data_type = ArrayType(scalar_type, [
        10, data_symbol, ArrayType.Extent.DEFERRED, ArrayType.Extent.ATTRIBUTE
    ])
    assert (str(data_type) == "Array<Scalar<INTEGER, UNDEFINED>,"
            " shape=[10, var, 'DEFERRED', 'ATTRIBUTE']>")
Esempio n. 30
0
def test_arraytype_str():
    '''Test that the ArrayType class str method works as expected.'''
    scalar_type = ScalarType(ScalarType.Intrinsic.INTEGER,
                             ScalarType.Precision.UNDEFINED)
    data_symbol = DataSymbol("var", scalar_type, constant_value=20)
    data_type = ArrayType(scalar_type, [10, Reference(data_symbol),
                                        ArrayType.Extent.DEFERRED,
                                        ArrayType.Extent.ATTRIBUTE])
    assert (str(data_type) == "Array<Scalar<INTEGER, UNDEFINED>,"
            " shape=[Literal[value:'10', Scalar<INTEGER, UNDEFINED>], "
            "Reference[name:'var'], 'DEFERRED', 'ATTRIBUTE']>")