Example #1
0
    def test_no_repeats(self):
        a = Argument("a")
        b = Argument("b")

        exp = a + b - a

        assert exp.get_all_argument_names() == ["a", "b"]
Example #2
0
    def test_arguments(self):
        assert Argument("foo").generate_code() == ("def f(foo):\n"
                                                   "    return foo\n")

        # Arguments should be in alphabetical order
        foo_bar = Argument("foo") + Argument("bar")
        assert foo_bar.generate_code() == ("def f(bar, foo):\n"
                                           "    return (foo + bar)\n")
Example #3
0
    def test_binary_operator_uses_pyexp_passed_in(self):
        lhs = Argument("lhs")
        rhs = Argument("rhs")
        exp = PyExp._binary_operator(lhs, rhs, "*")

        assert isinstance(exp, BinaryOperator)
        assert exp._lhs == lhs
        assert exp._rhs == rhs
        assert exp._operator == "*"
Example #4
0
    def test_ordered(self):
        a = Argument("a")
        b = Argument("b")

        exp = a + b
        assert exp.get_all_argument_names() == ["a", "b"]

        exp = b + a
        assert exp.get_all_argument_names() == ["a", "b"]
Example #5
0
def test_make_variable_coeff_arrays():
    coeff_arrays = make_variable_coeff_arrays(2, 0, Argument("foobar"))

    assert isinstance(coeff_arrays[1]["HL"][2, 3], PyExp)
    assert coeff_arrays[1]["HL"][2, 3] == Argument("foobar")[1]["HL"][2, 3]

    # Check default argument works too since it is a somewhat exciting type...
    assert make_variable_coeff_arrays(
        2, 0)[1]["HL"][2, 3] == Argument("coeffs")[1]["HL"][2, 3]
Example #6
0
def test_make_function():
    a = Argument("a")
    b = Argument("b")
    c = Argument("c")

    abc = (a + b) * c

    f = abc.make_function()

    assert f(a=1, b=2, c=10) == (1 + 2) * 10
Example #7
0
def test_variable_array():
    a = VariableArray(3, Argument("arg"))

    assert a.period == (1, 1, 1)
    assert a.nop is False
    assert a.relative_step_size_to(a) == (1, 1, 1)
    assert a.relative_step_size_to(VariableArray(2, Argument("arg"))) is None

    assert a[0, 0, 0] == Subscript(Argument("arg"), Constant((0, 0, 0)))

    assert a[1, 2, 3] == Subscript(Argument("arg"), Constant((1, 2, 3)))
Example #8
0
    def test_only_used_once(self):
        a = Argument("a")
        b = Argument("b")
        c = Argument("c")

        a_plus_b = a + b
        a_plus_b_plus_c = a_plus_b + c

        a_plus_b_plus_c._auto_inline()

        assert a_plus_b_plus_c._inline is True
        assert a_plus_b._inline is True
Example #9
0
    def test_used_multiple_times(self):
        a = Argument("a")
        b = Argument("b")
        c = Argument("c")

        a_plus_b = a + b
        twice_a_plus_b = a_plus_b + a_plus_b

        twice_a_plus_b._auto_inline()

        assert twice_a_plus_b._inline is True
        assert a_plus_b._inline is False
Example #10
0
    def test_swap(self):
        # Check variable swapping is supported (i.e. items in before and after
        # are same)

        a = Argument("a")
        b = Argument("b")

        a_sub_b = a - b

        b_sub_a = a_sub_b.subs({a: b, b: a})

        assert str(b_sub_a) == str(b - a)
Example #11
0
def make_variable_coeff_arrays(dwt_depth, dwt_depth_ho,
                               exp=Argument("coeffs")):
    r"""
    Create a set of :py:class:`~vc2_bit_widths.infinite_arrays.SymbolArray`\ s
    representing transform coefficient values, as expected by
    :py:func:`synthesis_transform`.
    
    Returns
    =======
    coeff_arrays : {level: {orientation: :py:class:`~vc2_bit_widths.infinite_arrays.VariableArray`, ...}, ...}
        The transform coefficient values. These dictionaries are indexed the
        same way as 'coeff_data' in the idwt pseudocode function in (15.4.1) in
        the VC-2 specification.
        
        The expressions within the
        :py:class:`~vc2_bit_widths.infinite_arrays.VariableArray`\ s will be
        indexed as follows::
        
            >>> from vc2_bit_widths.pyexp import Argument
            
            >>> coeffs_arg = Argument("coeffs_arg")
            >>> coeff_arrays = make_variable_coeff_arrays(3, 0, coeffs_arg)
            >>> coeff_arrays[2]["LH"][3, 4] == coeffs_arg[2]["LH"][3, 4]
            True
    """
    def make_array(level, orient):
        return VariableArray(2, exp[level][orient])

    return make_coeff_arrays(dwt_depth, dwt_depth_ho, make_array)
Example #12
0
def test_ensure_py_exp():
    # Passes through PyExp types unchanged
    foo = Argument("foo")
    assert ensure_py_exp(foo) is foo

    # Wraps other values in Constant
    assert ensure_py_exp(123) == Constant(123)
Example #13
0
    def test_subs_in_reused_binary_operator(self):
        # Check if operands to a re-used binary operator are changed, the new
        # expression still re-uses the updated binary operator.
        a = Argument("a")
        b = Argument("b")
        c = Argument("c")
        d = Argument("d")

        a_plus_b = a + b

        a_plus_b_squared = a_plus_b * a_plus_b

        # Sanity check
        assert a_plus_b_squared.lhs is a_plus_b_squared.rhs

        c_plus_d_squared = a_plus_b_squared.subs({a: c, b: d})
        assert c_plus_d_squared.lhs is c_plus_d_squared.rhs
Example #14
0
    def test_subscript(self):
        a = Argument("a")
        c = Constant(123)

        s = a[c]

        assert isinstance(s, Subscript)
        assert s.exp is a
        assert s.key is c
Example #15
0
def test_deeply_nested_expression():
    a = Argument("a")
    nest_depth = 1000
    for _ in range(nest_depth):
        a += 1

    f = a.make_function()

    assert f(10) == 10 + nest_depth
Example #16
0
    def test_nested_out_of_lineable_values(self):
        a = Argument("a")
        b = a + 1  # Depth 2 -> 0 (de-inlined)
        c = b + 1  # Depth 1
        d = c + 1  # Depth 2 -> 0 (de-inlined)
        e = d + 1  # Depth 1
        f = e + 1  # Depth 0

        f._auto_inline(2)
        assert not b._inline
        assert c._inline
        assert not d._inline
        assert e._inline
        assert f._inline
def test_get_transform_coeffs_used_by_synthesis_exp():
    a = Argument("a")
    
    exp = (
        a[0]["L"][(1, 2)] +
        a[1]["H"][(2, 3)] +
        a[2]["LH"][(3, 4)] +
        123
    )
    
    assert set(get_transform_coeffs_used_by_synthesis_exp(exp)) == set([
        (0, "L", 1, 2),
        (1, "H", 2, 3),
        (2, "LH", 3, 4),
    ])
Example #18
0
    def test_binary_operators(self, operator):
        a = Argument("a")
        b = Argument("b")

        # Native operation
        exp = eval("a {} b".format(operator), {}, {"a": a, "b": b})
        assert isinstance(exp, BinaryOperator)
        assert exp._lhs == a
        assert exp._rhs == b
        assert exp._operator == operator

        # RHS is not PyExp
        exp = eval("a {} 123".format(operator), {}, {"a": a})
        assert isinstance(exp, BinaryOperator)
        assert exp._lhs == a
        assert exp._rhs == Constant(123)
        assert exp._operator == operator

        # Reverse-operator methods (and LHS is not PyExp)
        exp = eval("123 {} a".format(operator), {}, {"a": a})
        assert isinstance(exp, BinaryOperator)
        assert exp._lhs == Constant(123)
        assert exp._rhs == a
        assert exp._operator == operator
Example #19
0
    def test_subs(self, exp, key):
        s = Subscript(exp, key)

        # Substitute whole subscript
        assert s.subs({exp[key]: Argument("bar")}) == Argument("bar")

        # Substitute expression
        assert s.subs({exp: Argument("bar")}) == Argument("bar")[123]

        # Substitute key
        assert s.subs({key: Constant(321)}) == exp[321]

        # Substitute nothing relevant
        assert s.subs({Argument("bar"): Argument("xxx")}) is s
Example #20
0
def exp_coeff_nested_dicts_to_list(exp):
    """
    Transform a synthesis transform describing
    :py:class:`~vc2_bit_widths.pyexp.PyExp` such that instead of taking a
    nested dictionary of coefficient value arrays it takes a single list of
    coefficient values.
    
    This transformation can speed up the execution of the generated function by
    around 3x while also eliminating the need to construct nested dictionaries
    of values as arguments (also a substantial performance saving).
    
    Parameters
    ==========
    exp : :py:class:`~vc2_bit_widths.pyexp.PyExp`
        An expression defined in terms of a single
        :py:class:`~vc2_bit_widths.pyexp.Argument` which is always used
        subscripted in the form ``arg[level][orient][x, y]``.
    
    Returns
    =======
    exp : :py:class:`~vc2_bit_widths.pyexp.PyExp`
        A modified expression which takes a single :py:class:`list` as
        argument. The values in this list should correspond to the transform
        coefficients enumerated in ``transform_coeffs_used``
    transform_coeffs_used : [(level, orient, x, y), ...]
        The transform coefficients expected by the returned expression, in the
        order they're expected.
    """
    transform_coeffs_used = get_transform_coeffs_used_by_synthesis_exp(exp)
    
    # Find the Argument in the expression
    all_argument_names = exp.get_all_argument_names()
    assert len(all_argument_names) == 1
    argument = Argument(all_argument_names[0])
    
    new_exp = exp.subs({
        argument[level][orient][x, y]: argument[i]
        for i, (level, orient, x, y) in enumerate(transform_coeffs_used)
    })
    
    return (new_exp, transform_coeffs_used)
Example #21
0
    def test_subs(self, lhs, rhs):
        b = lhs + rhs

        # Substitute whole subscript: NB: same object must be used in this case
        assert b.subs({b: Argument("bar")}) == Argument("bar")

        # NB: in the following we must comprae string for true equality since
        # BinaryOperators are compared by identity

        # Substitute LHS
        assert repr(b.subs({lhs:
                            Argument("foo")})) == repr(Argument("foo") + rhs)

        # Substitute RHS
        assert str(b.subs({rhs:
                           Argument("foo")})) == str(lhs + Argument("foo"))

        # Substitution which makes operation a no-op should not return a
        # BinaryOperator
        assert b.subs({rhs: Constant(0)}) == lhs

        # Substitute nothing relevant
        assert b.subs({Argument("bar"): Argument("xxx")}) is b
def test_exp_coeff_nested_dicts_to_list():
    a = Argument("a")
    
    dict_exp = (
        a[0]["L"][(1, 2)] -
        a[1]["H"][(2, 3)] +
        123
    )
    
    list_exp, transform_coeffs_used = exp_coeff_nested_dicts_to_list(dict_exp)
    
    coeffs_dict = {
        0: {"L": {(1, 2): 100}},
        1: {"H": {(2, 3): 1000}},
    }
    coeffs_list = [
        coeffs_dict[level][orient][x, y]
        for level, orient, x, y in transform_coeffs_used
    ]
    
    dict_f = dict_exp.make_function()
    list_f = list_exp.make_function()
    
    assert dict_f(a=coeffs_dict) == list_f(a=coeffs_list)
Example #23
0
 def test_code(self):
     a = Argument("foo")
     assert list(a.get_dependencies()) == []
     assert list(a.get_argument_names()) == ["foo"]
     assert a.get_definitions() == ""
     assert a.get_expression() == "foo"
Example #24
0
 def test_eq(self, exp, key):
     assert Subscript(exp, key) == Subscript(exp, key)
     assert Subscript(exp, key) != Subscript(Argument("bar"), key)
     assert Subscript(exp, key) != Subscript(exp, Constant(321))
Example #25
0
 def test_hash(self, exp, key):
     assert hash(Subscript(exp, key)) == hash(Subscript(exp, key))
     assert hash(Subscript(exp, key)) != hash(
         Subscript(Argument("bar"), key))
     assert hash(Subscript(exp, key)) != hash(Subscript(exp, Constant(321)))
Example #26
0
 def exp(self):
     return Argument("foo")
Example #27
0
 def test_subs(self):
     a = Argument("foo")
     assert a.subs({Argument("foo"): Argument("bar")}) == Argument("bar")
     assert a.subs({Argument("bar"): Argument("xxx")}) is a
Example #28
0
 def test_repr(self):
     assert repr(Argument("foo")) == "Argument('foo')"
Example #29
0
 def test_eq(self):
     assert Argument("foo") == Argument("foo")
     assert Argument("foo") != Argument("bar")
     assert Argument("foo") != Constant("foo")
Example #30
0
 def test_hash(self):
     assert hash(Argument("foo")) == hash(Argument("foo"))
     assert hash(Argument("foo")) != hash(Argument("bar"))