random.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
  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. # TODO: define random api
  15. import paddle
  16. from paddle.base import core
  17. __all__ = []
  18. def seed(seed):
  19. """
  20. Sets the seed for global default generator, which manages the random number generation.
  21. Args:
  22. seed(int): The random seed to set. It is recommend to set a large int number.
  23. Returns:
  24. Generator: The global default generator object.
  25. Examples:
  26. .. code-block:: python
  27. >>> import paddle
  28. >>> gen = paddle.seed(102)
  29. """
  30. # TODO(zhiqiu): 1. remove program.random_seed when all random-related op upgrade
  31. # 2. support gpu generator by global device
  32. seed = int(seed)
  33. if paddle.is_compiled_with_cuda():
  34. for i in range(core.get_cuda_device_count()):
  35. core.default_cuda_generator(i).manual_seed(seed)
  36. elif paddle.is_compiled_with_xpu():
  37. for i in range(core.get_xpu_device_count()):
  38. core.default_xpu_generator(i).manual_seed(seed)
  39. place = paddle.framework._current_expected_place()
  40. if isinstance(place, paddle.CustomPlace):
  41. dev_cnt = sum(
  42. [
  43. place.get_device_type() == s.split(':')[0]
  44. for s in core.get_available_custom_device()
  45. ]
  46. )
  47. for i in range(dev_cnt):
  48. core.default_custom_device_generator(
  49. paddle.CustomPlace(place.get_device_type(), i)
  50. ).manual_seed(seed)
  51. return core.default_cpu_generator().manual_seed(seed)
  52. def get_rng_state(device=None):
  53. """
  54. Get all random states of random generators of specified device.
  55. Args:
  56. device(str): This parameter determines the specific running device.
  57. It can be ``cpu``, ``gpu``, ``xpu``, Default is None.
  58. If None, return the generators of current device (specified by ``set_device``).
  59. Returns:
  60. GeneratorState: object.
  61. Examples:
  62. .. code-block:: python
  63. >>> import paddle
  64. >>> sts = paddle.get_rng_state()
  65. """
  66. state_list = []
  67. if device is None:
  68. place = paddle.framework._current_expected_place()
  69. else:
  70. place = paddle.device._convert_to_place(device)
  71. if isinstance(place, paddle.CPUPlace):
  72. state_list.append(core.default_cpu_generator().get_state())
  73. elif isinstance(place, paddle.CUDAPlace):
  74. for i in range(core.get_cuda_device_count()):
  75. state_list.append(core.default_cuda_generator(i).get_state())
  76. elif isinstance(place, paddle.XPUPlace):
  77. for i in range(core.get_xpu_device_count()):
  78. state_list.append(core.default_xpu_generator(i).get_state())
  79. elif isinstance(place, paddle.CustomPlace):
  80. dev_cnt = sum(
  81. [
  82. place.get_device_type() == s.split(':')[0]
  83. for s in core.get_available_custom_device()
  84. ]
  85. )
  86. for i in range(dev_cnt):
  87. state_list.append(
  88. core.default_custom_device_generator(
  89. core.CustomPlace(place.get_device_type(), i)
  90. ).get_state()
  91. )
  92. else:
  93. raise ValueError(
  94. f"get_rng_state is not implemented for current device: {place}"
  95. )
  96. return state_list
  97. def get_cuda_rng_state():
  98. """
  99. Get random state of cuda generators.
  100. Args:
  101. None.
  102. Returns:
  103. GeneratorState: object.
  104. Examples:
  105. .. code-block:: python
  106. >>> import paddle
  107. >>> sts = paddle.get_cuda_rng_state()
  108. """
  109. state_list = []
  110. if paddle.is_compiled_with_cuda():
  111. for i in range(core.get_cuda_device_count()):
  112. state_list.append(core.default_cuda_generator(i).get_state())
  113. return state_list
  114. def set_rng_state(state_list, device=None):
  115. """
  116. Sets generator state for all device generators.
  117. Args:
  118. state_list(list|tuple): The device states to set back to device generators. state_list is obtained from get_rng_state().
  119. device(str): This parameter determines the specific running device.
  120. It can be ``cpu``, ``gpu``, ``xpu``, Default is None.
  121. If None, return the generators of current device (specified by ``set_device``).
  122. Returns:
  123. None.
  124. Examples:
  125. .. code-block:: python
  126. >>> import paddle
  127. >>> sts = paddle.get_rng_state()
  128. >>> paddle.set_rng_state(sts)
  129. """
  130. if device is None:
  131. place = paddle.framework._current_expected_place()
  132. else:
  133. place = device._convert_to_place(device)
  134. if isinstance(place, paddle.CUDAPlace):
  135. if not len(state_list) == core.get_cuda_device_count():
  136. raise ValueError(
  137. "Length of gpu state list should be equal to the gpu device count"
  138. )
  139. for i in range(core.get_cuda_device_count()):
  140. core.default_cuda_generator(i).set_state(state_list[i])
  141. elif isinstance(place, paddle.XPUPlace):
  142. if not len(state_list) == core.get_xpu_device_count():
  143. raise ValueError(
  144. "Length of xpu state list should be equal to the xpu device count"
  145. )
  146. for i in range(core.get_xpu_device_count()):
  147. core.default_xpu_generator(i).set_state(state_list[i])
  148. elif isinstance(place, paddle.CustomPlace):
  149. dev_cnt = sum(
  150. [
  151. place.get_device_type() == s.split(':')[0]
  152. for s in core.get_available_custom_device()
  153. ]
  154. )
  155. if not len(state_list) == dev_cnt:
  156. raise ValueError(
  157. f"Length of custom device state list should be equal to the {place.get_dtype_type()} device count"
  158. )
  159. for i in range(dev_cnt):
  160. core.default_custom_device_generator(
  161. paddle.CustomPlace(place.get_device_type(), i)
  162. ).set_state(state_list[i])
  163. elif isinstance(place, core.CPUPlace):
  164. if not len(state_list) == 1:
  165. raise ValueError("Length of cpu state list should be equal to 1")
  166. core.default_cpu_generator().set_state(state_list[0])
  167. else:
  168. raise ValueError(
  169. f"set_rng_state is not implemented for current device: {place}"
  170. )
  171. def set_cuda_rng_state(state_list):
  172. """
  173. Sets generator state for all cuda generators.
  174. Args:
  175. state_list(list|tuple): The cuda states to set back to cuda generators. state_list is obtained from get_cuda_rng_state().
  176. Returns:
  177. None.
  178. Examples:
  179. .. code-block:: python
  180. >>> import paddle
  181. >>> sts = paddle.get_cuda_rng_state()
  182. >>> paddle.set_cuda_rng_state(sts)
  183. """
  184. if paddle.is_compiled_with_cuda():
  185. if not len(state_list) == core.get_cuda_device_count():
  186. raise ValueError(
  187. "Length of cuda state list should be equal to the cuda device count"
  188. )
  189. for i in range(core.get_cuda_device_count()):
  190. core.default_cuda_generator(i).set_state(state_list[i])
  191. def _manual_program_seed(seed):
  192. """
  193. Sets global seed for generating random numbers.
  194. NOTE(zhiqiu): This is the original implementation of seed. Keeps it temporally
  195. since CUDA generator is not developed, so we need it in the unittest.
  196. Args:
  197. seed(int): The random seed to set. It is recommend to set a large int number.
  198. Returns:
  199. None
  200. """
  201. paddle.static.default_main_program().random_seed = seed
  202. paddle.static.default_startup_program().random_seed = seed
  203. program = paddle.static.Program()
  204. program.global_seed(seed)
  205. def set_random_seed_generator(name, seed):
  206. core.set_random_seed_generator(name, seed)
  207. def get_random_seed_generator(name):
  208. return core.get_random_seed_generator(name)