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.

control_flow_ops.h 13 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /**
  2. * Copyright 2019-2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef GE_CONTROL_FLOW_OPS_H_
  17. #define GE_CONTROL_FLOW_OPS_H_
  18. #include "graph/operator_reg.h"
  19. #include "graph/operator.h"
  20. namespace ge {
  21. /**
  22. *@brief Forwards the value of an available tensor from input "x" to output "y". \n
  23. * Merge waits for at least one of the input tensors to become available. \n
  24. * It is usually combined with Switch to implement branching. \n
  25. * Merge forwards the first tensor to become available to output "y", \n
  26. * and sets "value_index" the index of the tensor in inputs.
  27. *@par Inputs:
  28. *x: The input tensors, one of which will become available. \n
  29. * Must be one of the following types: float16, float32, float64, int8, \n
  30. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  31. *@par Outputs:
  32. *@li y: The available tensor. Has the same type as "x".
  33. *@li value_index: A scalar of type int32, for the index of the chosen input \n
  34. * tensor.
  35. *@see Switch()
  36. */
  37. REG_OP(Merge)
  38. .DYNAMIC_INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  39. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  40. DT_UINT64, DT_BOOL}))
  41. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  42. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  43. DT_UINT64, DT_BOOL}))
  44. .OUTPUT(value_index, TensorType({DT_INT32}))
  45. .OP_END_FACTORY_REG(Merge)
  46. /**
  47. *@brief Forwards the value of an available tensor from input "x" to output "y". \n
  48. * Merge waits for at least one of the input tensors to become available. \n
  49. * It is usually combined with Switch to implement branching. \n
  50. * Merge forwards the first tensor to become available to output "y", \n
  51. * and sets "value_index" the index of the tensor in inputs.
  52. *@par Inputs:
  53. *x: The input tensors, one of which will become available. \n
  54. * Must be one of the following types: float16, float32, float64, int8, \n
  55. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  56. *@par Outputs:
  57. *@li y: The available tensor. Has the same type as "x".
  58. *@li value_index: A scalar of type int32, for the index of the chosen input \n
  59. * tensor.
  60. *@see Switch() | Merge()
  61. */
  62. REG_OP(RefMerge)
  63. .DYNAMIC_INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  64. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  65. DT_UINT64, DT_BOOL}))
  66. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  67. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  68. DT_UINT64, DT_BOOL}))
  69. .OUTPUT(value_index, TensorType({DT_INT32}))
  70. .OP_END_FACTORY_REG(RefMerge)
  71. /**
  72. *@brief Forwards "data" to the output port determined by "pred". \n
  73. * If "pred" is "true", the data input is forwarded to "output_true". \n
  74. * Otherwise, the data is forwarded to "output_false".
  75. *@par Inputs:
  76. *@li data: The tensor to be forwarded. \ n
  77. * Must be one of the following types: float16, float32, float64, \n
  78. * int8, int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  79. *@li pred: A boolean scalar. The output port that will receive data.
  80. *@par Outputs:
  81. *@li output_false: If "pred" is "false", data will be forwarded to this output. \n
  82. * Has the same type as "data".
  83. *@li output_true: If "pred" is "true", data will be forwarded to this output. \n
  84. * Has the same type as "data".
  85. *@see Merge()
  86. */
  87. REG_OP(Switch)
  88. .INPUT(data, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  89. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  90. DT_UINT64, DT_BOOL}))
  91. .INPUT(pred, TensorType({DT_BOOL}))
  92. .OUTPUT(output_false, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  93. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  94. DT_UINT64, DT_BOOL}))
  95. .OUTPUT(output_true, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  96. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  97. DT_UINT64, DT_BOOL}))
  98. .OP_END_FACTORY_REG(Switch)
  99. /**
  100. *@brief Forwards "data" to the output port determined by "pred". \n
  101. * If "pred" is "true", the data input is forwarded to "output_true". \n
  102. * Otherwise, the data is forwarded to "output_false".
  103. *@par Inputs:
  104. *@li data: The ref tensor to be forwarded. \n
  105. * Must be one of the following types: float16, float32, float64, \n
  106. * int8, int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  107. *@li pred: A boolean scalar. The output port that will receive data.
  108. *@par Outputs:
  109. *@li output_false: If "pred" is "false", data will be forwarded to this output. \n
  110. * Has the same type as "data".
  111. *@li output_true: If "pred" is "true", data will be forwarded to this output. \n
  112. * Has the same type as "data".
  113. *@see Merge() | Switch()
  114. */
  115. REG_OP(RefSwitch)
  116. .INPUT(data, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  117. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  118. DT_UINT64, DT_BOOL}))
  119. .INPUT(pred, TensorType({DT_BOOL}))
  120. .OUTPUT(output_false, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  121. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  122. DT_UINT64, DT_BOOL}))
  123. .OUTPUT(output_true, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  124. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  125. DT_UINT64, DT_BOOL}))
  126. .OP_END_FACTORY_REG(RefSwitch)
  127. REG_OP(SwitchN)
  128. .INPUT(data, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  129. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  130. DT_UINT64, DT_BOOL}))
  131. .INPUT(pred_value, TensorType({DT_INT64}))
  132. .DYNAMIC_OUTPUT(output, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  133. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  134. DT_UINT64, DT_BOOL}))
  135. .OP_END_FACTORY_REG(SwitchN)
  136. /**
  137. *@brief Creates or finds a child frame, and makes "x" available to the child \n
  138. * frame. This op is used together with Exit to create loops in the graph. \n
  139. * The Executor uses the unique "frame_name" to identify frames. \n
  140. * If "is_constant" is "true", output "y" is a constant in the child \n
  141. * frame; otherwise it may be changed in the child frame.
  142. *@par Inputs:
  143. *x: The tensor to be made available to the child frame. \n
  144. * Must be one of the following types: float16, float32, float64, int8, \n
  145. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  146. *@par Attributes:
  147. *@li frame_name: A required string. The name of the child frame.
  148. *@li is_constant: A required bool. If true, the output is constant in \n
  149. * the child frame.
  150. *@par Outputs:
  151. *y: A Tensor. Has the same type as "x".
  152. *@see Exit()
  153. */
  154. REG_OP(Enter)
  155. .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  156. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  157. DT_UINT64, DT_BOOL}))
  158. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  159. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  160. DT_UINT64, DT_BOOL}))
  161. .REQUIRED_ATTR(frame_name, String)
  162. .REQUIRED_ATTR(is_constant, Bool)
  163. .OP_END_FACTORY_REG(Enter)
  164. /**
  165. *@brief Creates or finds a child frame, and makes "x" available to the child \n
  166. * frame. This op is used together with Exit to create loops in the graph. \n
  167. * The Executor uses the unique "frame_name" to identify frames. \n
  168. * If "is_constant" is "true", output "y" is a constant in the child \n
  169. * frame; otherwise it may be changed in the child frame.
  170. *@par Inputs:
  171. *x: The tensor to be made available to the child frame. \n
  172. * Must be one of the following types: float16, float32, float64, int8, \n
  173. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  174. *@par Attributes:
  175. *@li frame_name: A required string. The name of the child frame.
  176. *@li is_constant: A required bool. If true, the output is constant in \n
  177. * the child frame.
  178. *@par Outputs:
  179. *y: A tensor. Has the same type as "x".
  180. *@see Exit() | Enter()
  181. */
  182. REG_OP(RefEnter)
  183. .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  184. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  185. DT_UINT64, DT_BOOL}))
  186. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  187. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  188. DT_UINT64, DT_BOOL}))
  189. .REQUIRED_ATTR(frame_name, String)
  190. .REQUIRED_ATTR(is_constant, Bool)
  191. .OP_END_FACTORY_REG(RefEnter)
  192. /**
  193. *@brief Forwards the input to the output. This op represents the loop \n
  194. * termination condition.
  195. *@par Inputs:
  196. *x: A boolean scalar. The condition of the Switch op.
  197. *@par Outputs:
  198. *y: The tensor "x".
  199. *@see Switch()
  200. */
  201. REG_OP(LoopCond)
  202. .INPUT(x, TensorType({DT_BOOL}))
  203. .OUTPUT(y, TensorType({DT_BOOL}))
  204. .OP_END_FACTORY_REG(LoopCond)
  205. /**
  206. *@brief Makes the input available to the next iteration.
  207. *@par Inputs:
  208. *x: The tensor to be made available to the next iteration. \n
  209. * Must be one of the following types: float16, float32, float64, int8, \n
  210. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  211. *@par Outputs:
  212. *y: A Tensor. Has the same type as "x".
  213. */
  214. REG_OP(NextIteration)
  215. .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  216. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  217. DT_UINT64, DT_BOOL}))
  218. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  219. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  220. DT_UINT64, DT_BOOL}))
  221. .OP_END_FACTORY_REG(NextIteration)
  222. /**
  223. *@brief Makes the input available to the next iteration.
  224. *@par Inputs:
  225. *x: The tensor to be made available to the next iteration. \n
  226. * Must be one of the following types: float16, float32, float64, int8, \n
  227. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  228. *@par Outputs:
  229. *y: A tensor. Has the same type as "x".
  230. */
  231. REG_OP(RefNextIteration)
  232. .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  233. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  234. DT_UINT64, DT_BOOL}))
  235. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  236. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  237. DT_UINT64, DT_BOOL}))
  238. .OP_END_FACTORY_REG(RefNextIteration)
  239. /**
  240. *@brief Exits the current frame to its parent frame.
  241. *@par Inputs:
  242. *x: The tensor to be made available to the parent frame. \n
  243. * Must be one of the following types: float16, float32, float64, int8, \n
  244. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  245. *@par Outputs:
  246. *y: A Tensor. Has the same type as "x".
  247. *@see Enter()
  248. */
  249. REG_OP(Exit)
  250. .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  251. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  252. DT_UINT64, DT_BOOL}))
  253. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  254. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  255. DT_UINT64, DT_BOOL}))
  256. .OP_END_FACTORY_REG(Exit)
  257. /**
  258. *@brief Exits the current frame to its parent frame.
  259. *@par Inputs:
  260. *x: The tensor to be made available to the parent frame. \n
  261. * Must be one of the following types: float16, float32, float64, int8, \n
  262. * int16, int32, int64, uint8, uint16, uint32, uint64, bool.
  263. *@par Outputs:
  264. *y: A tensor. Has the same type as "x".
  265. *@see Enter() | Exit()
  266. */
  267. REG_OP(RefExit)
  268. .INPUT(x, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  269. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  270. DT_UINT64, DT_BOOL}))
  271. .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_DOUBLE,
  272. DT_INT8, DT_INT16, DT_INT32, DT_INT64, DT_UINT8, DT_UINT16, DT_UINT32,
  273. DT_UINT64, DT_BOOL}))
  274. .OP_END_FACTORY_REG(RefExit)
  275. /**
  276. *@brief Only useful as a placeholder for control edges. \n
  277. * It is similar to a no-op that always produces a live control output \n
  278. * even when some control inputs are dead.
  279. */
  280. REG_OP(ControlTrigger)
  281. .OP_END_FACTORY_REG(ControlTrigger)
  282. } // namespace ge
  283. #endif // GE_CONTROL_FLOW_OPS_H_

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示