提交 5ea40ae1 authored 作者: James Bergstra's avatar James Bergstra

giant commit: moving pfunc & shared out of sandbox

上级 cf7f9f7e
......@@ -39,14 +39,15 @@ from gof import \
set_compiledir, get_compiledir, clear_compiledir
from compile import \
SymbolicInput, SymbolicInputKit, In, \
SymbolicInput, In, \
SymbolicOutput, Out, \
Mode, \
predefined_modes, predefined_linkers, predefined_optimizers, \
FunctionMaker, function, OpFromGraph, \
Component, External, Member, Method, \
Composite, ComponentList, ComponentDict, Module, \
ProfileMode
ProfileMode, \
Param, shared
FancyModule = Module
......
......@@ -19,3 +19,8 @@ from debugmode import DebugMode
from profilemode import ProfileMode
from theano.compile.sharedvalue import shared, shared_constructor, SharedVariable
from theano.compile.pfunc import pfunc, Param
from function import function
from theano import gof
from theano import gradient as G
from function_module import function
from function_module import orig_function
class OpFromGraph(gof.Op):
......@@ -44,7 +44,7 @@ class OpFromGraph(gof.Op):
raise TypeError('updates are not allowed in kwargs')
# TODO: the graph may have implicit inputs like Value and SharedVariable instances.
# what impact to they have on the validity of this Op?
self.fn = function(inputs, outputs, **kwargs)
self.fn = orig_function(inputs, outputs, **kwargs)
self.inputs = inputs
self.outputs = outputs
self.input_types = [input.type for input in inputs]
......
......@@ -830,10 +830,7 @@ def check_equal(x, y):
def register_checker(checker):
__checkers.insert(0, checker)
def function(inputs, outputs, mode=None, accept_inplace = False):
def orig_function(inputs, outputs, mode=None, accept_inplace = False):
"""
Return a Function that will calculate the outputs from the inputs.
......
......@@ -479,7 +479,7 @@ class Method(Component):
#backport
#effective_mode = mode if self.mode is None else self.mode
rval = F.function(inputs, outputs, effective_mode)
rval = F.orig_function(inputs, outputs, effective_mode)
memo[self] = rval
return rval
......
......@@ -2,8 +2,8 @@
__docformat__ = 'restructuredtext en'
from theano.gof import Container, Variable, generic, graph, Constant, Value
from theano.compile import function, In
from theano.compile.sandbox.sharedvalue import SharedVariable, shared
from theano.compile import orig_function, In, Out
from theano.compile.sharedvalue import SharedVariable, shared
import numpy # for backport to 2.4, to get any().
class Param(object):
......@@ -33,7 +33,7 @@ class Param(object):
self.strict = strict
self.implicit = implicit
def pfunc(params, outputs=None, mode=None, updates=[], givens=[]):
def pfunc(params, outputs=None, mode=None, updates=[], givens=[], accept_inplace=False):
"""Function-constructor for graphs with shared variables.
:type params: list of either Variable or Param instances.
......@@ -121,19 +121,33 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[]):
raise TypeError('Cannot use a shared variable (%s) as explicit input '
% v)
# computed_list is a list of output variables
# computed_list is a list of output variables (which will be extended later)
computed_list = []
if isinstance(outputs, list):
cloned_outputs = []
for v in outputs:
if not isinstance(v, Variable):
raise TypeError('outputs must be theano Variable instances', v)
# Copy list (because it may be extended later).
computed_list = [v_clone(o) for o in outputs]
cloned_outputs = list(computed_list)
if isinstance(v, Variable):
cloned_v = v_clone(v)
cloned_outputs.append(cloned_v)
elif isinstance(v, Out):
cloned_v = v_clone(v.variable)
cloned_outputs.append(Out(cloned_v, borrow=v.borrow))
else:
raise TypeError('outputs must be theano Variable or Out instances', v)
computed_list.append(cloned_v)
else:
if not isinstance(outputs, Variable):
raise TypeError('output must be a theano Variable instance', outputs)
cloned_outputs = v_clone(outputs)
computed_list = [cloned_outputs]
if isinstance(outputs, Variable):
cloned_v = v_clone(outputs)
cloned_outputs = cloned_v
computed_list.append(cloned_v)
elif isinstance(outputs, Out):
cloned_v = v_clone(outputs.variable)
cloned_outputs = Out(cloned_v, borrow=outputs.borrow)
computed_list.append(cloned_v)
elif outputs is None:
cloned_outputs = [] # TODO: return None
else:
raise TypeError('output must be a theano Variable or Out instance', outputs)
# Add update values as quantities that must be computed.
# Here, we
......@@ -187,14 +201,15 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[]):
in_sv.update = new_val
in_sv.mutable = True
return function(inputs, cloned_outputs, mode, accept_inplace=False)
return orig_function(inputs, cloned_outputs, mode, accept_inplace=accept_inplace)
def _pfunc_param_to_in(param):
if isinstance(param, Constant):
raise TypeError('Constants not allowed in param list', param)
if isinstance(param, Value):
raise NotImplementedError()
if isinstance(param, Variable): #includes SharedVariable
#if isinstance(param, Value):
#return In(variable=param)
#raise NotImplementedError()
if isinstance(param, Variable): #N.B. includes Value and SharedVariable
return In(variable=param)
elif isinstance(param, Param):
return In(
......@@ -204,7 +219,7 @@ def _pfunc_param_to_in(param):
mutable=param.mutable,
strict=param.strict,
implicit = param.implicit)
raise NotImplementedError('Unknown parameter type: %s' % type(param))
raise TypeError('Unknown parameter type: %s' % type(param))
def iter_over_pairs(pairs):
......
from theano.compile.sandbox.sharedvalue import shared, shared_constructor
from theano.compile.sandbox.pfunc import pfunc
import sys
print >> sys.stderr, "DEPRECATION: theano.compile.sandbox no longer provides shared, shared_constructor, and pfunc. They have been moved to theano.compile."
from theano.compile.sharedvalue import shared, shared_constructor
from theano.compile.pfunc import pfunc
......@@ -3,13 +3,7 @@ __docformat__ = 'restructuredtext en'
import traceback
import copy
import numpy
import theano.tensor.basic
from theano.gof import Container, Variable, generic
from theano.tensor import TensorType
from theano.scalar import Scalar
from theano.compile import function
import logging
_logger = logging.getLogger('theano.compile.sandbox.sharedvalue')
......@@ -146,59 +140,3 @@ def generic_constructor(value, name=None, strict=False):
"""SharedVariable Constructor"""
return SharedVariable(type=generic, value=value, name=name, strict=strict)
class TensorSharedVariable(SharedVariable, theano.tensor.basic._tensor_py_operators):
pass
@shared_constructor
def tensor_constructor(value, name=None, strict=False, broadcastable=None):
"""SharedVariable Constructor for TensorType
:note: Regarding the inference of the broadcastable pattern...
The default is to assume that the value might be resized in any dimension, so the default
broadcastable is ``(False,)*len(value.shape)``. The optional `broadcastable` argument will
override this default.
"""
if not isinstance(value, numpy.ndarray):
raise TypeError()
# if no broadcastable is given, then the default is to assume that the value might be
# resized in any dimension in the future.
#
if broadcastable is None:
broadcastable = (False,)*len(value.shape)
type = TensorType(value.dtype, broadcastable=broadcastable)
return TensorSharedVariable(type=type, value=value, 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
class ScalarSharedVariable(SharedVariable, theano.tensor.basic._tensor_py_operators):
pass
@shared_constructor
def scalar_constructor(value, name=None, strict=False, dtype=None):
"""SharedVariable constructor for scalar values. Defaults to int64 or float64.
:note: We implement this using 0-d tensors for now.
"""
if not isinstance (value, (numpy.number, float, int)):
raise TypeError()
if dtype is None:
if isinstance(value, float):
dtype = 'float64'
elif isinstance(value, int):
dtype = 'int64'
else:
dtype = type(value).__name__
type = TensorType(dtype=dtype, broadcastable=[])
try:
# don't pass the dtype to asarray because we want this to fail if strict is True and the
# types do not match
rval = ScalarSharedVariable(type=type, value=numpy.asarray(value), name=name, strict=strict)
return rval
except:
traceback.print_exc()
raise
......@@ -4,6 +4,7 @@ from theano import gof
from theano import compile
from theano.compile.function_module import *
from theano.compile import function
from theano.scalar import *
from theano import tensor
......
......@@ -4,6 +4,7 @@ from theano import gof
from theano import compile
from theano.scalar import *
from theano.compile.function_module import *
from theano.compile import function
from theano import tensor
from theano import tensor as T
......
import numpy, theano, unittest
from theano.compile.sandbox.pfunc import pfunc
from theano.compile.sandbox.sharedvalue import shared
from theano.compile.pfunc import pfunc
from theano.compile.sharedvalue import shared
from theano import tensor
from theano.tensor.nnet import sigmoid
......
......@@ -5,8 +5,8 @@ import theano
from theano.tensor import Tensor, dmatrix, dvector, lscalar
from theano import tensor
from theano.compile.sandbox.sharedvalue import *
from theano.compile.sandbox.pfunc import *
from theano.compile.sharedvalue import *
from theano.compile.pfunc import *
class Test_pfunc(unittest.TestCase):
......
......@@ -2,9 +2,9 @@ import numpy
import unittest
import copy
import theano
from theano.tensor import Tensor
from theano.tensor import Tensor, TensorType
from theano.compile.sandbox.sharedvalue import *
from theano.compile.sharedvalue import *
class Test_SharedVariable(unittest.TestCase):
......
......@@ -17,6 +17,7 @@ random = RandomStreams(seed=0xBAD5EED)
from elemwise import \
DimShuffle, Elemwise, CAReduce
import sharedvar # adds shared-variable constructors
......
......@@ -4,10 +4,9 @@ __docformat__ = "restructuredtext en"
import sys
import numpy
from ...gof import Container
from ...tensor import raw_random
from sharedvalue import SharedVariable, shared_constructor, shared
from ..gof import Container
from ..compile.sharedvalue import SharedVariable, shared_constructor, shared
import raw_random
class RandomStateSharedVariable(SharedVariable):
pass
......
......@@ -9,9 +9,9 @@ from unittest import TestCase
from theano.tests import unittest_tools
from copy import copy
from theano import In, Out
from theano import Param, shared
from test_basic import (_approx_eq, as_tensor_variable, inplace_func,
compile, value, constant, inplace, eval_outputs)
compile, constant, inplace, eval_outputs)
class t_gemm(TestCase):
"""This test suite is supposed to establish that gemm works as it is supposed to."""
......@@ -138,12 +138,12 @@ class t_gemm(TestCase):
def test_destroy_map4(self):
"""test that dot args can be aliased"""
Z = value(self.rand(2,2))
A = value(self.rand(2,2))
f = inplace_func([A,Z], gemm(Z, 1.0, A, A, 1.0))
f(A.data, Z.data)
f = inplace_func([A,Z], gemm(Z, 1.0, A, A.T, 1.0))
f(A.data, Z.data)
Z = shared(self.rand(2,2))
A = shared(self.rand(2,2))
f = inplace_func([], gemm(Z, 1.0, A, A, 1.0))
f()
f = inplace_func([], gemm(Z, 1.0, A, A.T, 1.0))
f()
def test_transposes(self):
# three square matrices which are not contiguous
......@@ -156,14 +156,27 @@ class t_gemm(TestCase):
z_orig = z.copy()
z_after = self._gemm(z, a, x, y, b)
tz,ta,tx,ty,tb = [value(p) for p in z,a,x,y,b]
tz,ta,tx,ty,tb = [shared(p) for p in z,a,x,y,b]
f = inplace_func([tz,ta,tx,ty,tb], gemm(tz,ta,tx,ty,tb), mode = compile.Mode(optimizer = None, linker=l))
f(z, a, x, y, b)
#f = inplace_func([tz,ta,tx,ty,tb], gemm(tz,ta,tx,ty,tb), mode = compile.Mode(optimizer = None, linker=l))
#f(z, a, x, y, b)
f = inplace_func([], gemm(tz,ta,tx,ty,tb), mode = compile.Mode(optimizer = None, linker=l))
f()
self.failUnless(_approx_eq(z_after, z), (z_orig, z_after, z, z_after - z))
f()
self.failUnless(_approx_eq(z_after, z), (z_orig, z_after, z, z_after - z))
f()
self.failUnless(_approx_eq(z_after, z), (z_orig, z_after, z, z_after - z))
f(z.T, a, y.T, x.T, b)
self.failUnless(_approx_eq(z_after, z))
#tz.value *= 0 # clear z's value
y_T = ty.value.T
ty.value = tx.value.T
tx.value = y_T
f()
assert numpy.all(tz.value == z) # should be aliased still
# test that the transposed version of multiplication gives same answer
self.failUnless(_approx_eq(z_after, z.T))
t(C,A,B)
t(C.T, A, B)
......@@ -256,7 +269,7 @@ class Warning(Exception):
def just_gemm(i, o, ishapes = [(4,3), (3,5), (4,5), (), ()]):
try:
f = inplace_func([In(ii, mutable=True) for ii in i],o, mode='FAST_RUN')
f = inplace_func([Param(ii, mutable=True) for ii in i],o, mode='FAST_RUN')
for node in f.maker.env.nodes:
if node.op == T.dot: raise Warning('dot not changed to gemm in graph')
if node.op == _dot22: raise Warning('_dot22 not changed to gemm in graph')
......@@ -320,7 +333,7 @@ def test_gemm_opt_double_gemm():
i = [X,Y,Z,a,b, R, S, c]
o = [a * T.dot(X,Y) + gemm(Z, b, S.T, R.T, 1.0)]
try:
f = inplace_func([In(ii, mutable=True) for ii in i],o, mode='FAST_RUN')
f = inplace_func([Param(ii, mutable=True) for ii in i],o, mode='FAST_RUN')
for node in f.maker.env.nodes:
if node.op == T.dot: raise Failure('dot in graph')
if node.op == _dot22: raise Failure('_dot22 in graph')
......
## PENDING REWRITE OF tensor_opt.py
import numpy
import theano
from theano import gof
from theano.tensor.opt import *
from theano import tensor
from theano.tensor import TensorType
from theano.gof import Env
from theano.tensor.elemwise import DimShuffle
from theano import pprint
import numpy
from theano import pprint, shared
#import scalar_opt
from theano import function, compile
......@@ -808,10 +810,6 @@ def test_const_type_in_mul_canonizer():
assert numpy.allclose(
f2(ival, wval, visbval, hidbval, betaval, aval),
f1(ival, wval, visbval, hidbval, betaval, aval))
from theano.compile.sandbox.pfunc import pfunc
from theano.compile.sandbox.sharedvalue import shared
import theano
class test_fusion(unittest.TestCase):
......@@ -951,7 +949,7 @@ class test_fusion(unittest.TestCase):
nb_repeat=1
else:
out=shared_fn(numpy.zeros(shp, dtype=out_dtype),'out')
f = pfunc(sym_inputs,[],updates=[(out,out+g)],mode=mode)
f = function(sym_inputs,[],updates=[(out,out+g)],mode=mode)
#pre-call to have the data in cache if it fit to don't penalise the first iteration
# if id==0:
# f(*val_inputs)
......@@ -1084,9 +1082,9 @@ class test_fusion(unittest.TestCase):
# v1=weakref.ref(v)
out=shared_fn(v,'out')
pdb.set_trace()
# f = pfunc(sym_inputs,[],updates=[(out,out+g)],mode=mode)
# f = pfunc([fx],[],updates=[(out,out+fx)],mode=mode)
# f = pfunc([fx],out+fx,mode=mode)
# f = function(sym_inputs,[],updates=[(out,out+g)],mode=mode)
# f = function([fx],[],updates=[(out,out+fx)],mode=mode)
# f = function([fx],out+fx,mode=mode)
# f = compile.function([fx,out],[out+fx],mode=mode)#no memory leak.
f = compile.function([fx,compile.In(variable=out, value=out.container, mutable=None)],
[out+fx],mode=mode)#if mutable is True or False, their is a memory leak
......
......@@ -5,8 +5,8 @@ import unittest
import numpy
from theano.tensor import raw_random
from theano.compile.sandbox.shared_randomstreams import RandomStreams
from theano.compile.sandbox.pfunc import pfunc
from theano.tensor.shared_randomstreams import RandomStreams
from theano.compile.pfunc import pfunc
from theano import tensor
from theano import compile, gof
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论