提交 2f95561e authored 作者: James Bergstra's avatar James Bergstra

added profile param to function

* * * added profile param support to function * * * added profile param support to pfunc * * * profile argument support in DebugMode
上级 754d4dd6
"""Provides `DebugMode`, an evaluation mode for debugging theano internals.""" """Provides `DebugMode`, an evaluation mode for debugging theano internals.
:TODO: add support for Cond Op, LazyLinker, PureOp, etc.
"""
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
import time, copy, sys, copy_reg, gc, os import time, copy, sys, copy_reg, gc, os
...@@ -1552,7 +1556,8 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions ...@@ -1552,7 +1556,8 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions
def __init__(self, inputs, outputs, optimizer, mode, def __init__(self, inputs, outputs, optimizer, mode,
accept_inplace = False, accept_inplace = False,
function_builder = Function): function_builder = Function,
profile=None):
""" """
:type inputs: a list of SymbolicInput instances :type inputs: a list of SymbolicInput instances
...@@ -1567,7 +1572,7 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions ...@@ -1567,7 +1572,7 @@ class _Maker(FunctionMaker): #inheritance buys a few helper functions
:note: this function sets TensorType.filter_checks_isfinite when `mode.check_isfinite` is True :note: this function sets TensorType.filter_checks_isfinite when `mode.check_isfinite` is True
""" """
self.profile = profile
# Handle the case where inputs and/or outputs is a single Variable (not in a list) # Handle the case where inputs and/or outputs is a single Variable (not in a list)
unpack_single = False unpack_single = False
return_none = False return_none = False
......
...@@ -7,12 +7,13 @@ _logger = logging.getLogger('theano.compile.function') ...@@ -7,12 +7,13 @@ _logger = logging.getLogger('theano.compile.function')
from io import In from io import In
from function_module import orig_function from function_module import orig_function
from profiling import ProfileStats
from pfunc import pfunc from pfunc import pfunc
from numpy import any #for to work in python 2.4 from numpy import any #for to work in python 2.4
def function(inputs, outputs=None, mode=None, updates=[], givens=[], def function(inputs, outputs=None, mode=None, updates=[], givens=[],
no_default_updates=False, accept_inplace=False, name=None, no_default_updates=False, accept_inplace=False, name=None,
rebuild_strict=True, allow_input_downcast=None): rebuild_strict=True, allow_input_downcast=None, profile=None):
""" """
Return a callable object that will calculate `outputs` from `inputs`. Return a callable object that will calculate `outputs` from `inputs`.
...@@ -62,6 +63,11 @@ def function(inputs, outputs=None, mode=None, updates=[], givens=[], ...@@ -62,6 +63,11 @@ def function(inputs, outputs=None, mode=None, updates=[], givens=[],
precise, type. None (default) is almost like False, but allows precise, type. None (default) is almost like False, but allows
downcasting of Python float scalars to floatX. downcasting of Python float scalars to floatX.
:type profile: None, True, or ProfileStats instance
:param profile: accumulate profiling information into a given ProfileStats
instance. If argument is `True` then a new ProfileStats instance will be
used. This profiling object will be available via self.profile.
:note: Regarding givens: Be careful to make sure that these substitutions are :note: Regarding givens: Be careful to make sure that these substitutions are
independent--behaviour when Var1 of one pair appears in the graph leading to Var2 in independent--behaviour when Var1 of one pair appears in the graph leading to Var2 in
another expression is undefined. Replacements specified with givens are different from another expression is undefined. Replacements specified with givens are different from
...@@ -88,6 +94,8 @@ def function(inputs, outputs=None, mode=None, updates=[], givens=[], ...@@ -88,6 +94,8 @@ def function(inputs, outputs=None, mode=None, updates=[], givens=[],
if uses_In or uses_tuple: if uses_In or uses_tuple:
# we must use old semantics in this case. # we must use old semantics in this case.
if profile:
raise NotImplementedError('profiling not supported in old-style function')
if uses_updates or uses_givens: if uses_updates or uses_givens:
raise NotImplementedError("In() instances and tuple inputs triggers the old semantics, which disallow using updates and givens") raise NotImplementedError("In() instances and tuple inputs triggers the old semantics, which disallow using updates and givens")
fn = orig_function(inputs, outputs, fn = orig_function(inputs, outputs,
...@@ -102,7 +110,8 @@ def function(inputs, outputs=None, mode=None, updates=[], givens=[], ...@@ -102,7 +110,8 @@ def function(inputs, outputs=None, mode=None, updates=[], givens=[],
no_default_updates=no_default_updates, no_default_updates=no_default_updates,
accept_inplace=accept_inplace,name=name, accept_inplace=accept_inplace,name=name,
rebuild_strict=rebuild_strict, rebuild_strict=rebuild_strict,
allow_input_downcast=allow_input_downcast) allow_input_downcast=allow_input_downcast,
profile=profile)
# We need to add the flag check_aliased inputs if we have any mutable or # We need to add the flag check_aliased inputs if we have any mutable or
# borrowed used defined inputs # borrowed used defined inputs
fn._check_for_aliased_inputs = check_for_aliased_inputs fn._check_for_aliased_inputs = check_for_aliased_inputs
......
"""Provide a simple user friendly API """ """Provide a simple user friendly API """
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import numpy # for backport to 2.4, to get any().
from profiling import ProfileStats
from theano.gof import Container, Variable, generic, graph, Constant, Value from theano.gof import Container, Variable, generic, graph, Constant, Value
from theano.compile import orig_function, In, Out from theano.compile import orig_function, In, Out
from theano.compile.sharedvalue import SharedVariable, shared from theano.compile.sharedvalue import SharedVariable, shared
import numpy # for backport to 2.4, to get any(). from theano import config
def rebuild_collect_shared( outputs def rebuild_collect_shared( outputs
, inputs = None , inputs = None
...@@ -292,7 +295,8 @@ class Param(object): ...@@ -292,7 +295,8 @@ class Param(object):
def pfunc(params, outputs=None, mode=None, updates=[], givens=[], def pfunc(params, outputs=None, mode=None, updates=[], givens=[],
no_default_updates=False, accept_inplace=False, name=None, no_default_updates=False, accept_inplace=False, name=None,
rebuild_strict=True, allow_input_downcast=None): rebuild_strict=True, allow_input_downcast=None,
profile=None):
"""Function-constructor for graphs with shared variables. """Function-constructor for graphs with shared variables.
:type params: list of either Variable or Param instances. :type params: list of either Variable or Param instances.
...@@ -319,11 +323,9 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[], ...@@ -319,11 +323,9 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[],
If False (default), perform them all. Else, perform automatic updates on all Variables If False (default), perform them all. Else, perform automatic updates on all Variables
that are neither in "updates" nor in "no_default_updates". that are neither in "updates" nor in "no_default_updates".
:param name: an optional name for this fct. If used, the profile mode will print the time spent in this fct. :type name: None or string
:param name: attaches a name to the Profiling result of this function when
:rtype: theano.compile.Function using ProfileMode (will be deprecated).
:returns: a callable object that will compute the outputs (given the inputs)
and update the implicit function arguments according to the `updates`.
:type allow_input_downcast: Boolean :type allow_input_downcast: Boolean
:param allow_input_downcast: True means that the values passed as :param allow_input_downcast: True means that the values passed as
...@@ -333,6 +335,21 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[], ...@@ -333,6 +335,21 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[],
precise, type. None (default) is almost like False, but allows precise, type. None (default) is almost like False, but allows
downcasting of Python float scalars to floatX. downcasting of Python float scalars to floatX.
:type profile: None, True, str, or ProfileStats instance
:param profile: accumulate profiling information into a given ProfileStats
instance. None is the default, and means to use the value of
config.profile.
If argument is `True` then a new ProfileStats instance will be
used. If argument is a string, a new ProfileStats instance will be created
with that string as its `message` attribute. This profiling object will be
available via self.profile.
:rtype: theano.compile.Function
:returns: a callable object that will compute the outputs (given the inputs)
and update the implicit function arguments according to the `updates`.
:note: Regarding givens: Be careful to make sure that these substitutions are :note: Regarding givens: Be careful to make sure that these substitutions are
independent--behaviour when Var1 of one pair appears in the graph leading to Var2 in independent--behaviour when Var1 of one pair appears in the graph leading to Var2 in
another expression is undefined. Replacements specified with givens are different from another expression is undefined. Replacements specified with givens are different from
...@@ -354,6 +371,17 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[], ...@@ -354,6 +371,17 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[],
# Then it clones the outputs and the update expressions. This rebuilds a computation graph # Then it clones the outputs and the update expressions. This rebuilds a computation graph
# from the inputs and the givens. # from the inputs and the givens.
# #
if profile is None:
profile = config.profile
# profile -> True or False
if profile == True:
profile = ProfileStats(message=name)
# profile -> object
if type(profile) == str:
profile = ProfileStats(message=profile)
# profile is typically either False or an object at this point.
# No need to block other objects being passed through though. It might be
# useful.
if not isinstance(params,(list,tuple)): if not isinstance(params,(list,tuple)):
raise Exception("in pfunc() the first argument must be a list or a tuple") raise Exception("in pfunc() the first argument must be a list or a tuple")
...@@ -393,7 +421,7 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[], ...@@ -393,7 +421,7 @@ def pfunc(params, outputs=None, mode=None, updates=[], givens=[],
inputs.append(si) inputs.append(si)
return orig_function(inputs, cloned_outputs, mode, return orig_function(inputs, cloned_outputs, mode,
accept_inplace=accept_inplace, name=name) accept_inplace=accept_inplace, name=name, profile=profile)
def _pfunc_param_to_in(param, strict=False, allow_downcast=None): def _pfunc_param_to_in(param, strict=False, allow_downcast=None):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论