You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_profiling.py 22 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ==============================================================================
  15. """
  16. Testing profiling support in DE
  17. """
  18. import json
  19. import os
  20. import numpy as np
  21. import mindspore.common.dtype as mstype
  22. import mindspore.dataset as ds
  23. import mindspore.dataset.transforms.c_transforms as C
  24. import mindspore.dataset.vision.c_transforms as vision
  25. FILES = ["../data/dataset/testTFTestAllTypes/test.data"]
  26. DATASET_ROOT = "../data/dataset/testTFTestAllTypes/"
  27. SCHEMA_FILE = "../data/dataset/testTFTestAllTypes/datasetSchema.json"
  28. PIPELINE_FILE = "./pipeline_profiling"
  29. CPU_UTIL_FILE = "./minddata_cpu_utilization"
  30. DATASET_ITERATOR_FILE = "./dataset_iterator_profiling"
  31. # add file name to rank id mapping to avoid file writing crash
  32. file_name_map_rank_id = {"test_profiling_simple_pipeline": "0",
  33. "test_profiling_complex_pipeline": "1",
  34. "test_profiling_inline_ops_pipeline1": "2",
  35. "test_profiling_inline_ops_pipeline2": "3",
  36. "test_profiling_sampling_interval": "4",
  37. "test_profiling_basic_pipeline": "5",
  38. "test_profiling_cifar10_pipeline": "6",
  39. "test_profiling_seq_pipelines_epochctrl3": "7",
  40. "test_profiling_seq_pipelines_epochctrl2": "8",
  41. "test_profiling_seq_pipelines_repeat": "9"}
  42. def set_profiling_env_var(index='0'):
  43. """
  44. Set the MindData Profiling environment variables
  45. """
  46. os.environ['PROFILING_MODE'] = 'true'
  47. os.environ['MINDDATA_PROFILING_DIR'] = '.'
  48. os.environ['DEVICE_ID'] = index
  49. os.environ['RANK_ID'] = index
  50. def delete_profiling_files(index='0'):
  51. """
  52. Delete the MindData profiling files generated from the test.
  53. Also disable the MindData Profiling environment variables.
  54. """
  55. # Delete MindData profiling files
  56. pipeline_file = PIPELINE_FILE + "_" + index + ".json"
  57. cpu_util_file = CPU_UTIL_FILE + "_" + index + ".json"
  58. dataset_iterator_file = DATASET_ITERATOR_FILE + "_" + index + ".txt"
  59. os.remove(pipeline_file)
  60. os.remove(cpu_util_file)
  61. os.remove(dataset_iterator_file)
  62. # Disable MindData Profiling environment variables
  63. del os.environ['PROFILING_MODE']
  64. del os.environ['MINDDATA_PROFILING_DIR']
  65. del os.environ['DEVICE_ID']
  66. del os.environ['RANK_ID']
  67. def confirm_cpuutil(num_pipeline_ops, cpu_uti_file):
  68. """
  69. Confirm CPU utilization JSON file with <num_pipeline_ops> in the pipeline
  70. """
  71. with open(cpu_uti_file) as file1:
  72. data = json.load(file1)
  73. op_info = data["op_info"]
  74. assert len(op_info) == num_pipeline_ops
  75. def confirm_ops_in_pipeline(num_ops, op_list, pipeline_file):
  76. """
  77. Confirm pipeline JSON file with <num_ops> are in the pipeline and the given list of ops
  78. """
  79. with open(pipeline_file) as file1:
  80. data = json.load(file1)
  81. op_info = data["op_info"]
  82. # Confirm ops in pipeline file
  83. assert len(op_info) == num_ops
  84. for i in range(num_ops):
  85. assert op_info[i]["op_type"] in op_list
  86. def test_profiling_simple_pipeline():
  87. """
  88. Generator -> Shuffle -> Batch
  89. """
  90. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  91. file_id = file_name_map_rank_id[file_name]
  92. set_profiling_env_var(file_id)
  93. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  94. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  95. dataset_iterator_file = DATASET_ITERATOR_FILE + "_" + file_id + ".txt"
  96. source = [(np.array([x]),) for x in range(1024)]
  97. data1 = ds.GeneratorDataset(source, ["data"])
  98. data1 = data1.shuffle(64)
  99. data1 = data1.batch(32)
  100. # try output shape type and dataset size and make sure no profiling file is generated
  101. assert data1.output_shapes() == [[32, 1]]
  102. assert [str(tp) for tp in data1.output_types()] == ["int64"]
  103. assert data1.get_dataset_size() == 32
  104. # Confirm profiling files do not (yet) exist
  105. assert os.path.exists(pipeline_file) is False
  106. assert os.path.exists(cpu_util_file) is False
  107. assert os.path.exists(dataset_iterator_file) is False
  108. try:
  109. for _ in data1:
  110. pass
  111. # Confirm profiling files now exist
  112. assert os.path.exists(pipeline_file) is True
  113. assert os.path.exists(cpu_util_file) is True
  114. assert os.path.exists(dataset_iterator_file) is True
  115. except Exception as error:
  116. delete_profiling_files(file_id)
  117. raise error
  118. else:
  119. delete_profiling_files(file_id)
  120. def test_profiling_complex_pipeline():
  121. """
  122. Generator -> Map ->
  123. -> Zip
  124. TFReader -> Shuffle ->
  125. """
  126. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  127. file_id = file_name_map_rank_id[file_name]
  128. set_profiling_env_var(file_id)
  129. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  130. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  131. source = [(np.array([x]),) for x in range(1024)]
  132. data1 = ds.GeneratorDataset(source, ["gen"])
  133. data1 = data1.map(operations=[(lambda x: x + 1)], input_columns=["gen"])
  134. pattern = DATASET_ROOT + "/test.data"
  135. data2 = ds.TFRecordDataset(pattern, SCHEMA_FILE, shuffle=ds.Shuffle.FILES)
  136. data2 = data2.shuffle(4)
  137. data3 = ds.zip((data1, data2))
  138. try:
  139. for _ in data3:
  140. pass
  141. with open(pipeline_file) as f:
  142. data = json.load(f)
  143. op_info = data["op_info"]
  144. assert len(op_info) == 5
  145. for i in range(5):
  146. if op_info[i]["op_type"] != "ZipOp":
  147. assert "size" in op_info[i]["metrics"]["output_queue"]
  148. assert "length" in op_info[i]["metrics"]["output_queue"]
  149. else:
  150. # Note: Zip is an inline op and hence does not have metrics information
  151. assert op_info[i]["metrics"] is None
  152. # Confirm CPU util JSON file content, when 5 ops are in the pipeline JSON file
  153. confirm_cpuutil(5, cpu_util_file)
  154. except Exception as error:
  155. delete_profiling_files(file_id)
  156. raise error
  157. else:
  158. delete_profiling_files(file_id)
  159. def test_profiling_inline_ops_pipeline1():
  160. """
  161. Test pipeline with inline ops: Concat and EpochCtrl
  162. Generator ->
  163. Concat -> EpochCtrl
  164. Generator ->
  165. """
  166. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  167. file_id = file_name_map_rank_id[file_name]
  168. set_profiling_env_var(file_id)
  169. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  170. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  171. # In source1 dataset: Number of rows is 3; its values are 0, 1, 2
  172. def source1():
  173. for i in range(3):
  174. yield (np.array([i]),)
  175. # In source2 dataset: Number of rows is 7; its values are 3, 4, 5 ... 9
  176. def source2():
  177. for i in range(3, 10):
  178. yield (np.array([i]),)
  179. data1 = ds.GeneratorDataset(source1, ["col1"])
  180. data2 = ds.GeneratorDataset(source2, ["col1"])
  181. data3 = data1.concat(data2)
  182. try:
  183. num_iter = 0
  184. # Note: set num_epochs=2 in create_tuple_iterator(), so that EpochCtrl op is added to the pipeline
  185. # Here i refers to index, d refers to data element
  186. for i, d in enumerate(data3.create_tuple_iterator(num_epochs=2, output_numpy=True)):
  187. num_iter += 1
  188. t = d
  189. assert i == t[0][0]
  190. assert num_iter == 10
  191. # Confirm pipeline is created with EpochCtrl op
  192. with open(pipeline_file) as f:
  193. data = json.load(f)
  194. op_info = data["op_info"]
  195. assert len(op_info) == 4
  196. for i in range(4):
  197. # Note: The following ops are inline ops: Concat, EpochCtrl
  198. if op_info[i]["op_type"] in ("ConcatOp", "EpochCtrlOp"):
  199. # Confirm these inline ops do not have metrics information
  200. assert op_info[i]["metrics"] is None
  201. else:
  202. assert "size" in op_info[i]["metrics"]["output_queue"]
  203. assert "length" in op_info[i]["metrics"]["output_queue"]
  204. # Confirm CPU util JSON file content, when 4 ops are in the pipeline JSON file
  205. confirm_cpuutil(4, cpu_util_file)
  206. except Exception as error:
  207. delete_profiling_files(file_id)
  208. raise error
  209. else:
  210. delete_profiling_files(file_id)
  211. def test_profiling_inline_ops_pipeline2():
  212. """
  213. Test pipeline with many inline ops
  214. Generator -> Rename -> Skip -> Repeat -> Take
  215. """
  216. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  217. file_id = file_name_map_rank_id[file_name]
  218. set_profiling_env_var(file_id)
  219. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  220. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  221. # In source1 dataset: Number of rows is 10; its values are 0, 1, 2, 3, 4, 5 ... 9
  222. def source1():
  223. for i in range(10):
  224. yield (np.array([i]),)
  225. data1 = ds.GeneratorDataset(source1, ["col1"])
  226. data1 = data1.rename(input_columns=["col1"], output_columns=["newcol1"])
  227. data1 = data1.skip(2)
  228. data1 = data1.repeat(2)
  229. data1 = data1.take(12)
  230. try:
  231. for _ in data1:
  232. pass
  233. with open(pipeline_file) as f:
  234. data = json.load(f)
  235. op_info = data["op_info"]
  236. assert len(op_info) == 5
  237. for i in range(5):
  238. # Check for these inline ops
  239. if op_info[i]["op_type"] in ("RenameOp", "RepeatOp", "SkipOp", "TakeOp"):
  240. # Confirm these inline ops do not have metrics information
  241. assert op_info[i]["metrics"] is None
  242. else:
  243. assert "size" in op_info[i]["metrics"]["output_queue"]
  244. assert "length" in op_info[i]["metrics"]["output_queue"]
  245. # Confirm CPU util JSON file content, when 5 ops are in the pipeline JSON file
  246. confirm_cpuutil(5, cpu_util_file)
  247. except Exception as error:
  248. delete_profiling_files(file_id)
  249. raise error
  250. else:
  251. delete_profiling_files(file_id)
  252. def test_profiling_sampling_interval():
  253. """
  254. Test non-default monitor sampling interval
  255. """
  256. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  257. file_id = file_name_map_rank_id[file_name]
  258. set_profiling_env_var(file_id)
  259. interval_origin = ds.config.get_monitor_sampling_interval()
  260. ds.config.set_monitor_sampling_interval(30)
  261. interval = ds.config.get_monitor_sampling_interval()
  262. assert interval == 30
  263. source = [(np.array([x]),) for x in range(1024)]
  264. data1 = ds.GeneratorDataset(source, ["data"])
  265. data1 = data1.shuffle(64)
  266. data1 = data1.batch(32)
  267. try:
  268. for _ in data1:
  269. pass
  270. except Exception as error:
  271. ds.config.set_monitor_sampling_interval(interval_origin)
  272. delete_profiling_files(file_id)
  273. raise error
  274. else:
  275. ds.config.set_monitor_sampling_interval(interval_origin)
  276. delete_profiling_files(file_id)
  277. def test_profiling_basic_pipeline():
  278. """
  279. Test with this basic pipeline
  280. Generator -> Map -> Batch -> Repeat -> EpochCtrl
  281. """
  282. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  283. file_id = file_name_map_rank_id[file_name]
  284. set_profiling_env_var(file_id)
  285. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  286. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  287. def source1():
  288. for i in range(8000):
  289. yield (np.array([i]),)
  290. # Create this basic and common pipeline
  291. # Leaf/Source-Op -> Map -> Batch -> Repeat
  292. data1 = ds.GeneratorDataset(source1, ["col1"])
  293. type_cast_op = C.TypeCast(mstype.int32)
  294. data1 = data1.map(operations=type_cast_op, input_columns="col1")
  295. data1 = data1.batch(16)
  296. data1 = data1.repeat(2)
  297. try:
  298. num_iter = 0
  299. # Note: If create_dict_iterator() is called with num_epochs>1, then EpochCtrlOp is added to the pipeline
  300. for _ in data1.create_dict_iterator(num_epochs=2):
  301. num_iter += 1
  302. assert num_iter == 1000
  303. with open(pipeline_file) as f:
  304. data = json.load(f)
  305. op_info = data["op_info"]
  306. assert len(op_info) == 5
  307. for i in range(5):
  308. # Check for inline ops
  309. if op_info[i]["op_type"] in ("EpochCtrlOp", "RepeatOp"):
  310. # Confirm these inline ops do not have metrics information
  311. assert op_info[i]["metrics"] is None
  312. else:
  313. assert "size" in op_info[i]["metrics"]["output_queue"]
  314. assert "length" in op_info[i]["metrics"]["output_queue"]
  315. # Confirm CPU util JSON file content, when 5 ops are in the pipeline JSON file
  316. confirm_cpuutil(5, cpu_util_file)
  317. except Exception as error:
  318. delete_profiling_files(file_id)
  319. raise error
  320. else:
  321. delete_profiling_files(file_id)
  322. def test_profiling_cifar10_pipeline():
  323. """
  324. Test with this common pipeline with Cifar10
  325. Cifar10 -> Map -> Map -> Batch -> Repeat
  326. """
  327. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  328. file_id = file_name_map_rank_id[file_name]
  329. set_profiling_env_var(file_id)
  330. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  331. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  332. # Create this common pipeline
  333. # Cifar10 -> Map -> Map -> Batch -> Repeat
  334. DATA_DIR_10 = "../data/dataset/testCifar10Data"
  335. data1 = ds.Cifar10Dataset(DATA_DIR_10, num_samples=8000)
  336. type_cast_op = C.TypeCast(mstype.int32)
  337. data1 = data1.map(operations=type_cast_op, input_columns="label")
  338. random_horizontal_op = vision.RandomHorizontalFlip()
  339. data1 = data1.map(operations=random_horizontal_op, input_columns="image")
  340. data1 = data1.batch(32)
  341. data1 = data1.repeat(3)
  342. try:
  343. num_iter = 0
  344. # Note: If create_dict_iterator() is called with num_epochs=1, then EpochCtrlOp is NOT added to the pipeline
  345. for _ in data1.create_dict_iterator(num_epochs=1):
  346. num_iter += 1
  347. assert num_iter == 750
  348. with open(pipeline_file) as f:
  349. data = json.load(f)
  350. op_info = data["op_info"]
  351. assert len(op_info) == 5
  352. for i in range(5):
  353. # Check for inline ops
  354. if op_info[i]["op_type"] == "RepeatOp":
  355. # Confirm these inline ops do not have metrics information
  356. assert op_info[i]["metrics"] is None
  357. else:
  358. assert "size" in op_info[i]["metrics"]["output_queue"]
  359. assert "length" in op_info[i]["metrics"]["output_queue"]
  360. # Confirm CPU util JSON file content, when 5 ops are in the pipeline JSON file
  361. confirm_cpuutil(5, cpu_util_file)
  362. except Exception as error:
  363. delete_profiling_files(file_id)
  364. raise error
  365. else:
  366. delete_profiling_files(file_id)
  367. def test_profiling_seq_pipelines_epochctrl3():
  368. """
  369. Test with these 2 sequential pipelines:
  370. 1) Generator -> Batch -> EpochCtrl
  371. 2) Generator -> Batch
  372. Note: This is a simplification of the user scenario to use the same pipeline for training and then evaluation.
  373. """
  374. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  375. file_id = file_name_map_rank_id[file_name]
  376. set_profiling_env_var(file_id)
  377. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  378. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  379. source = [(np.array([x]),) for x in range(64)]
  380. data1 = ds.GeneratorDataset(source, ["data"])
  381. data1 = data1.batch(32)
  382. try:
  383. # Test A - Call create_dict_iterator with num_epochs>1
  384. num_iter = 0
  385. # Note: If create_dict_iterator() is called with num_epochs>1, then EpochCtrlOp is added to the pipeline
  386. for _ in data1.create_dict_iterator(num_epochs=2):
  387. num_iter += 1
  388. assert num_iter == 2
  389. # Confirm pipeline file and CPU util file each have 3 ops
  390. confirm_ops_in_pipeline(3, ["GeneratorOp", "BatchOp", "EpochCtrlOp"], pipeline_file)
  391. confirm_cpuutil(3, cpu_util_file)
  392. # Test B - Call create_dict_iterator with num_epochs=1
  393. num_iter = 0
  394. # Note: If create_dict_iterator() is called with num_epochs=1,
  395. # then EpochCtrlOp should not be NOT added to the pipeline
  396. for _ in data1.create_dict_iterator(num_epochs=1):
  397. num_iter += 1
  398. assert num_iter == 2
  399. # Confirm pipeline file and CPU util file each have 2 ops
  400. confirm_ops_in_pipeline(2, ["GeneratorOp", "BatchOp"], pipeline_file)
  401. confirm_cpuutil(2, cpu_util_file)
  402. except Exception as error:
  403. delete_profiling_files(file_id)
  404. raise error
  405. else:
  406. delete_profiling_files(file_id)
  407. def test_profiling_seq_pipelines_epochctrl2():
  408. """
  409. Test with these 2 sequential pipelines:
  410. 1) Generator -> Batch
  411. 2) Generator -> Batch -> EpochCtrl
  412. """
  413. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  414. file_id = file_name_map_rank_id[file_name]
  415. set_profiling_env_var(file_id)
  416. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  417. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  418. source = [(np.array([x]),) for x in range(64)]
  419. data2 = ds.GeneratorDataset(source, ["data"])
  420. data2 = data2.batch(16)
  421. try:
  422. # Test A - Call create_dict_iterator with num_epochs=1
  423. num_iter = 0
  424. # Note: If create_dict_iterator() is called with num_epochs=1, then EpochCtrlOp is NOT added to the pipeline
  425. for _ in data2.create_dict_iterator(num_epochs=1):
  426. num_iter += 1
  427. assert num_iter == 4
  428. # Confirm pipeline file and CPU util file each have 2 ops
  429. confirm_ops_in_pipeline(2, ["GeneratorOp", "BatchOp"], pipeline_file)
  430. confirm_cpuutil(2, cpu_util_file)
  431. # Test B - Call create_dict_iterator with num_epochs>1
  432. num_iter = 0
  433. # Note: If create_dict_iterator() is called with num_epochs>1,
  434. # then EpochCtrlOp should be added to the pipeline
  435. for _ in data2.create_dict_iterator(num_epochs=2):
  436. num_iter += 1
  437. assert num_iter == 4
  438. # Confirm pipeline file and CPU util file each have 3 ops
  439. confirm_ops_in_pipeline(3, ["GeneratorOp", "BatchOp", "EpochCtrlOp"], pipeline_file)
  440. confirm_cpuutil(3, cpu_util_file)
  441. except Exception as error:
  442. delete_profiling_files(file_id)
  443. raise error
  444. else:
  445. delete_profiling_files(file_id)
  446. def test_profiling_seq_pipelines_repeat():
  447. """
  448. Test with these 2 sequential pipelines:
  449. 1) Generator -> Batch
  450. 2) Generator -> Batch -> Repeat
  451. """
  452. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  453. file_id = file_name_map_rank_id[file_name]
  454. set_profiling_env_var(file_id)
  455. pipeline_file = PIPELINE_FILE + "_" + file_id + ".json"
  456. cpu_util_file = CPU_UTIL_FILE + "_" + file_id + ".json"
  457. source = [(np.array([x]),) for x in range(64)]
  458. data2 = ds.GeneratorDataset(source, ["data"])
  459. data2 = data2.batch(16)
  460. try:
  461. # Test A - Call create_dict_iterator with 2 ops in pipeline
  462. num_iter = 0
  463. for _ in data2.create_dict_iterator(num_epochs=1):
  464. num_iter += 1
  465. assert num_iter == 4
  466. # Confirm pipeline file and CPU util file each have 2 ops
  467. confirm_ops_in_pipeline(2, ["GeneratorOp", "BatchOp"], pipeline_file)
  468. confirm_cpuutil(2, cpu_util_file)
  469. # Test B - Add repeat op to pipeline. Call create_dict_iterator with 3 ops in pipeline
  470. data2 = data2.repeat(5)
  471. num_iter = 0
  472. for _ in data2.create_dict_iterator(num_epochs=1):
  473. num_iter += 1
  474. assert num_iter == 20
  475. # Confirm pipeline file and CPU util file each have 3 ops
  476. confirm_ops_in_pipeline(3, ["GeneratorOp", "BatchOp", "RepeatOp"], pipeline_file)
  477. confirm_cpuutil(3, cpu_util_file)
  478. except Exception as error:
  479. delete_profiling_files(file_id)
  480. raise error
  481. else:
  482. delete_profiling_files(file_id)
  483. if __name__ == "__main__":
  484. test_profiling_simple_pipeline()
  485. test_profiling_complex_pipeline()
  486. test_profiling_inline_ops_pipeline1()
  487. test_profiling_inline_ops_pipeline2()
  488. test_profiling_sampling_interval()
  489. test_profiling_basic_pipeline()
  490. test_profiling_cifar10_pipeline()
  491. test_profiling_seq_pipelines_epochctrl3()
  492. test_profiling_seq_pipelines_epochctrl2()
  493. test_profiling_seq_pipelines_repeat()