提交 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):
readonly=False,
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.
:param borrow:
True to return the internal value directly, potentially creating problems related
to aliased memory.
If the return value is mutable, and you have used borrow=True to get at the internal
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
cached computations based on the old value.)
True to permit returning of an object aliased to internal memory.
:param return_internal_type:
True to permit the returning of an arbitrary type object used internally to store
the shared variable.
Only with borrow=False and return_internal_type=True does this function guarantee that
you actually get the internal object. But in that case, you may get different return
types when using different compute devices.
"""
if borrow:
......@@ -116,7 +117,7 @@ class SharedVariable(Variable):
return cp
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):
return self.set_value(new_value, borrow=config.shared.value_borrows)
......
......@@ -48,15 +48,22 @@ CudaNdarrayType.Constant = CudaNdarrayConstant
class CudaNdarraySharedVariable(SharedVariable, _operators):
def __getvalue(self):
# Return a read-only array, since it is only a copy,
# to avoid users modifying it expecting self.container.value to change
v = numpy.asarray(self.container.value)
v.setflags(write=False)
return v
def __setvalue(self, value):
self.container.value = value #container does the filtering
value = property(__getvalue, __setvalue)
def get_value(self, borrow=False, return_internal_type=False):
if return_internal_type: # return a cuda_ndarray
if borrow:
return self.container.value
else:
return copy.deepcopy(self.container.value)
else: #return an ndarray
return numpy.asarray(self.container.value)
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):
if hasattr(other, '_as_CudaNdarrayVariable'):
......@@ -73,7 +80,7 @@ class CudaNdarraySharedVariable(SharedVariable, _operators):
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"""
# 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):
raise
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"""
# if value isn't a float32 ndarray, then raise
......
import copy
import scipy.sparse
from theano.compile import shared_constructor, SharedVariable
from theano import config
......@@ -7,7 +8,7 @@ class SparseTensorSharedVariable(SharedVariable, _sparse_py_operators):
pass
@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
writeme
......@@ -18,6 +19,8 @@ def sparse_constructor(value, name=None, strict=False, format = None):
if format is None:
format = value.format
type = SparseType(format =format, dtype = value.dtype)
if not borrow:
value = copy.deepcopy(value)
return SparseTensorSharedVariable(type = type, value = value, name=name, strict =strict)
"""Define RandomStreams, providing random number variables for Theano graphs."""
__docformat__ = "restructuredtext en"
import sys
import copy, sys
import numpy
from theano.gof import Container
......@@ -12,10 +12,12 @@ class RandomStateSharedVariable(SharedVariable):
pass
@shared_constructor
def randomstate_constructor(value, name=None, strict=False):
def randomstate_constructor(value, name=None, strict=False, borrow=False):
"""SharedVariable Constructor for RandomState"""
if not isinstance(value, numpy.random.RandomState):
raise TypeError
if not borrow:
value = copy.deepcopy(value)
return RandomStateSharedVariable(
type=raw_random.random_state_type,
value=value,
......
......@@ -9,7 +9,7 @@ class TensorSharedVariable(SharedVariable, _tensor_py_operators):
pass
@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
:note: Regarding the inference of the broadcastable pattern...
......@@ -27,7 +27,7 @@ def tensor_constructor(value, name=None, strict=False, broadcastable=None):
if broadcastable is None:
broadcastable = (False,)*len(value.shape)
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
# dont do purely scalar-scalar operations
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论