@@ -33,23 +33,29 @@ class DeviceNamePathConversionTest(test_util.TensorFlowTestCase):
3333
3434 def testDeviceNameToDevicePath (self ):
3535 self .assertEqual (
36- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
37- ",job_ps,replica_1,task_2,cpu_0" ,
38- debug_data .device_name_to_device_path ("/job:ps/replica:1/task:2/cpu:0" ))
36+ debug_data .METADATA_FILE_PREFIX
37+ + debug_data .DEVICE_TAG
38+ + ",job_ps,replica_1,task_2,cpu_0" ,
39+ debug_data .device_name_to_device_path ("/job:ps/replica:1/task:2/cpu:0" ),
40+ )
3941
4042 def testDevicePathToDeviceName (self ):
4143 self .assertEqual (
4244 "/job:ps/replica:1/task:2/cpu:0" ,
4345 debug_data .device_path_to_device_name (
44- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
45- ",job_ps,replica_1,task_2,cpu_0" ))
46+ debug_data .METADATA_FILE_PREFIX
47+ + debug_data .DEVICE_TAG
48+ + ",job_ps,replica_1,task_2,cpu_0"
49+ ),
50+ )
4651
4752
4853class HasNanOrInfTest (test_util .TensorFlowTestCase ):
4954
5055 def setUp (self ):
5156 self ._dummy_datum = dummy_datum = debug_data .DebugTensorDatum (
52- "/foo" , "bar_0_DebugIdentity_42" )
57+ "/foo" , "bar_0_DebugIdentity_42"
58+ )
5359
5460 def testNaN (self ):
5561 a = np .array ([np .nan , np .nan , 7.0 ])
@@ -72,14 +78,22 @@ def testEmpty(self):
7278 self .assertFalse (debug_data .has_inf_or_nan (self ._dummy_datum , a ))
7379
7480 def testInconvertibleTensorProto (self ):
75- self .assertFalse (debug_data .has_inf_or_nan (
76- self ._dummy_datum ,
77- debug_data .InconvertibleTensorProto (tensor_pb2 .TensorProto (),
78- initialized = False )))
79- self .assertFalse (debug_data .has_inf_or_nan (
80- self ._dummy_datum ,
81- debug_data .InconvertibleTensorProto (tensor_pb2 .TensorProto (),
82- initialized = True )))
81+ self .assertFalse (
82+ debug_data .has_inf_or_nan (
83+ self ._dummy_datum ,
84+ debug_data .InconvertibleTensorProto (
85+ tensor_pb2 .TensorProto (), initialized = False
86+ ),
87+ )
88+ )
89+ self .assertFalse (
90+ debug_data .has_inf_or_nan (
91+ self ._dummy_datum ,
92+ debug_data .InconvertibleTensorProto (
93+ tensor_pb2 .TensorProto (), initialized = True
94+ ),
95+ )
96+ )
8397
8498 def testDTypeComplexWorks (self ):
8599 a = np .array ([1j , 3j , 3j , 7j ], dtype = np .complex128 )
@@ -109,9 +123,11 @@ class DebugTensorDatumTest(test_util.TensorFlowTestCase):
109123 def testDebugDatum (self ):
110124 dump_root = "/tmp/tfdbg_1"
111125 debug_dump_rel_path = (
112- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
113- ",job_localhost,replica_0,task_0,cpu_0" +
114- "/ns1/ns2/node_a_1_2_DebugIdentity_1472563253536385" )
126+ debug_data .METADATA_FILE_PREFIX
127+ + debug_data .DEVICE_TAG
128+ + ",job_localhost,replica_0,task_0,cpu_0"
129+ + "/ns1/ns2/node_a_1_2_DebugIdentity_1472563253536385"
130+ )
115131
116132 datum = debug_data .DebugTensorDatum (dump_root , debug_dump_rel_path )
117133
@@ -122,19 +138,20 @@ def testDebugDatum(self):
122138 self .assertEqual (1472563253536385 , datum .timestamp )
123139 self .assertEqual ("ns1/ns2/node_a_1:2:DebugIdentity" , datum .watch_key )
124140 self .assertEqual (
125- os .path .join (dump_root , debug_dump_rel_path ), datum .file_path )
141+ os .path .join (dump_root , debug_dump_rel_path ), datum .file_path
142+ )
126143 self .assertEqual (
127144 "{DebugTensorDatum (/job:localhost/replica:0/task:0/cpu:0) "
128- "%s:%d @ %s @ %d}" % ( datum . node_name ,
129- datum .output_slot ,
130- datum . debug_op ,
131- datum . timestamp ), str ( datum ) )
145+ "%s:%d @ %s @ %d}"
146+ % ( datum . node_name , datum . output_slot , datum . debug_op , datum .timestamp ) ,
147+ str ( datum ) ,
148+ )
132149 self .assertEqual (
133150 "{DebugTensorDatum (/job:localhost/replica:0/task:0/cpu:0) "
134- "%s:%d @ %s @ %d}" % ( datum . node_name ,
135- datum .output_slot ,
136- datum . debug_op ,
137- datum . timestamp ), repr ( datum ) )
151+ "%s:%d @ %s @ %d}"
152+ % ( datum . node_name , datum . output_slot , datum . debug_op , datum .timestamp ) ,
153+ repr ( datum ) ,
154+ )
138155
139156 def testDumpSizeBytesIsNoneForNonexistentFilePath (self ):
140157 dump_root = "/tmp/tfdbg_1"
@@ -156,25 +173,37 @@ def tearDown(self):
156173 def _makeDataDirWithMultipleDevicesAndDuplicateNodeNames (self ):
157174 cpu_0_dir = os .path .join (
158175 self ._dump_root ,
159- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
160- ",job_localhost,replica_0,task_0,cpu_0" )
176+ debug_data .METADATA_FILE_PREFIX
177+ + debug_data .DEVICE_TAG
178+ + ",job_localhost,replica_0,task_0,cpu_0" ,
179+ )
161180 gpu_0_dir = os .path .join (
162181 self ._dump_root ,
163- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
164- ",job_localhost,replica_0,task_0,device_GPU_0" )
182+ debug_data .METADATA_FILE_PREFIX
183+ + debug_data .DEVICE_TAG
184+ + ",job_localhost,replica_0,task_0,device_GPU_0" ,
185+ )
165186 gpu_1_dir = os .path .join (
166187 self ._dump_root ,
167- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
168- ",job_localhost,replica_0,task_0,device_GPU_1" )
188+ debug_data .METADATA_FILE_PREFIX
189+ + debug_data .DEVICE_TAG
190+ + ",job_localhost,replica_0,task_0,device_GPU_1" ,
191+ )
169192 os .makedirs (cpu_0_dir )
170193 os .makedirs (gpu_0_dir )
171194 os .makedirs (gpu_1_dir )
172- open (os .path .join (
173- cpu_0_dir , "node_foo_1_2_DebugIdentity_1472563253536386" ), "wb" )
174- open (os .path .join (
175- gpu_0_dir , "node_foo_1_2_DebugIdentity_1472563253536385" ), "wb" )
176- open (os .path .join (
177- gpu_1_dir , "node_foo_1_2_DebugIdentity_1472563253536387" ), "wb" )
195+ open (
196+ os .path .join (cpu_0_dir , "node_foo_1_2_DebugIdentity_1472563253536386" ),
197+ "wb" ,
198+ )
199+ open (
200+ os .path .join (gpu_0_dir , "node_foo_1_2_DebugIdentity_1472563253536385" ),
201+ "wb" ,
202+ )
203+ open (
204+ os .path .join (gpu_1_dir , "node_foo_1_2_DebugIdentity_1472563253536387" ),
205+ "wb" ,
206+ )
178207
179208 def testDebugDumpDir_nonexistentDumpRoot (self ):
180209 with self .assertRaisesRegex (IOError , "does not exist" ):
@@ -184,13 +213,16 @@ def testDebugDumpDir_invalidFileNamingPattern(self):
184213 # File name with too few underscores should lead to an exception.
185214 device_dir = os .path .join (
186215 self ._dump_root ,
187- debug_data .METADATA_FILE_PREFIX + debug_data .DEVICE_TAG +
188- ",job_localhost,replica_0,task_0,cpu_0" )
216+ debug_data .METADATA_FILE_PREFIX
217+ + debug_data .DEVICE_TAG
218+ + ",job_localhost,replica_0,task_0,cpu_0" ,
219+ )
189220 os .makedirs (device_dir )
190221 open (os .path .join (device_dir , "node1_DebugIdentity_1234" ), "wb" )
191222
192- with self .assertRaisesRegex (ValueError ,
193- "does not conform to the naming pattern" ):
223+ with self .assertRaisesRegex (
224+ ValueError , "does not conform to the naming pattern"
225+ ):
194226 debug_data .DebugDumpDir (self ._dump_root )
195227
196228 def testDebugDumpDir_validDuplicateNodeNamesWithMultipleDevices (self ):
@@ -214,22 +246,29 @@ def testDebugDumpDir_validDuplicateNodeNamesWithMultipleDevices(self):
214246
215247 dump_dir = debug_data .DebugDumpDir (
216248 self ._dump_root ,
217- partition_graphs = [graph_cpu_0 , graph_gpu_0 , graph_gpu_1 ])
218-
219- self .assertItemsEqual (
220- ["/job:localhost/replica:0/task:0/cpu:0" ,
221- "/job:localhost/replica:0/task:0/device:GPU:0" ,
222- "/job:localhost/replica:0/task:0/device:GPU:1" ], dump_dir .devices ())
249+ partition_graphs = [graph_cpu_0 , graph_gpu_0 , graph_gpu_1 ],
250+ )
251+
252+ self .assertCountEqual (
253+ [
254+ "/job:localhost/replica:0/task:0/cpu:0" ,
255+ "/job:localhost/replica:0/task:0/device:GPU:0" ,
256+ "/job:localhost/replica:0/task:0/device:GPU:1" ,
257+ ],
258+ dump_dir .devices (),
259+ )
223260 self .assertEqual (1472563253536385 , dump_dir .t0 )
224261 self .assertEqual (3 , dump_dir .size )
225262
226263 with self .assertRaisesRegex (ValueError , r"Invalid device name: " ):
227264 dump_dir .nodes ("/job:localhost/replica:0/task:0/device:GPU:2" )
228- self .assertItemsEqual (["node_foo_1" , "node_foo_1" , "node_foo_1" ],
229- dump_dir .nodes ())
230- self .assertItemsEqual (
265+ self .assertCountEqual (
266+ ["node_foo_1" , "node_foo_1" , "node_foo_1" ], dump_dir .nodes ()
267+ )
268+ self .assertCountEqual (
231269 ["node_foo_1" ],
232- dump_dir .nodes (device_name = "/job:localhost/replica:0/task:0/cpu:0" ))
270+ dump_dir .nodes (device_name = "/job:localhost/replica:0/task:0/cpu:0" ),
271+ )
233272
234273 def testDuplicateNodeNamesInGraphDefOfSingleDeviceRaisesException (self ):
235274 self ._makeDataDirWithMultipleDevicesAndDuplicateNodeNames ()
@@ -256,7 +295,8 @@ def testDuplicateNodeNamesInGraphDefOfSingleDeviceRaisesException(self):
256295 with self .assertRaisesRegex (ValueError , r"Duplicate node name on device " ):
257296 debug_data .DebugDumpDir (
258297 self ._dump_root ,
259- partition_graphs = [graph_cpu_0 , graph_gpu_0 , graph_gpu_1 ])
298+ partition_graphs = [graph_cpu_0 , graph_gpu_0 , graph_gpu_1 ],
299+ )
260300
261301 def testDebugDumpDir_emptyDumpDir (self ):
262302 dump_dir = debug_data .DebugDumpDir (self ._dump_root )
@@ -275,27 +315,77 @@ def fake_gfile_glob(glob_pattern):
275315 return []
276316
277317 with test .mock .patch .object (
278- gfile , "Glob" , side_effect = fake_gfile_glob , autospec = True ) as fake :
318+ gfile , "Glob" , side_effect = fake_gfile_glob , autospec = True
319+ ) as fake :
279320 debug_data .DebugDumpDir (self ._dump_root )
280321 expected_calls = [
281- test .mock .call (os .path .join (
282- self ._dump_root ,
283- (debug_data .METADATA_FILE_PREFIX +
284- debug_data .CORE_METADATA_TAG + "*" ))),
285- test .mock .call (os .path .join (
286- self ._dump_root ,
287- (debug_data .METADATA_FILE_PREFIX +
288- debug_data .FETCHES_INFO_FILE_TAG + "*" ))),
289- test .mock .call (os .path .join (
290- self ._dump_root ,
291- (debug_data .METADATA_FILE_PREFIX +
292- debug_data .FEED_KEYS_INFO_FILE_TAG + "*" ))),
293- test .mock .call (os .path .join (
294- self ._dump_root ,
295- (debug_data .METADATA_FILE_PREFIX +
296- debug_data .DEVICE_TAG + "*" )))]
322+ test .mock .call (
323+ os .path .join (
324+ self ._dump_root ,
325+ (
326+ debug_data .METADATA_FILE_PREFIX
327+ + debug_data .CORE_METADATA_TAG
328+ + "*"
329+ ),
330+ )
331+ ),
332+ test .mock .call (
333+ os .path .join (
334+ self ._dump_root ,
335+ (
336+ debug_data .METADATA_FILE_PREFIX
337+ + debug_data .FETCHES_INFO_FILE_TAG
338+ + "*"
339+ ),
340+ )
341+ ),
342+ test .mock .call (
343+ os .path .join (
344+ self ._dump_root ,
345+ (
346+ debug_data .METADATA_FILE_PREFIX
347+ + debug_data .FEED_KEYS_INFO_FILE_TAG
348+ + "*"
349+ ),
350+ )
351+ ),
352+ test .mock .call (
353+ os .path .join (
354+ self ._dump_root ,
355+ (
356+ debug_data .METADATA_FILE_PREFIX
357+ + debug_data .DEVICE_TAG
358+ + "*"
359+ ),
360+ )
361+ ),
362+ ]
297363 fake .assert_has_calls (expected_calls , any_order = True )
298364
365+ def testValidationSucceedsOnDoubleSlashNodeName (self ):
366+ device_dir = os .path .join (
367+ self ._dump_root ,
368+ debug_data .device_name_to_device_path (
369+ "/job:localhost/replica:0/task:0/cpu:0"
370+ ),
371+ )
372+ node_scope_dir = os .path .join (device_dir , "scope_A" )
373+ os .makedirs (node_scope_dir )
374+ file_io .write_string_to_file (
375+ os .path .join (node_scope_dir , "op_B_0_DebugIdentity_12345" ), "dummy"
376+ )
377+ graph_def = graph_pb2 .GraphDef ()
378+ node = graph_def .node .add ()
379+ # Previously double slash would have caused validation to fail. b/429335661
380+ node .name = "scope_A//op_B"
381+ node .op = "NoOp"
382+ node .device = "/job:localhost/replica:0/task:0/cpu:0"
383+ dump_dir = debug_data .DebugDumpDir (
384+ self ._dump_root , partition_graphs = [graph_def ]
385+ )
386+ self .assertEqual (1 , dump_dir .size )
387+ self .assertIn ("scope_A/op_B" , dump_dir .nodes ()[0 ])
388+
299389
300390if __name__ == "__main__" :
301391 googletest .main ()
0 commit comments