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.

execution_tree.h 9.5 kB

5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /**
  2. * Copyright 2019-2021 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 MINDSPORE_CCSRC_MINDDATA_DATASET_ENGINE_EXECUTION_TREE_H_
  17. #define MINDSPORE_CCSRC_MINDDATA_DATASET_ENGINE_EXECUTION_TREE_H_
  18. #include <functional>
  19. #include <memory>
  20. #include <stack>
  21. #include <string>
  22. #include <vector>
  23. #ifndef ENABLE_ANDROID
  24. #if !defined(_WIN32) && !defined(_WIN64) && !defined(__APPLE__)
  25. #include <sys/sysinfo.h>
  26. #include <opencv2/imgproc/imgproc.hpp>
  27. #endif
  28. #endif
  29. #include "minddata/dataset/engine/datasetops/dataset_op.h"
  30. #include "minddata/dataset/util/status.h"
  31. #ifndef ENABLE_SECURITY
  32. #include "mindspore/ccsrc/minddata/dataset/engine/perf/profiling.h"
  33. #endif
  34. namespace mindspore {
  35. namespace dataset {
  36. // Forward declares
  37. class TaskGroup;
  38. class DatasetOp;
  39. class Pass;
  40. using OptPass = std::vector<std::unique_ptr<Pass>>;
  41. class ExecutionTree {
  42. public:
  43. // State flags for the lifecycle of the tree
  44. enum TreeState {
  45. kDeTStateInit = 0, // The freshly initialized state after construction
  46. kDeTStateBuilding, // The tree is being built, nodes are being added
  47. kDeTStatePrepared, // The tree has been prepared and is ready to be launched
  48. kDeTStateExecuting, // The tree has been launched and is executing
  49. kDeTStateEpochEnd, // The tree has been received end of epoch signal, just for profiling
  50. kDeTStateFinished // The tree has been drained, dataset iterator received EOF
  51. };
  52. class Iterator {
  53. public:
  54. // Constructor
  55. // @param root The root node to start iterating from
  56. explicit Iterator(const std::shared_ptr<DatasetOp> &root = nullptr);
  57. // Destructor
  58. ~Iterator() {}
  59. Iterator &operator++() {
  60. ++ind_;
  61. return *this;
  62. } // prefix ++ overload
  63. Iterator operator++(int) {
  64. Iterator it = *this;
  65. it.ind_ = ind_;
  66. ind_++;
  67. return it;
  68. } // post-fix ++ overload
  69. Iterator &operator--() {
  70. --ind_;
  71. return *this;
  72. } // prefix -- overload
  73. Iterator operator--(int) {
  74. Iterator it = *this;
  75. it.ind_ = ind_;
  76. ind_--;
  77. return it;
  78. } // post-fix -- overload
  79. DatasetOp &operator*() { return *nodes_[ind_]; } // dereference operator
  80. std::shared_ptr<DatasetOp> operator->() { return nodes_[ind_]; }
  81. // getter function
  82. // @return Shared pointer to the current operator
  83. std::shared_ptr<DatasetOp> get() { return nodes_[ind_]; }
  84. bool operator==(const Iterator &rhs) { return nodes_[ind_] == rhs.nodes_[rhs.ind_]; }
  85. bool operator!=(const Iterator &rhs) { return nodes_[ind_] != rhs.nodes_[rhs.ind_]; }
  86. size_t NumNodes() const { return nodes_.size(); }
  87. private:
  88. size_t ind_; // the cur node our Iterator points to
  89. std::vector<std::shared_ptr<DatasetOp>> nodes_; // store the nodes in post order
  90. void PostOrderTraverse(const std::shared_ptr<DatasetOp> &);
  91. };
  92. // Constructor
  93. ExecutionTree();
  94. // Destructor
  95. ~ExecutionTree();
  96. /// \brief Associates a DatasetOp with this tree. This assigns a valid node id to the operator and
  97. /// provides it with a link to the tree. A node cannot form any relationships (parent/child) with
  98. /// other nodes unless they are associated with the same tree.
  99. /// \param op - The operator to associate
  100. /// \return Status The status code returned
  101. Status AssociateNode(const std::shared_ptr<DatasetOp> &op);
  102. /// \brief Set the root node of the tree
  103. /// \param op - The operator to assign as root
  104. /// \return Status The status code returned
  105. Status AssignRoot(const std::shared_ptr<DatasetOp> &op);
  106. /// \brief Start the execution of the tree
  107. /// \return Status The status code returned
  108. Status Launch();
  109. /// /brief A print method typically used for debugging
  110. /// \param out - The output stream to write output to
  111. void Print(std::ostream &out, const std::shared_ptr<DatasetOp> &op = nullptr) const;
  112. /// \brief Return an iterator positioned at the start
  113. /// \return Iterator - The iterator
  114. ExecutionTree::Iterator begin(const std::shared_ptr<DatasetOp> &root = nullptr) const {
  115. return Iterator(root == nullptr ? root_ : root);
  116. }
  117. /// \brief Return an iterator positioned at the end
  118. /// \return Iterator - The iterator
  119. ExecutionTree::Iterator end() const { return Iterator(nullptr); }
  120. /// \brief << Stream output operator overload
  121. /// \notes This allows you to write the debug print info using stream operators
  122. /// \param out - reference to the output stream being overloaded
  123. /// \param exe_tree - reference to the execution tree to display
  124. /// \return - the output stream must be returned
  125. friend std::ostream &operator<<(std::ostream &out, const ExecutionTree &exe_tree) {
  126. exe_tree.Print(out);
  127. return out;
  128. }
  129. const bool IsPython() {
  130. for (auto itr = this->begin(); itr != this->end(); ++itr) {
  131. if (itr->IsPython()) {
  132. return true;
  133. }
  134. }
  135. return false;
  136. }
  137. /// \brief Given the number of workers, launches the worker entry function for each. Essentially a
  138. /// wrapper for the TaskGroup handling that is stored inside the execution tree.
  139. /// \param num_workers - The number of workers to launch
  140. /// \param func - The function entry point that workers will execute
  141. /// \param[out] worker_tasks - output vector to hold generated tasks
  142. /// \param name - The description of worker to launch
  143. /// \param op_id - The id of corresponding operator, if not inherit from dataset op then it is -1.
  144. /// \return Status The status code returned
  145. Status LaunchWorkers(int32_t num_workers, std::function<Status(uint32_t)> func, std::vector<Task *> *worker_tasks,
  146. std::string name = "", int32_t operator_id = -1);
  147. Status LaunchWorkers(int32_t num_workers, std::function<Status(uint32_t)> func, std::string name = "",
  148. int32_t operator_id = -1);
  149. /// \brief Getter method
  150. /// \return shared_ptr to the root operator
  151. std::shared_ptr<DatasetOp> root() const { return root_; }
  152. /// \brief The prepare phase walks the tree in post-order to perform modifications to get it ready for execution.
  153. /// \return Status The status code returned
  154. Status Prepare();
  155. /// \brief Return the pointer to the TaskGroup
  156. /// \return raw pointer to the TaskGroup
  157. TaskGroup *const AllTasks() const { return tg_.get(); }
  158. /// \brief Return if the ExecutionTree is at end of epoch status
  159. /// \return bool - true is ExecutionTree is end of epoch status
  160. bool IsEpochEnd() const { return tree_state_ == TreeState::kDeTStateEpochEnd; }
  161. /// \brief Set the ExecutionTree to EOE state
  162. void SetEpochEnd() { tree_state_ = TreeState::kDeTStateEpochEnd; }
  163. /// \brief Set the ExecutionTree to executing state
  164. void SetExecuting() { tree_state_ = TreeState::kDeTStateExecuting; }
  165. /// \brief Set the ExecutionTree to Finished state.
  166. void SetFinished() { tree_state_ = TreeState::kDeTStateFinished; }
  167. /// \brief Return if the ExecutionTree is finished (iterator receives EOF).
  168. /// \return Bool - true is ExecutionTree is finished
  169. bool isFinished() const { return tree_state_ == TreeState::kDeTStateFinished; }
  170. /// \brief Return if the ExecutionTree is ready.
  171. /// \return Bool - true is ExecutionTree is ready
  172. bool isPrepared() const {
  173. return tree_state_ == TreeState::kDeTStatePrepared || tree_state_ == TreeState::kDeTStateExecuting ||
  174. tree_state_ == TreeState::kDeTStateFinished;
  175. }
  176. /// \brief Get a unique identifier for the tree
  177. /// \return unique ID as a string
  178. std::string GetUniqueId() { return unique_id_; }
  179. private:
  180. /// \brief A helper functions for doing the recursive printing
  181. /// \param dataset_op - The dataset op to print
  182. /// \param indent - an indent string for aligning child levels in output
  183. /// \param last - an indicator if it's the last child or not
  184. /// \param detailed - should it display the detailed node output or the summary line
  185. void PrintNode(std::ostream &out, const std::shared_ptr<DatasetOp> &dataset_op, std::string indent, bool last,
  186. bool detailed) const;
  187. std::unique_ptr<TaskGroup> tg_; // Class for worker management
  188. std::shared_ptr<DatasetOp> root_; // The root node of the tree
  189. int32_t id_count_; // Counter for generating operator id's
  190. uint32_t prepare_flags_; // Flags used during tree prepare
  191. TreeState tree_state_; // Tracking the current tree state
  192. std::string unique_id_; // A unique identifier for the tree
  193. #if defined(ENABLE_GPUQUE) || defined(ENABLE_TDTQUE)
  194. // This rank_id is for numa and device_queue, one process work with only one rank_id,
  195. // for standalone scenario, this rank_id may come from env 'CUDA_VISIBLE_DEVICES',
  196. // but for distribute scenario, this rank_id come from _get_global_rank() in python
  197. int32_t rank_id_;
  198. bool numa_enable_;
  199. void *handle_;
  200. #endif
  201. };
  202. } // namespace dataset
  203. } // namespace mindspore
  204. #endif // MINDSPORE_CCSRC_MINDDATA_DATASET_ENGINE_EXECUTION_TREE_H_