提交 0ffd130e authored 作者: Frédéric Bastien's avatar Frédéric Bastien 提交者: GitHub

Merge pull request #5796 from notoraptor/improve-theano-cache-list

Print compilation count for all compiled Op classes with "theano-cache list" command
...@@ -93,6 +93,15 @@ def cleanup(): ...@@ -93,6 +93,15 @@ def cleanup():
file.close() file.close()
def print_title(title, overline='', underline=''):
len_title = len(title)
if overline:
print(str(overline) * len_title)
print(title)
if underline:
print(str(underline) * len_title)
def print_compiledir_content(): def print_compiledir_content():
""" """
print list of %d compiled individual ops in the "theano.config.compiledir" print list of %d compiled individual ops in the "theano.config.compiledir"
...@@ -101,7 +110,8 @@ def print_compiledir_content(): ...@@ -101,7 +110,8 @@ def print_compiledir_content():
compiledir = theano.config.compiledir compiledir = theano.config.compiledir
table = [] table = []
more_than_one_ops = 0 table_multiple_ops = []
table_op_class = {}
zeros_op = 0 zeros_op = 0
big_key_files = [] big_key_files = []
total_key_sizes = 0 total_key_sizes = 0
...@@ -115,10 +125,12 @@ def print_compiledir_content(): ...@@ -115,10 +125,12 @@ def print_compiledir_content():
keydata = pickle.load(file) keydata = pickle.load(file)
ops = list(set([x for x in flatten(keydata.keys) ops = list(set([x for x in flatten(keydata.keys)
if isinstance(x, theano.gof.Op)])) if isinstance(x, theano.gof.Op)]))
# Whatever the case, we count compilations for OP classes.
for op_class in set([op.__class__ for op in ops]):
table_op_class.setdefault(op_class, 0)
table_op_class[op_class] += 1
if len(ops) == 0: if len(ops) == 0:
zeros_op += 1 zeros_op += 1
elif len(ops) > 1:
more_than_one_ops += 1
else: else:
types = list(set([x for x in flatten(keydata.keys) types = list(set([x for x in flatten(keydata.keys)
if isinstance(x, theano.gof.Type)])) if isinstance(x, theano.gof.Type)]))
...@@ -131,7 +143,12 @@ def print_compiledir_content(): ...@@ -131,7 +143,12 @@ def print_compiledir_content():
compile_end = os.path.getmtime( compile_end = os.path.getmtime(
os.path.join(compiledir, dir, fn)) os.path.join(compiledir, dir, fn))
compile_time = compile_end - compile_start compile_time = compile_end - compile_start
table.append((dir, ops[0], types, compile_time)) if len(ops) == 1:
table.append((dir, ops[0], types, compile_time))
else:
ops_to_str = '[%s]' % ', '.join(sorted(str(op) for op in ops))
types_to_str = '[%s]' % ', '.join(sorted(str(t) for t in types))
table_multiple_ops.append((dir, ops_to_str, types_to_str, compile_time))
size = os.path.getsize(filename) size = os.path.getsize(filename)
total_key_sizes += size total_key_sizes += size
...@@ -143,19 +160,25 @@ def print_compiledir_content(): ...@@ -143,19 +160,25 @@ def print_compiledir_content():
except IOError: except IOError:
pass pass
print("List of %d compiled individual ops in this theano cache %s:" % ( print_title("Theano cache: %s" % compiledir, overline='=', underline='=')
len(table), compiledir)) print()
print("sub dir/compiletime/Op/set of different associated Theano types")
print_title("List of %d compiled individual ops" % len(table), underline='+')
print_title("sub dir/compiletime/Op/set of different associated Theano types", underline='-')
table = sorted(table, key=lambda t: str(t[1])) table = sorted(table, key=lambda t: str(t[1]))
table_op_class = {}
for dir, op, types, compile_time in table: for dir, op, types, compile_time in table:
print(dir, '%.3fs' % compile_time, op, types) print(dir, '%.3fs' % compile_time, op, types)
table_op_class.setdefault(op.__class__, 0)
table_op_class[op.__class__] += 1
print() print()
print(("List of %d individual compiled Op classes and " print_title("List of %d compiled sets of ops" % len(table_multiple_ops), underline='+')
"the number of times they got compiled" % len(table_op_class))) print_title("sub dir/compiletime/Set of ops/set of different associated Theano types", underline='-')
table_multiple_ops = sorted(table_multiple_ops, key=lambda t: (t[1], t[2]))
for dir, ops_to_str, types_to_str, compile_time in table_multiple_ops:
print(dir, '%.3fs' % compile_time, ops_to_str, types_to_str)
print()
print_title(("List of %d compiled Op classes and "
"the number of times they got compiled" % len(table_op_class)), underline='+')
table_op_class = sorted(iteritems(table_op_class), key=lambda t: t[1]) table_op_class = sorted(iteritems(table_op_class), key=lambda t: t[1])
for op_class, nb in table_op_class: for op_class, nb in table_op_class:
print(op_class, nb) print(op_class, nb)
...@@ -174,13 +197,11 @@ def print_compiledir_content(): ...@@ -174,13 +197,11 @@ def print_compiledir_content():
nb_keys = sorted(iteritems(nb_keys)) nb_keys = sorted(iteritems(nb_keys))
print() print()
print("Number of keys for a compiled module") print_title("Number of keys for a compiled module", underline='+')
print("number of keys/number of modules with that number of keys") print_title("number of keys/number of modules with that number of keys", underline='-')
for n_k, n_m in nb_keys: for n_k, n_m in nb_keys:
print(n_k, n_m) print(n_k, n_m)
print()
print(("Skipped %d files that contained more than"
" 1 op (was compiled with the C linker)" % more_than_one_ops))
print(("Skipped %d files that contained 0 op " print(("Skipped %d files that contained 0 op "
"(are they always theano.scalar ops?)" % zeros_op)) "(are they always theano.scalar ops?)" % zeros_op))
......
...@@ -209,8 +209,23 @@ class GpuArrayType(Type): ...@@ -209,8 +209,23 @@ class GpuArrayType(Type):
return get_context(self.context_name) return get_context(self.context_name)
def __repr__(self): def __repr__(self):
return "GpuArrayType<%s>(%s, %s)" % (self.context_name, self.dtype, # Inspired from TensorType.
self.broadcastable) if self.name:
return self.name
else:
b = self.broadcastable
named_broadcastable = {tuple(): 'scalar',
(False,): 'vector',
(False, True): 'col',
(True, False): 'row',
(False, False): 'matrix'}
if b in named_broadcastable:
bcast = named_broadcastable[b]
elif any(b):
bcast = str(b)
else:
bcast = '%iD' % len(b)
return "GpuArrayType<%s>(%s, %s)" % (self.context_name, self.dtype, bcast)
def filter(self, data, strict=False, allow_downcast=None): def filter(self, data, strict=False, allow_downcast=None):
return self.filter_inplace(data, None, strict=strict, return self.filter_inplace(data, None, strict=strict,
......
...@@ -373,7 +373,6 @@ class TensorType(Type): ...@@ -373,7 +373,6 @@ class TensorType(Type):
def __repr__(self): def __repr__(self):
return str(self) return str(self)
# "TensorType{%s, %s}" % (str(self.dtype), str(self.broadcastable))
def c_declare(self, name, sub, check_input=True): def c_declare(self, name, sub, check_input=True):
""" """
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论