def test_gpujoin_preserves_broadcasting():
    _a = numpy.asarray([[1, 2], [3, 4]], dtype="float32")
    _b = numpy.asarray([[5, 6, 7], [8, 9, 10]], dtype="float32")
    a = tcn.shared_constructor(_a)
    b = tcn.shared_constructor(_b)

    # [0,0] : the two original dims were non-broadcastable
    # [1,x,0]: new order and broadcastability
    gpu_dimshuffle = GpuDimShuffle([0, 0], [1, "x", 0])

    a_shuffled = gpu_dimshuffle(a)
    b_shuffled = gpu_dimshuffle(b)

    c = gpu_join(0, a_shuffled, b_shuffled)

    assert c.type.broadcastable == (False, True, False)

    f = theano.function([], c, mode=mode_with_gpu)

    res = f()

    a_reshaped = numpy.asarray([[[1, 3]], [[2, 4]]], dtype="float32")
    b_reshaped = numpy.asarray([[[5, 8]], [[6, 9]], [[7, 10]]], dtype="float32")

    concat = numpy.concatenate([a_reshaped, b_reshaped], axis=0)

    assert numpy.all(res == concat)
Exemple #2
0
def local_gpu_join(node):
    """
    Inspired by the opt for convop.

    Very loose notation follows.

    Subgraphs concerned first look like
        [array of HostTensor] -> HostToGpu -> GpuToHost
        -> Join -> HostToGpu -> GpuToHost

    First we apply this Opt:

    join(host_from_gpu) -> host_from_gpu(gpu_join)

    then, as an intermediate result, there should be
    host_from_gpu(gpu_join) -> HostToGpu -> GpuToHost
    this unnecessary GpuToHost -> HostToGpu should be removed
    by other opts, leaving us with
    host_from_gpu(gpu_join)


    For intermediate places in the graph not covered by the first opt, the following could be useful:

    gpu_from_host(join) -> gpu_join(gpu_from_host)

    not implemented yet.

    """
    if isinstance(node.op, tensor.Join):
        # optimizing this case:
        # join(host_from_gpu) -> host_from_gpu(gpu_join)

        # print "OPT: we've got a Join instance"

        axis_and_tensors = node.inputs

        # print "OPT: axis_and_tensors=", axis_and_tensors

        matches = [not t.owner is None and t.owner.op == host_from_gpu for t in axis_and_tensors[1:]]

        # print "OPT: matches =", matches

        # if all input tensors are host_from_gpu'ified
        if numpy.all(matches):
            # the extra gpu_from_host introduced here will
            # be removed by further optimizations
            new_tensors = [gpu_from_host(t) for t in axis_and_tensors[1:]]
            new_a_and_t = [axis_and_tensors[0]] + new_tensors

            replacement_node = host_from_gpu(gpu_join(*new_a_and_t))

            # print "OPT: replacement_node", replacement_node

            return [replacement_node]
def test_gpujoin_twomatrices_joincolumns():
    _a = numpy.asarray([[1, 2], [3, 4]], dtype="float32")
    _b = numpy.asarray([[5, 6, 7], [8, 9, 10]], dtype="float32")
    a = tcn.shared_constructor(_a)
    b = tcn.shared_constructor(_b)

    c = gpu_join(1, a, b)

    f = theano.function([], c)

    assert numpy.all(f() == numpy.concatenate([_a, _b], axis=1))
def test_gpujoin_assert_cndas():
    # this will end up being an ndarray, as it's float64
    _a = numpy.asarray([[1, 2], [3, 4]], dtype="float64")
    a = theano.shared(_a)

    try:
        c = gpu_join(1, a)
        # can't "assert False" here, as we want the assertion
        # error from gpu_join
    except AssertionError:
        assert True
        return

    assert False
def test_gpujoin_twomatrices_badshapes():
    _a = numpy.asarray([[1, 2], [3, 4]], dtype="float32")
    _b = numpy.asarray([[5, 6, 7], [8, 9, 10]], dtype="float32")
    a = tcn.shared_constructor(_a)
    b = tcn.shared_constructor(_b)

    # try to join on dimension 0 where they don't agree (2!=3)
    c = gpu_join(0, a, b)

    f = theano.function([], c)

    try:
        f()
        assert False
    except ValueError:
        assert True