Пример #1
0
def test_validate7():
    '''Check that the Matmul2Code validate method raises the expected
    exception when the supplied node is a MATMUL binary operation but
    its first (matrix) argument has fewer than 2 dimensions.

    '''
    trans = Matmul2CodeTrans()
    array_type = ArrayType(REAL_TYPE, [10])
    array = Reference(DataSymbol("x", array_type))
    matmul = BinaryOperation.create(BinaryOperation.Operator.MATMUL,
                                    array.copy(), array.copy())
    _ = Assignment.create(array, matmul)
    with pytest.raises(TransformationError) as excinfo:
        trans.validate(matmul)
    assert ("Transformation Error: Expected 1st child of a MATMUL "
            "BinaryOperation to be a matrix with at least 2 dimensions, "
            "but found '1'." in str(excinfo.value))
Пример #2
0
def test_validate6():
    '''Check that the Matmul2Code validate method raises the expected
    exception when the supplied node is a MATMUL binary operation but
    either or both of its arguments are references to datasymbols that
    are not arrays.

    '''
    trans = Matmul2CodeTrans()
    scalar = Reference(DataSymbol("x", REAL_TYPE))
    matmul = BinaryOperation.create(BinaryOperation.Operator.MATMUL, scalar,
                                    scalar.copy())
    _ = Assignment.create(scalar.copy(), matmul)
    with pytest.raises(TransformationError) as excinfo:
        trans.validate(matmul)
    assert ("Transformation Error: Expected children of a MATMUL "
            "BinaryOperation to be references to arrays, but found "
            "'DataSymbol', 'DataSymbol'." in str(excinfo.value))
Пример #3
0
def test_validate4():
    '''Check that the Matmul2Code validate method raises the expected
    exception when the supplied node is a MATMUL binary operation but
    it is not the only operation on the RHS of an assignment.

    '''
    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)
    rhs = BinaryOperation.create(BinaryOperation.Operator.MUL, matmul,
                                 vector.copy())
    _ = Assignment.create(array.copy(), rhs)
    with pytest.raises(TransformationError) as excinfo:
        trans.validate(matmul)
    assert ("Transformation Error: Matmul2CodeTrans only supports the "
            "transformation of a MATMUL operation when it is the sole "
            "operation on the rhs of an assignment." in str(excinfo.value))
Пример #4
0
def test_reference_can_be_copied():
    ''' Test that a reference can be copied. '''

    array_symbol = DataSymbol("symbol", ArrayType(REAL_TYPE, [10]))
    scalar_symbol = DataSymbol("other", REAL_TYPE)

    ref = Reference(array_symbol)

    ref1 = ref.copy()
    assert isinstance(ref1, Reference)
    assert ref1 is not ref
    assert ref1.symbol is array_symbol

    # Modifying the new reference does not affect the original
    ref1._symbol = scalar_symbol
    assert ref.symbol is array_symbol
Пример #5
0
def test_validate9():
    '''Check that the Matmul2Code validate method raises the expected
    exception when the supplied node is a MATMUL binary operation but
    its second (vector) argument is a reference to a vector with
    greater than 1 dimension.

    '''
    trans = Matmul2CodeTrans()
    array_type = ArrayType(REAL_TYPE, [10, 10])
    array = Reference(DataSymbol("x", array_type))
    vector_type = ArrayType(REAL_TYPE, [10, 10, 10])
    vector = Reference(DataSymbol("y", vector_type))
    matmul = BinaryOperation.create(BinaryOperation.Operator.MATMUL, array,
                                    vector)
    _ = Assignment.create(array.copy(), matmul)
    with pytest.raises(TransformationError) as excinfo:
        trans.validate(matmul)
    assert ("Transformation Error: Expected 2nd child of a MATMUL "
            "BinaryOperation to have 1 dimension, but found '3'."
            in str(excinfo.value))
Пример #6
0
def test_array_is_full_range():
    '''Test that the is_full_range method in the Array Node works as
    expected. '''
    # pylint: disable=too-many-statements
    zero = Literal("0", INTEGER_SINGLE_TYPE)
    one = Literal("1", INTEGER_SINGLE_TYPE)
    array_type = ArrayType(REAL_SINGLE_TYPE, [10])
    symbol = DataSymbol("my_array", array_type)
    reference = Reference(symbol)
    lbound = BinaryOperation.create(BinaryOperation.Operator.LBOUND, reference,
                                    one)
    ubound = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                    reference.copy(), one.copy())
    symbol_error = DataSymbol("another_array", array_type)
    reference_error = Reference(symbol_error)

    # Index out of bounds
    array_reference = ArrayReference.create(symbol, [one.copy()])
    with pytest.raises(ValueError) as excinfo:
        array_reference.is_full_range(1)
    assert ("In ArrayReference 'my_array' the specified index '1' must be "
            "less than the number of dimensions '1'." in str(excinfo.value))

    # Array dimension is not a Range
    assert not array_reference.is_full_range(0)

    # Check LBOUND
    # Array dimension range lower bound is not a binary operation
    my_range = Range.create(one.copy(), one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range lower bound is not an LBOUND binary operation
    my_range = Range.create(ubound, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range lower bound is an LBOUND binary operation
    # with the first value not being a reference
    lbound_error = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                          zero.copy(), zero.copy())
    my_range = Range.create(lbound_error, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range lower bound is an LBOUND binary operation
    # with the first value being a reference to a different symbol
    lbound_error = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                          reference_error, zero.copy())
    my_range = Range.create(lbound_error, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range lower bound is an LBOUND binary operation
    # with the second value not being a literal.
    lbound_error = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                          reference.copy(), reference.copy())
    my_range = Range.create(lbound_error, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range lower bound is an LBOUND binary operation
    # with the second value not being an integer literal.
    lbound_error = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                          reference.copy(),
                                          Literal("1.0", REAL_SINGLE_TYPE))
    my_range = Range.create(lbound_error, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range lower bound is an LBOUND binary operation
    # with the second value being an integer literal with the wrong
    # value (should be 0 as this dimension index is 0).
    lbound_error = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                          reference.copy(), one.copy())
    my_range = Range.create(lbound_error, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Check UBOUND
    # Array dimension range upper bound is not a binary operation
    my_range = Range.create(lbound, one.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range upper bound is not a UBOUND binary operation
    my_range = Range.create(lbound.copy(), lbound.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range upper bound is a UBOUND binary operation
    # with the first value not being a reference
    ubound_error = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                          zero.copy(), zero.copy())
    my_range = Range.create(lbound.copy(), ubound_error, one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range upper bound is a UBOUND binary operation
    # with the first value being a reference to a different symbol
    ubound_error = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                          reference_error.copy(), zero.copy())
    my_range = Range.create(lbound.copy(), ubound_error, one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range upper bound is a UBOUND binary operation
    # with the second value not being a literal.
    ubound_error = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                          reference.copy(), reference.copy())
    my_range = Range.create(lbound.copy(), ubound_error, one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range upper bound is a UBOUND binary operation
    # with the second value not being an integer literal.
    ubound_error = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                          reference.copy(),
                                          Literal("1.0", REAL_SINGLE_TYPE))
    my_range = Range.create(lbound.copy(), ubound_error, one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range upper bound is a UBOUND binary operation
    # with the second value being an integer literal with the wrong
    # value (should be 1 as this dimension is 1).
    ubound_error = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                          reference.copy(), zero.copy())
    my_range = Range.create(lbound.copy(), ubound_error, one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Check Step
    # Array dimension range step is not a literal.
    my_range = Range.create(lbound.copy(), ubound.copy(), lbound.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range step is not an integer literal.
    my_range = Range.create(lbound.copy(), ubound.copy(), one.copy())
    # We have to change this to a non-integer manually as the create
    # function only accepts integer literals for the step argument.
    my_range.children[2] = Literal("1.0", REAL_SINGLE_TYPE)
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # Array dimension range step is is an integer literal with the
    # wrong value (not 1).
    my_range = Range.create(lbound.copy(), ubound.copy(), zero.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert not array_reference.is_full_range(0)

    # All is as it should be.
    # The full range is covered so return true.
    my_range = Range.create(lbound.copy(), ubound.copy(), one.copy())
    array_reference = ArrayReference.create(symbol, [my_range])
    assert array_reference.is_full_range(0)