提交 42f2a52e authored 作者: James Bergstra's avatar James Bergstra

merge of pfunc & shared

......@@ -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('outputs must be a theano Variable instance or list of.', 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 (or list of them)', outputs)
# Add update values as quantities that must be computed.
# Here, we
......@@ -188,14 +202,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(
......@@ -205,7 +220,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):
......
......@@ -22,7 +22,7 @@ THEANO_BASE_COMPILEDIR = os.getenv('THEANO_BASE_COMPILEDIR', None)
HOME = os.getenv('HOME')
#0 compare with default precission, 1 less precission, 2 event less.
THEANO_CMP_SLOPPY = os.getenv('THEANO_CMP_SLOPPY', 0)
THEANO_CMP_SLOPPY = int(os.getenv('THEANO_CMP_SLOPPY', 0))
#flag for compiling with an optimized blas library. Used for gemm operation
#if THEANO_BLAS_LDFLAGS exist but empty, we will use numpy.dot()
......
"""Provide xscalar, xvector, xmatrix, etc. pseudo-types
"""
import theano.config as config
from theano.scalar import float32, float64
from theano.tensor import fscalar, fvector, fmatrix, frow, fcol, ftensor3, ftensor4, dscalar, dvector, dmatrix, drow, dcol, dtensor3, dtensor4
from theano.tensor import (fscalar, fvector, fmatrix, frow, fcol, ftensor3, ftensor4, dscalar,
dvector, dmatrix, drow, dcol, dtensor3, dtensor4)
#
# !!! set_floatX adds symbols directly to the module's symbol table !!!
#
def set_floatX(dtype = config.floatX):
""" add the xmatrix, xvector, xscalar etc. aliases to theano.tensor
......@@ -14,7 +21,6 @@ def set_floatX(dtype = config.floatX):
globals()['floatX'] = globals()[dtype]
# convert_to_floatX = Cast(floatX, name='convert_to_floatX')
#tensor.tensor stuff
for symbol in ('scalar', 'vector', 'matrix', 'row', 'col','tensor3','tensor4'):
globals()['x'+symbol] = globals()[prefix+symbol]
......
......@@ -17,6 +17,7 @@ random = RandomStreams(seed=0xBAD5EED)
from elemwise import \
DimShuffle, Elemwise, CAReduce
import sharedvar # adds shared-variable constructors
......
......@@ -5,9 +5,8 @@ import sys
import numpy
from theano.gof import Container
from theano.tensor import raw_random
from sharedvalue import SharedVariable, shared_constructor, shared
from theano.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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论