提交 0f7e6fad authored 作者: James Bergstra's avatar James Bergstra

added borrow and return_internal_type params to shared get_value and constructors

上级 7eb32681
...@@ -73,17 +73,18 @@ class SharedVariable(Variable): ...@@ -73,17 +73,18 @@ class SharedVariable(Variable):
readonly=False, readonly=False,
strict=strict) strict=strict)
def get_value(self, borrow=False): def get_value(self, borrow=False, return_internal_type=False):
"""Get the non-symbolic value associated with this SharedVariable. """Get the non-symbolic value associated with this SharedVariable.
:param borrow: :param borrow:
True to return the internal value directly, potentially creating problems related True to permit returning of an object aliased to internal memory.
to aliased memory. :param return_internal_type:
True to permit the returning of an arbitrary type object used internally to store
If the return value is mutable, and you have used borrow=True to get at the internal the shared variable.
value, then you should be careful about changing it. If you modify it, call
set_value(rval, borrow=True) to tell Theano that you modified it. (Theano may have Only with borrow=False and return_internal_type=True does this function guarantee that
cached computations based on the old value.) you actually get the internal object. But in that case, you may get different return
types when using different compute devices.
""" """
if borrow: if borrow:
...@@ -116,7 +117,7 @@ class SharedVariable(Variable): ...@@ -116,7 +117,7 @@ class SharedVariable(Variable):
return cp return cp
def _value_get(self): def _value_get(self):
return self.get_value(borrow=config.shared.value_borrows) return self.get_value(borrow=config.shared.value_borrows, return_internal_type=False)
def _value_set(self, new_value): def _value_set(self, new_value):
return self.set_value(new_value, borrow=config.shared.value_borrows) return self.set_value(new_value, borrow=config.shared.value_borrows)
......
...@@ -48,15 +48,22 @@ CudaNdarrayType.Constant = CudaNdarrayConstant ...@@ -48,15 +48,22 @@ CudaNdarrayType.Constant = CudaNdarrayConstant
class CudaNdarraySharedVariable(SharedVariable, _operators): class CudaNdarraySharedVariable(SharedVariable, _operators):
def __getvalue(self): def get_value(self, borrow=False, return_internal_type=False):
# Return a read-only array, since it is only a copy, if return_internal_type: # return a cuda_ndarray
# to avoid users modifying it expecting self.container.value to change if borrow:
v = numpy.asarray(self.container.value) return self.container.value
v.setflags(write=False) else:
return v return copy.deepcopy(self.container.value)
def __setvalue(self, value): else: #return an ndarray
self.container.value = value #container does the filtering return numpy.asarray(self.container.value)
value = property(__getvalue, __setvalue)
def set_value(self, value, borrow=False):
if not borrow:
#TODO: check for cuda_ndarray type
if not isinstance(value, numpy.ndarray):
# in case this is a cuda_ndarray, we copy it
value = copy.deepcopy(value)
self.container.value = value # this will copy a numpy ndarray
def filter_update(self, other): def filter_update(self, other):
if hasattr(other, '_as_CudaNdarrayVariable'): if hasattr(other, '_as_CudaNdarrayVariable'):
...@@ -73,7 +80,7 @@ class CudaNdarraySharedVariable(SharedVariable, _operators): ...@@ -73,7 +80,7 @@ class CudaNdarraySharedVariable(SharedVariable, _operators):
CudaNdarrayType.SharedVariable = CudaNdarraySharedVariable CudaNdarrayType.SharedVariable = CudaNdarraySharedVariable
def cuda_shared_constructor(value, name=None, strict=False, broadcastable=None): def cuda_shared_constructor(value, name=None, strict=False, borrow=False, broadcastable=None):
"""SharedVariable Constructor for TensorType""" """SharedVariable Constructor for TensorType"""
# THIS CONSTRUCTOR TRIES TO CAST VALUE TO A FLOAT32, WHICH THEN GOES ONTO THE CARD # THIS CONSTRUCTOR TRIES TO CAST VALUE TO A FLOAT32, WHICH THEN GOES ONTO THE CARD
...@@ -103,7 +110,7 @@ def cuda_shared_constructor(value, name=None, strict=False, broadcastable=None): ...@@ -103,7 +110,7 @@ def cuda_shared_constructor(value, name=None, strict=False, broadcastable=None):
raise raise
return rval return rval
def float32_shared_constructor(value, name=None, strict=False, broadcastable=None): def float32_shared_constructor(value, name=None, strict=False, borrow=False, broadcastable=None):
"""SharedVariable Constructor for TensorType""" """SharedVariable Constructor for TensorType"""
# if value isn't a float32 ndarray, then raise # if value isn't a float32 ndarray, then raise
......
import copy
import scipy.sparse import scipy.sparse
from theano.compile import shared_constructor, SharedVariable from theano.compile import shared_constructor, SharedVariable
from theano import config from theano import config
...@@ -7,7 +8,7 @@ class SparseTensorSharedVariable(SharedVariable, _sparse_py_operators): ...@@ -7,7 +8,7 @@ class SparseTensorSharedVariable(SharedVariable, _sparse_py_operators):
pass pass
@shared_constructor @shared_constructor
def sparse_constructor(value, name=None, strict=False, format = None): def sparse_constructor(value, name=None, strict=False, borrow=False, format = None):
"""SharedVariable Constructor for SparseType """SharedVariable Constructor for SparseType
writeme writeme
...@@ -18,6 +19,8 @@ def sparse_constructor(value, name=None, strict=False, format = None): ...@@ -18,6 +19,8 @@ def sparse_constructor(value, name=None, strict=False, format = None):
if format is None: if format is None:
format = value.format format = value.format
type = SparseType(format =format, dtype = value.dtype) type = SparseType(format =format, dtype = value.dtype)
if not borrow:
value = copy.deepcopy(value)
return SparseTensorSharedVariable(type = type, value = value, name=name, strict =strict) return SparseTensorSharedVariable(type = type, value = value, name=name, strict =strict)
"""Define RandomStreams, providing random number variables for Theano graphs.""" """Define RandomStreams, providing random number variables for Theano graphs."""
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
import sys import copy, sys
import numpy import numpy
from theano.gof import Container from theano.gof import Container
...@@ -12,10 +12,12 @@ class RandomStateSharedVariable(SharedVariable): ...@@ -12,10 +12,12 @@ class RandomStateSharedVariable(SharedVariable):
pass pass
@shared_constructor @shared_constructor
def randomstate_constructor(value, name=None, strict=False): def randomstate_constructor(value, name=None, strict=False, borrow=False):
"""SharedVariable Constructor for RandomState""" """SharedVariable Constructor for RandomState"""
if not isinstance(value, numpy.random.RandomState): if not isinstance(value, numpy.random.RandomState):
raise TypeError raise TypeError
if not borrow:
value = copy.deepcopy(value)
return RandomStateSharedVariable( return RandomStateSharedVariable(
type=raw_random.random_state_type, type=raw_random.random_state_type,
value=value, value=value,
......
...@@ -9,7 +9,7 @@ class TensorSharedVariable(SharedVariable, _tensor_py_operators): ...@@ -9,7 +9,7 @@ class TensorSharedVariable(SharedVariable, _tensor_py_operators):
pass pass
@shared_constructor @shared_constructor
def tensor_constructor(value, name=None, strict=False, broadcastable=None): def tensor_constructor(value, name=None, strict=False, borrow=False, broadcastable=None):
"""SharedVariable Constructor for TensorType """SharedVariable Constructor for TensorType
:note: Regarding the inference of the broadcastable pattern... :note: Regarding the inference of the broadcastable pattern...
...@@ -27,7 +27,7 @@ def tensor_constructor(value, name=None, strict=False, broadcastable=None): ...@@ -27,7 +27,7 @@ def tensor_constructor(value, name=None, strict=False, broadcastable=None):
if broadcastable is None: if broadcastable is None:
broadcastable = (False,)*len(value.shape) broadcastable = (False,)*len(value.shape)
type = TensorType(value.dtype, broadcastable=broadcastable) type = TensorType(value.dtype, broadcastable=broadcastable)
return TensorSharedVariable(type=type, value=numpy.array(value,copy=True), name=name, strict=strict) return TensorSharedVariable(type=type, value=numpy.array(value,copy=(not borrow)), name=name, strict=strict)
# TensorSharedVariable brings in the tensor operators, is not ideal, but works as long as we # TensorSharedVariable brings in the tensor operators, is not ideal, but works as long as we
# dont do purely scalar-scalar operations # dont do purely scalar-scalar operations
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论