提交 3e86efec authored 作者: Frédéric Bastien's avatar Frédéric Bastien 提交者: GitHub

Merge pull request #6143 from affanv14/metaopt

Implement Meta-optimizer on new backend
......@@ -1116,3 +1116,26 @@ import theano and print the config variable, as in:
The number of user stack level to keep for variables during Theano
compilation. If higher then 0, will make us keep Theano internal
stack trace.
.. attribute:: config.metaopt.verbose
Int value, default: 0
The verbosity level of the meta-optimizer. 0 for silent.
1 to only warn if we cannot meta-optimize some op.
2 for full output of separate timings and selected implementation
.. attribute:: config.metaopt.optimizer_excluding
Default: ``""``
A list of optimizer tags that we don't want included in the Meta-optimizer.
If multiple tags, separate them by ':'.
.. attribute:: config.metaopt.optimizer_including
Default: ``""``
A list of optimizer tags that we want included in the Meta-optimizer.
If multiple tags, separate them by ':'.
......@@ -1456,8 +1456,21 @@ AddConfigVar('blas.ldflags',
AddConfigVar(
'metaopt.verbose',
"Enable verbose output for meta optimizers",
theano.configparser.BoolParam(False),
"0 for silent, 1 for only warnings, 2 for full output with"
"timings and selected implementation",
theano.configparser.IntParam(0),
in_c_key=False)
AddConfigVar('metaopt.optimizer_excluding',
("exclude optimizers with these tags. "
"Separate tags with ':'."),
StrParam(""),
in_c_key=False)
AddConfigVar('metaopt.optimizer_including',
("include optimizers with these tags. "
"Separate tags with ':'."),
StrParam(""),
in_c_key=False)
AddConfigVar('profile',
......
......@@ -1131,13 +1131,20 @@ class LocalMetaOptimizer(LocalOptimizer):
"""
def __init__(self, tracks=None, optimizers=()):
self._tracks = tracks
self.optimizers = list(optimizers)
def __init__(self):
self.verbose = config.metaopt.verbose
self.track_dict = defaultdict(lambda: [])
self.tag_dict = defaultdict(lambda: [])
self._tracks = []
self.optimizers = []
def register(self, optimizer):
def register(self, optimizer, tag_list):
self.optimizers.append(optimizer)
for c in optimizer.tracks():
self.track_dict[c].append(optimizer)
self._tracks.append(c)
for tag in tag_list:
self.tag_dict[tag].append(optimizer)
def tracks(self):
return self._tracks
......@@ -1167,39 +1174,40 @@ class LocalMetaOptimizer(LocalOptimizer):
missing.difference_update(givens.keys())
# ensure we have data for all input variables that need it
if missing:
if self.verbose:
if self.verbose > 0:
print(("%s cannot meta-optimize %s, "
"%d of %d input shapes unknown" %
(self.__class__.__name__, node, len(missing), node.nin)))
return
# now we can apply the different optimizations in turn,
# compile the resulting subgraphs and time their execution
if self.verbose:
if self.verbose > 1:
print(("%s meta-optimizing %s (%d choices):" %
(self.__class__.__name__, node, len(self.optimizers))))
(self.__class__.__name__, node, len(self.get_opts(node)))))
timings = []
for opt in self.optimizers:
for opt in self.get_opts(node):
outputs = opt.transform(node)
if outputs:
try:
fn = theano.function([], outputs, givens=givens,
on_unused_input='ignore')
timing = min(self.time_call(fn) for _ in range(3))
fn.trust_input = True
timing = min(self.time_call(fn) for _ in range(2))
except Exception as e:
if self.verbose:
if self.verbose > 0:
print("* %s: exception" % opt, e)
continue
else:
if self.verbose:
if self.verbose > 1:
print("* %s: %.5g sec" % (opt, timing))
timings.append((timing, outputs, opt))
else:
if self.verbose:
if self.verbose > 0:
print("* %s: not applicable" % opt)
# finally, we choose the fastest one
if timings:
timings.sort()
if self.verbose:
if self.verbose > 1:
print("= %s" % timings[0][2])
return timings[0][1]
return
......@@ -1213,6 +1221,12 @@ class LocalMetaOptimizer(LocalOptimizer):
"""
raise NotImplementedError()
def get_opts(self, node):
"""
Can be overrided to change the way opts are selected
"""
return self.track_dict[type(node.op)]
def time_call(self, fn):
start = time.time()
fn()
......@@ -2313,7 +2327,6 @@ class EquilibriumOptimizer(NavigatorOptimizer):
self.final_optimizers = []
self.cleanup_optimizers = []
self.tracks_on_change_inputs = tracks_on_change_inputs
for opt in optimizers:
if isinstance(opt, LocalOptimizer):
if opt.tracks() is None:
......
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论