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_reset.py 8.9 kB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. # Copyright 2022 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 dataset pipeline failover Reset
  17. """
  18. import os
  19. import numpy as np
  20. import pytest
  21. import mindspore.dataset as ds
  22. import mindspore.dataset.vision.c_transforms as c_vision
  23. from util_minddataset import add_and_remove_cv_file
  24. np.random.seed(0)
  25. def create_np_dataset(size):
  26. dimensions = (size, 4, 3, 2)
  27. np_data = np.random.random(dimensions)
  28. data = ds.NumpySlicesDataset(np_data, shuffle=False)
  29. return data
  30. def create_cifar_dataset1(size):
  31. data_dir = "../data/dataset/testCifar100Data"
  32. pad_size = 100
  33. crop_size = 64
  34. data = ds.Cifar100Dataset(data_dir, num_samples=size, shuffle=False)
  35. data = data.project(["image"])
  36. pad_op = c_vision.Pad(pad_size)
  37. data = data.map(operations=pad_op, input_columns=["image"])
  38. crop_op = c_vision.CenterCrop(crop_size)
  39. data = data.map(operations=crop_op, input_columns=["image"])
  40. return data
  41. def create_cifar_dataset2(size):
  42. data_dir = "../data/dataset/testCifar100Data"
  43. pad_size = 100
  44. crop_size = 64
  45. repeat_count = 2
  46. data = ds.Cifar100Dataset(data_dir, num_samples=size, shuffle=False)
  47. data = data.repeat(repeat_count)
  48. data = data.project(["image"])
  49. pad_op = c_vision.Pad(pad_size)
  50. data = data.map(operations=pad_op, input_columns=["image"])
  51. crop_op = c_vision.CenterCrop(crop_size)
  52. data = data.map(operations=crop_op, input_columns=["image"])
  53. return data
  54. def create_imagenet_dataset(size):
  55. data_dir = "../data/dataset/testImageNetData2/train"
  56. batch_size = 2
  57. data = ds.ImageFolderDataset(data_dir, num_samples=size * batch_size, shuffle=False)
  58. data = data.batch(batch_size)
  59. data = data.project(["image"])
  60. return data
  61. def create_minddata_dataset(size):
  62. columns_list = ["data"]
  63. num_readers = 2
  64. file_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
  65. data = ds.MindDataset(file_name + "0", columns_list, num_readers, shuffle=False, num_samples=size)
  66. data = data.rename(input_columns=["data"], output_columns="fake_data")
  67. return data
  68. def run_reset(data, num_epochs, failure_point: int, reset_step: int):
  69. size = data.get_dataset_size()
  70. expected = []
  71. expected_itr = data.create_tuple_iterator(num_epochs=num_epochs, output_numpy=True)
  72. for _ in range(num_epochs):
  73. for d in expected_itr:
  74. expected.append(d)
  75. del expected_itr
  76. actual_before_reset = []
  77. itr = data.create_tuple_iterator(num_epochs=num_epochs, output_numpy=True)
  78. ds.engine.datasets._set_training_dataset(itr) # pylint: disable=W0212
  79. cur_step: int = 0
  80. failed = False
  81. for _ in range(num_epochs):
  82. for d in itr:
  83. actual_before_reset.append(d)
  84. if cur_step == failure_point:
  85. ds.engine.datasets._reset_training_dataset(reset_step) # pylint: disable=W0212
  86. failed = True
  87. break
  88. cur_step += 1
  89. if failed:
  90. break
  91. actual_after_reset = []
  92. if failed:
  93. for _ in range(reset_step // size, num_epochs):
  94. for d in itr:
  95. actual_after_reset.append(d)
  96. with pytest.raises(RuntimeError, match="User tries to fetch data beyond the specified number of epochs."):
  97. for _ in itr:
  98. pass
  99. for x, y in zip(expected[:failure_point], actual_before_reset):
  100. np.testing.assert_array_equal(x, y)
  101. for x, y in zip(expected[reset_step:], actual_after_reset):
  102. np.testing.assert_array_equal(x, y)
  103. def run_reset_error(data, num_epochs: int, failure_point: int):
  104. itr = data.create_tuple_iterator(num_epochs=num_epochs, output_numpy=True) # pylint: disable=unused-variable
  105. ds.engine.datasets._set_training_dataset(itr) # pylint: disable=W0212
  106. if failure_point > 0:
  107. with pytest.raises(RuntimeError) as err:
  108. ds.engine.datasets._reset_training_dataset(failure_point) # pylint: disable=W0212
  109. assert "Cannot reset the pipeline, reset step must be less than dataset_size * num_epochs." in str(err.value)
  110. else:
  111. with pytest.raises(RuntimeError) as err:
  112. ds.engine.datasets._reset_training_dataset(failure_point) # pylint: disable=W0212
  113. assert "Cannot reset the pipeline, reset step must be >= 0." in str(err.value)
  114. def test_reset_np():
  115. """
  116. Feature: dataset recovery
  117. Description: Simple test of data pipeline reset feature on a pipeline with NumpySlicesDataset as a leaf node
  118. Expectation: same datasets after reset
  119. """
  120. dataset_size = 50
  121. num_epochs = 3
  122. failure_steps = (dataset_size * num_epochs) // 10
  123. data = create_np_dataset(size=dataset_size)
  124. for failure_point in range(0, dataset_size * num_epochs, failure_steps):
  125. for reset_step in range(0, dataset_size * num_epochs, failure_steps):
  126. run_reset(data, num_epochs=num_epochs, failure_point=failure_point, reset_step=reset_step)
  127. def test_reset_cifar1():
  128. """
  129. Feature: dataset recovery
  130. Description: Simple test of data pipeline reset feature on a pipeline with Cifar100Dataset as a leaf node (1)
  131. Expectation: same datasets after reset
  132. """
  133. dataset_size = 30
  134. num_epochs = 2
  135. failure_steps = (dataset_size * num_epochs) // 5
  136. data = create_cifar_dataset1(size=dataset_size)
  137. for failure_point in range(0, dataset_size * num_epochs, failure_steps):
  138. for reset_step in range(0, dataset_size * num_epochs, failure_steps):
  139. run_reset(data, num_epochs=num_epochs, failure_point=failure_point, reset_step=reset_step)
  140. def test_reset_cifar2():
  141. """
  142. Feature: dataset recovery
  143. Description: Simple test of data pipeline reset feature on a pipeline with Cifar100Dataset as a leaf node (2)
  144. Expectation: same datasets after reset
  145. """
  146. dataset_size = 30
  147. num_epochs = 3
  148. failure_steps = (dataset_size * num_epochs) // 5
  149. data = create_cifar_dataset2(size=dataset_size)
  150. for failure_point in range(0, dataset_size * num_epochs, failure_steps):
  151. for reset_step in range(0, dataset_size * num_epochs, failure_steps):
  152. run_reset(data, num_epochs=num_epochs, failure_point=failure_point, reset_step=reset_step)
  153. def test_reset_imagenet():
  154. """
  155. Feature: dataset recovery
  156. Description: Simple test of data pipeline reset feature on a pipeline with ImageFolderDataset as a leaf node
  157. Expectation: same datasets after reset
  158. """
  159. dataset_size = 3
  160. num_epochs = 4
  161. failure_steps = (dataset_size * num_epochs) // 4
  162. data = create_imagenet_dataset(size=dataset_size)
  163. for failure_point in range(0, dataset_size * num_epochs, failure_steps):
  164. for reset_step in range(0, dataset_size * num_epochs, failure_steps):
  165. run_reset(data, num_epochs=num_epochs, failure_point=failure_point, reset_step=reset_step)
  166. def test_reset_mindrecord(add_and_remove_cv_file): # pylint: disable=unused-argument, redefined-outer-name
  167. """
  168. Feature: dataset recovery
  169. Description: Simple test of data pipeline reset feature on a pipeline with MindDataset as a leaf node
  170. Expectation: same datasets after reset
  171. """
  172. dataset_size = 10
  173. num_epochs = 3
  174. failure_steps = (dataset_size * num_epochs) // 10
  175. data = create_minddata_dataset(size=dataset_size)
  176. for failure_point in range(0, dataset_size * num_epochs, failure_steps):
  177. for reset_step in range(0, dataset_size * num_epochs, failure_steps):
  178. run_reset(data, num_epochs=num_epochs, failure_point=failure_point, reset_step=reset_step)
  179. def test_reset_np_error():
  180. """
  181. Feature: dataset recovery
  182. Description: Simple test of data pipeline reset feature for error cases (step is negative, or larger than expected)
  183. Expectation: failures are detected properly and correct error message is produced
  184. """
  185. dataset_size = 100
  186. num_epochs = 3
  187. failure_points = (-1000, -300, -99, -5, 300, 301, 1000)
  188. data = create_np_dataset(size=dataset_size)
  189. for failure_point in failure_points:
  190. run_reset_error(data, num_epochs=num_epochs, failure_point=failure_point)
  191. if __name__ == "__main__":
  192. test_reset_np()
  193. test_reset_cifar1()
  194. test_reset_cifar2()
  195. test_reset_imagenet()
  196. test_reset_mindrecord(add_and_remove_cv_file)
  197. test_reset_np_error()