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)
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