Esempio n. 1
0
def test_opwiseclinker_constant():
    x, y, z = inputs()
    x = Constant(tdouble, 7.2, name="x")
    e = add(mul(x, y), mul(y, z))
    lnk = OpWiseCLinker().accept(FunctionGraph([y, z], [e]))
    fn = lnk.make_function()
    res = fn(1.5, 3.0)
    assert res == 15.3
Esempio n. 2
0
def test_c_fail_error():
    x, y, z = inputs()
    x = Constant(tdouble, 7.2, name="x")
    e = add_fail(mul(x, y), mul(y, z))
    lnk = OpWiseCLinker().accept(FunctionGraph([y, z], [e]))
    fn = lnk.make_function()
    with pytest.raises(RuntimeError):
        fn(1.5, 3.0)
Esempio n. 3
0
def test_opwiseclinker_straightforward():
    x, y, z = inputs()
    e = add(mul(add(x, y), div(x, y)), bad_sub(bad_sub(x, y), z))
    lnk = OpWiseCLinker().accept(FunctionGraph([x, y, z], [e]))
    fn = lnk.make_function()
    if aesara.config.cxx:
        assert fn(2.0, 2.0, 2.0) == 2.0
    else:
        # The python version of bad_sub always return -10.
        assert fn(2.0, 2.0, 2.0) == -6
Esempio n. 4
0
    def __init__(self,
                 pre_func=None,
                 post_func=None,
                 optimizer="default",
                 linker=None):
        self.pre_func = pre_func
        self.post_func = post_func
        wrap_linker = WrapLinkerMany([OpWiseCLinker()], [self.eval])
        if optimizer == "default":
            optimizer = config.optimizer
        if linker is not None and not isinstance(linker.mode, MonitorMode):
            raise Exception(
                "MonitorMode can only use its own linker! You "
                "should not provide one.",
                linker,
            )

        super().__init__(wrap_linker, optimizer=optimizer)
Esempio n. 5
0
def test_sort_schedule_fn():
    import aesara
    from aesara.graph.sched import make_depends, sort_schedule_fn

    x = matrix("x")
    y = aesara.tensor.dot(x[:5] * 2, x.T + 1).T

    def str_cmp(a, b):
        return cmp(str(a), str(b))  # lexicographical sort

    linker = OpWiseCLinker(schedule=sort_schedule_fn(str_cmp))
    mode = Mode(linker=linker)
    f = aesara.function((x, ), (y, ), mode=mode)

    nodes = f.maker.linker.make_all()[-1]
    depends = make_depends()
    for a, b in zip(nodes[:-1], nodes[1:]):
        if not depends((b, a)):
            assert str(a) < str(b)
Esempio n. 6
0
def test_duallinker_mismatch():
    x, y, z = inputs()
    # bad_sub is correct in C but erroneous in Python
    e = bad_sub(mul(x, y), mul(y, z))
    g = FunctionGraph([x, y, z], [e])
    lnk = DualLinker(checker=_my_checker).accept(g)
    fn = make_function(lnk)

    # good
    assert make_function(CLinker().accept(g))(1.0, 2.0, 3.0) == -4.0
    # good
    assert make_function(OpWiseCLinker().accept(g))(1.0, 2.0, 3.0) == -4.0

    # (purposely) wrong
    assert make_function(PerformLinker().accept(g))(1.0, 2.0, 3.0) == -10.0

    with pytest.raises(MyExc):
        # this runs OpWiseCLinker and PerformLinker in parallel and feeds
        # variables of matching operations to _my_checker to verify that they
        # are the same.
        fn(1.0, 2.0, 3.0)
Esempio n. 7
0
)
from aesara.graph.optdb import EquilibriumDB, LocalGroupDB, Query, SequenceDB, TopoDB
from aesara.link.basic import PerformLinker
from aesara.link.c.basic import CLinker, OpWiseCLinker
from aesara.link.jax import JAXLinker
from aesara.link.vm import VMLinker

_logger = logging.getLogger("aesara.compile.mode")

# If a string is passed as the linker argument in the constructor for
# Mode, it will be used as the key to retrieve the real linker in this
# dictionary
predefined_linkers = {
    "py": PerformLinker(),  # Use allow_gc Aesara flag
    "c": CLinker(),  # Don't support gc. so don't check allow_gc
    "c|py": OpWiseCLinker(),  # Use allow_gc Aesara flag
    "c|py_nogc": OpWiseCLinker(allow_gc=False),
    "vm": VMLinker(use_cloop=False),  # Use allow_gc Aesara flag
    "cvm": VMLinker(use_cloop=True),  # Use allow_gc Aesara flag
    "vm_nogc": VMLinker(allow_gc=False, use_cloop=False),
    "cvm_nogc": VMLinker(allow_gc=False, use_cloop=True),
    "jax": JAXLinker(),
}


def register_linker(name, linker):
    """Add a `Linker` which can be referred to by `name` in `Mode`."""
    if name in predefined_linkers:
        raise ValueError(f"Linker name already taken: {name}")
    predefined_linkers[name] = linker
Esempio n. 8
0
 def test_c_or_py(self):
     # Shape op don't have C code.
     # But This will test DimShuffle c code
     self.with_linker(OpWiseCLinker())
Esempio n. 9
0
def test_gc_never_pickles_temporaries():
    x = dvector()

    r = x
    for i in range(2):  # TODO: 30 causes like LONG compilation due to MERGE
        r = r + r / 10

    optimizer = None
    optimizer = "fast_run"

    for f_linker, g_linker in [
        (PerformLinker(allow_gc=True), PerformLinker(allow_gc=False)),
        (OpWiseCLinker(allow_gc=True), OpWiseCLinker(allow_gc=False)),
    ]:
        # f_linker has garbage collection

        # g_linker has no garbage collection

        f = aesara.function([x],
                            r,
                            mode=Mode(optimizer=optimizer, linker=f_linker))
        g = aesara.function([x],
                            r,
                            mode=Mode(optimizer=optimizer, linker=g_linker))

        pre_f = pickle.dumps(f)
        # pre_g = pickle.dumps(g)
        len_pre_f = len(pre_f)

        # len_pre_g = len(pre_g)

        # We can't compare the content or the length of the string
        # between f and g. 2 reason, we store some timing information
        # in float. They won't be the same each time. Different float
        # can have different length when printed.

        def a(fn):
            return len(pickle.dumps(fn.maker))

        assert a(f) == a(f)  # some sanity checks on the pickling mechanism
        assert a(g) == a(g)  # some sanity checks on the pickling mechanism

        def b(fn):
            return len(
                pickle.dumps(
                    aesara.compile.function.types._pickle_Function(fn)))

        assert b(f) == b(f)  # some sanity checks on the pickling mechanism

        def c(fn):
            return len(pickle.dumps(fn))

        assert c(f) == c(f)  # some sanity checks on the pickling mechanism
        assert c(g) == c(g)  # some sanity checks on the pickling mechanism

        # now run the function once to create temporaries within the no-gc
        # linker
        f(np.ones(100, dtype="float64"))
        g(np.ones(100, dtype="float64"))

        # serialize the functions again
        post_f = pickle.dumps(f)
        post_g = pickle.dumps(g)
        len_post_f = len(post_f)
        len_post_g = len(post_g)

        # assert that f() didn't cause the function to grow
        # allow_gc should leave the function un-changed by calling
        assert len_pre_f == len_post_f, (len_pre_f, len_post_f)

        # assert that g() didn't cause g to grow because temporaries
        # that weren't collected shouldn't be pickled anyway
        # Allow for a couple of bytes of difference, since timing info,
        # for instance, can be represented as text of varying size.
        assert abs(len_post_f - len_post_g) < 256, (f_linker, len_post_f,
                                                    len_post_g)
Esempio n. 10
0
from aesara.graph.sched import sort_schedule_fn
from aesara.link.c.basic import OpWiseCLinker
from aesara.tensor.io import (
    MPISend,
    MPISendWait,
    mpi_cmps,
    mpi_enabled,
    mpi_send_wait_cmp,
    recv,
    send,
)
from aesara.tensor.type import matrix


mpi_scheduler = sort_schedule_fn(*mpi_cmps)
mpi_linker = OpWiseCLinker(schedule=mpi_scheduler)
mpi_mode = Mode(linker=mpi_linker)


@config.change_flags(compute_test_value="off")
def test_recv():
    x = recv((10, 10), "float64", 0, 11)
    assert x.dtype == "float64"
    assert x.broadcastable == (False, False)

    recvnode = x.owner.inputs[0].owner
    assert recvnode.op.source == 0
    assert recvnode.op.tag == 11


def test_send():