@@ -350,6 +350,8 @@ def __init__(self):
350350 self ._tensors = []
351351 self ._trainable_variables = []
352352 self ._all_variables = []
353+ # Maps a name used in the graph to the next id to use for that name.
354+ self ._names_in_use = {}
353355
354356 def __repr__ (self ):
355357 return self .to_string
@@ -374,6 +376,37 @@ def all_variables(self):
374376 def to_string (self ):
375377 return "\n " .join ([op .to_string for op in self .operations ])
376378
379+ def unique_name (self , name , mark_as_used = True ):
380+ """Like tf.Graph.unique_name, returns a unique operation name for `name`.
381+
382+ Args:
383+ name: The name for an operation.
384+ mark_as_used: whether to mark this name as being used.
385+
386+ Returns:
387+ A string to use as the name for the operation.
388+ """
389+ scope_name = tf .get_variable_scope ().name
390+ if scope_name :
391+ name = scope_name + "/" + name
392+
393+ # As in TensorFlow, treat names as case insensitive when deciding whether
394+ # they are in use.
395+ name_key = name .lower ()
396+ i = self ._names_in_use .get (name_key , 0 )
397+ if mark_as_used :
398+ self ._names_in_use [name_key ] = i + 1
399+ if i > 0 :
400+ base_name_key = name_key
401+ while name_key in self ._names_in_use :
402+ name_key = "%s_%d" % (base_name_key , i )
403+ i += 1
404+ if mark_as_used :
405+ self ._names_in_use [name_key ] = 1
406+ name = "%s_%d" % (name , i - 1 )
407+
408+ return name
409+
377410
378411class Lowering (object ):
379412 """Lowering of a Graph from Mesh-TensorFlow to TensorFlow.
@@ -1143,10 +1176,7 @@ def __init__(self, inputs, mesh=None, name=None):
11431176 self ._outputs = []
11441177 self ._mesh = mesh
11451178 assert name is not None
1146- scope_name = tf .get_variable_scope ().name
1147- if scope_name :
1148- name = scope_name + "/" + name
1149- self ._name = name
1179+ self ._name = mesh .graph .unique_name (name )
11501180 mesh .graph .operations .append (self )
11511181
11521182 @property
0 commit comments