提交 b981e02b authored 作者: abergeron's avatar abergeron 提交者: GitHub

Merge pull request #5013 from nouiz/gpu_alloc_empty

Fix an error. GpuAllocEmpty in the new back-end was inheriting from A…
...@@ -7,7 +7,8 @@ import numpy ...@@ -7,7 +7,8 @@ import numpy
from theano import Op, Apply, Type, Variable from theano import Op, Apply, Type, Variable
from theano import tensor, config from theano import tensor, config
from theano.gradient import grad_undefined from theano.gradient import grad_undefined
from theano.tensor.basic import Alloc, Join, Split from theano.tensor.basic import (
Alloc, AllocEmpty, alloc_validate_shape, Join, Split)
from theano.gof import HideC, COp from theano.gof import HideC, COp
from theano.gof.utils import MethodNotDefined from theano.gof.utils import MethodNotDefined
...@@ -805,7 +806,7 @@ class GpuAlloc(HideC, Alloc): ...@@ -805,7 +806,7 @@ class GpuAlloc(HideC, Alloc):
def make_node(self, value, *shape): def make_node(self, value, *shape):
value = as_gpuarray_variable(value, context_name=self.context_name) value = as_gpuarray_variable(value, context_name=self.context_name)
sh, bcast = self.validate_shape(shape) sh, bcast = alloc_validate_shape(shape)
if value.ndim > len(sh): if value.ndim > len(sh):
TypeError("The GpuAlloc value to use has more dimensions " TypeError("The GpuAlloc value to use has more dimensions "
"than the specified shape", value.ndim, len(sh)) "than the specified shape", value.ndim, len(sh))
...@@ -941,7 +942,7 @@ def gpu_alloc(ctx, memset_0=False): ...@@ -941,7 +942,7 @@ def gpu_alloc(ctx, memset_0=False):
gpu_alloc.cache = {} gpu_alloc.cache = {}
class GpuAllocEmpty(HideC, Alloc): class GpuAllocEmpty(HideC, AllocEmpty):
""" """
Allocate uninitialized memory on the GPU. Allocate uninitialized memory on the GPU.
...@@ -958,7 +959,7 @@ class GpuAllocEmpty(HideC, Alloc): ...@@ -958,7 +959,7 @@ class GpuAllocEmpty(HideC, Alloc):
return get_context(self.context_name) return get_context(self.context_name)
def make_node(self, *shape): def make_node(self, *shape):
sh, bcast = self.validate_shape(shape) sh, bcast = alloc_validate_shape(shape)
output = GpuArrayType(dtype=self.dtype, broadcastable=bcast, output = GpuArrayType(dtype=self.dtype, broadcastable=bcast,
context_name=self.context_name)() context_name=self.context_name)()
output.tag.values_eq_approx = tensor.type.values_eq_approx_always_true output.tag.values_eq_approx = tensor.type.values_eq_approx_always_true
......
...@@ -3658,25 +3658,10 @@ class GpuAllocEmpty(GpuOp): ...@@ -3658,25 +3658,10 @@ class GpuAllocEmpty(GpuOp):
__props__ = () __props__ = ()
@staticmethod def make_node(self, *shape):
def validate_shape(shape): shape, bcast = tensor.basic.alloc_validate_shape(shape)
sh = [tensor.as_tensor_variable(s) for s in shape]
bcast = []
for s in sh:
if s.type.dtype[:3] not in ('int', 'uin'):
raise TypeError('Shape arguments must be integers', s)
# if s is constant 1, then we're broadcastable in that dim
try:
const_shp = tensor.get_scalar_constant_value(s)
except tensor.NotScalarConstantError:
const_shp = None
bcast.append(1 == const_shp)
otype = CudaNdarrayType(dtype='float32', broadcastable=bcast) otype = CudaNdarrayType(dtype='float32', broadcastable=bcast)
output = otype() output = otype()
return sh, output
def make_node(self, *shape):
shape, output = self.validate_shape(shape)
output.tag.values_eq_approx = tensor.type.values_eq_approx_always_true output.tag.values_eq_approx = tensor.type.values_eq_approx_always_true
# The outut can contain nan/inf. output.type is a new # The outut can contain nan/inf. output.type is a new
# instance, so we can do this only for that variable. # instance, so we can do this only for that variable.
...@@ -3767,7 +3752,11 @@ class GpuAlloc(GpuAllocEmpty): ...@@ -3767,7 +3752,11 @@ class GpuAlloc(GpuAllocEmpty):
# if there is unneeded transfert generated by the next line # if there is unneeded transfert generated by the next line
# the optimizer will remove them. # the optimizer will remove them.
v = as_cuda_ndarray_variable(value) v = as_cuda_ndarray_variable(value)
shape, output = self.validate_shape(shape)
shape, bcast = tensor.basic.alloc_validate_shape(shape)
otype = CudaNdarrayType(dtype='float32', broadcastable=bcast)
output = otype()
return Apply(self, [v] + shape, [output]) return Apply(self, [v] + shape, [output])
# This is required because the superclass (GpuAllocEmpty) also has it. # This is required because the superclass (GpuAllocEmpty) also has it.
......
...@@ -2726,27 +2726,7 @@ def identity_like(x): ...@@ -2726,27 +2726,7 @@ def identity_like(x):
return eye(x.shape[0], x.shape[1], k=0, dtype=x.dtype) return eye(x.shape[0], x.shape[1], k=0, dtype=x.dtype)
class Alloc(gof.Op): def alloc_validate_shape(shape):
"""Create a Tensor from an initial value and a desired shape.
alloc(value, shape0, shape1, ..., shapeN)
Returns an N-dimensional tensor initialized by `value` using something
equivalent to
z = numpy.zeros(shape, value.dtype)
z += value
The result has N dimensions, has the dtype of `value` and is obtained by
broadcasting value over the output ndarray.
This Op is used to replace fill() during optimizations because after shapes
are lifted, the first argument to fill can often be pruned from the graph.
"""
__props__ = ()
def validate_shape(self, shape):
sh = [as_tensor_variable(s) for s in shape] sh = [as_tensor_variable(s) for s in shape]
bcast = [] bcast = []
for i, s in enumerate(sh): for i, s in enumerate(sh):
...@@ -2775,9 +2755,33 @@ class Alloc(gof.Op): ...@@ -2775,9 +2755,33 @@ class Alloc(gof.Op):
bcast.append(1 == const_shp) bcast.append(1 == const_shp)
return sh, bcast return sh, bcast
class Alloc(gof.Op):
"""Create a Tensor from an initial value and a desired shape.
alloc(value, shape0, shape1, ..., shapeN)
Returns an N-dimensional tensor initialized by `value` using something
equivalent to
z = numpy.zeros(shape, value.dtype)
z += value
The result has N dimensions, has the dtype of `value` and is obtained by
broadcasting value over the output ndarray.
This Op is used to replace fill() during optimizations because after shapes
are lifted, the first argument to fill can often be pruned from the graph.
"""
__props__ = ()
def validate_shape(self, shape):
return alloc_validate_shape(shape)
def make_node(self, value, *shape): def make_node(self, value, *shape):
v = as_tensor_variable(value) v = as_tensor_variable(value)
sh, bcast = self.validate_shape(shape) sh, bcast = alloc_validate_shape(shape)
if v.ndim > len(sh): if v.ndim > len(sh):
raise TypeError("The Alloc value to use has more dimensions" raise TypeError("The Alloc value to use has more dimensions"
" than the specified dimensions", " than the specified dimensions",
...@@ -6356,24 +6360,11 @@ class AllocEmpty(gof.Op): ...@@ -6356,24 +6360,11 @@ class AllocEmpty(gof.Op):
assert isinstance(dtype, str), dtype assert isinstance(dtype, str), dtype
self.dtype = dtype.lower() self.dtype = dtype.lower()
def validate_shape(self, shape): def make_node(self, *shape):
sh = [as_tensor_variable(s) for s in shape] shape, bcast = alloc_validate_shape(shape)
bcast = []
for s in sh:
if s.type.dtype[:3] not in ('int', 'uin'):
raise TypeError('Shape arguments must be integers', s)
# if s is constant 1, then we're broadcastable in that dim
try:
const_shp = get_scalar_constant_value(s)
except NotScalarConstantError:
const_shp = None
bcast.append(1 == const_shp)
otype = TensorType(dtype=self.dtype, broadcastable=bcast) otype = TensorType(dtype=self.dtype, broadcastable=bcast)
output = otype() output = otype()
return sh, output
def make_node(self, *shape):
shape, output = self.validate_shape(shape)
output.tag.values_eq_approx = values_eq_approx_always_true output.tag.values_eq_approx = values_eq_approx_always_true
# The outut can contain nan/inf. output.type is a new # The outut can contain nan/inf. output.type is a new
# instance, so we can do this only for that variable. # instance, so we can do this only for that variable.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论