• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 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 
17 #include "runtime/framework/actor/actor_common.h"
18 #include "runtime/framework/device_tensor_store.h"
19 #include "utils/ms_context.h"
20 
21 namespace mindspore {
22 namespace runtime {
ComputeThreadNums(size_t * actor_thread_num,size_t * OMP_thread_num,size_t * max_thread_num)23 void ComputeThreadNums(size_t *actor_thread_num, size_t *OMP_thread_num, size_t *max_thread_num) {
24   MS_EXCEPTION_IF_NULL(actor_thread_num);
25   MS_EXCEPTION_IF_NULL(OMP_thread_num);
26   MS_EXCEPTION_IF_NULL(max_thread_num);
27   size_t cpu_core_num = std::thread::hardware_concurrency() - 1;
28   const size_t kMaxThreadNum = 23;
29   const size_t kActorThreadMaxNum = 5;
30   // The MemoryManagerActor binds single thread, and the other actors share one thread at least, so the min num is 2.
31   const size_t kActorThreadMinNum = 2;
32   auto context_ptr = MsContext::GetInstance();
33   MS_EXCEPTION_IF_NULL(context_ptr);
34   *actor_thread_num = cpu_core_num < kActorThreadMinNum ? kActorThreadMinNum : cpu_core_num;
35   *actor_thread_num = *actor_thread_num > kActorThreadMaxNum ? kActorThreadMaxNum : *actor_thread_num;
36 
37   const size_t kOMPThreadMaxNum = 8;
38   *OMP_thread_num = cpu_core_num < kOMPThreadMaxNum ? cpu_core_num : kOMPThreadMaxNum;
39   *max_thread_num = cpu_core_num > *actor_thread_num ? cpu_core_num : (*actor_thread_num + 1);
40   if (*max_thread_num > kMaxThreadNum) {
41     *max_thread_num = kMaxThreadNum;
42   }
43 }
44 
IsDeviceQueueDSActor(const AnfNodePtr & node,GraphExecutionStrategy strategy)45 bool IsDeviceQueueDSActor(const AnfNodePtr &node, GraphExecutionStrategy strategy) {
46   MS_EXCEPTION_IF_NULL(node);
47   if (strategy == GraphExecutionStrategy::kStep) {
48     return false;
49   }
50 
51   if (node->isa<CNode>() && (AnfAlgo::GetCNodeName(node) == kGetNextOpName)) {
52     return true;
53   }
54   return false;
55 }
56 
IsHostQueueDSActor(const AnfNodePtr & node,const KernelGraphPtr & graph,const std::vector<AnfNodePtr> & host_parameters,GraphExecutionStrategy strategy)57 bool IsHostQueueDSActor(const AnfNodePtr &node, const KernelGraphPtr &graph,
58                         const std::vector<AnfNodePtr> &host_parameters, GraphExecutionStrategy strategy) {
59   MS_EXCEPTION_IF_NULL(node);
60 
61   bool is_parameter_data = node->isa<Parameter>() && (!AnfAlgo::IsParameterWeight(node->cast<ParameterPtr>()));
62   if (!is_parameter_data) {
63     return false;
64   }
65 
66   if (strategy == GraphExecutionStrategy::kStep) {
67     MS_EXCEPTION_IF_NULL(graph);
68     return graph->execution_order().size() > 1;
69   }
70 
71   if (graph == nullptr) {
72     return true;
73   }
74 
75   // In control flow, only the parameters of the root funcgraph are in the host data source.
76   const auto &front_node = graph->GetFrontAnfByBackendAnf(node);
77   bool is_host = ((front_node == nullptr) || host_parameters.empty() ||
78                   find(host_parameters.begin(), host_parameters.end(), front_node) != host_parameters.end());
79 
80   // Judge whether node is internal parameter.
81   const auto &internal_front_node = graph->GetFrontNodeByInternalParameter(node);
82   if (internal_front_node.first == nullptr && is_host) {
83     return true;
84   }
85 
86   return false;
87 }
88 
IsSwitchActor(const AnfNodePtr & node)89 bool IsSwitchActor(const AnfNodePtr &node) { return AnfAlgo::CheckPrimitiveType(node, prim::kPrimSwitch); }
90 
IsInternalParameter(const AnfNodePtr & node,const KernelGraphPtr & graph)91 bool IsInternalParameter(const AnfNodePtr &node, const KernelGraphPtr &graph) {
92   MS_EXCEPTION_IF_NULL(node);
93   MS_EXCEPTION_IF_NULL(graph);
94   if (node->isa<Parameter>() && (!AnfAlgo::IsParameterWeight(node->cast<ParameterPtr>()))) {
95     //  Judge whether node is internal parameter.
96     const auto &front_node = graph->GetFrontNodeByInternalParameter(node);
97     if (front_node.first != nullptr) {
98       return true;
99     }
100   }
101   return false;
102 }
103 
IsKernelActor(const AnfNodePtr & node,GraphExecutionStrategy strategy)104 bool IsKernelActor(const AnfNodePtr &node, GraphExecutionStrategy strategy) {
105   MS_EXCEPTION_IF_NULL(node);
106   if (!node->isa<CNode>()) {
107     return false;
108   }
109 
110   if (strategy == GraphExecutionStrategy::kStep) {
111     return true;
112   }
113 
114   return (AnfAlgo::GetCNodeName(node) != kGetNextOpName);
115 }
116 
IsSkippedKernelActor(const AnfNodePtr & node)117 bool IsSkippedKernelActor(const AnfNodePtr &node) {
118   MS_EXCEPTION_IF_NULL(node);
119   if (IsKernelActor(node) && AnfAlgo::IsInplaceNode(node, "skip")) {
120     return true;
121   }
122   return false;
123 }
124 
IsPersistentDeviceTensor(const AnfNodePtr & node)125 bool IsPersistentDeviceTensor(const AnfNodePtr &node) {
126   MS_EXCEPTION_IF_NULL(node);
127   if (node->isa<ValueNode>()) {
128     return true;
129   }
130   if (node->isa<Parameter>() && AnfAlgo::IsParameterWeight(node->cast<ParameterPtr>())) {
131     return true;
132   }
133   return false;
134 }
135 
IsGatherActor(const AnfNodePtr & front_node,const std::unordered_map<std::string,OpActor<DeviceTensor> * > & actor_name_to_actor)136 bool IsGatherActor(const AnfNodePtr &front_node,
137                    const std::unordered_map<std::string, OpActor<DeviceTensor> *> &actor_name_to_actor) {
138   MS_EXCEPTION_IF_NULL(front_node);
139   if (front_node->isa<Parameter>() && (!AnfAlgo::IsParameterWeight(front_node->cast<ParameterPtr>())) &&
140       (front_node->func_graph() != nullptr) && (actor_name_to_actor.count(front_node->func_graph()->ToString()) > 0)) {
141     return true;
142   }
143   return false;
144 }
145 
Copy(const DeviceTensor * dst_device_tensor,const DeviceTensor * src_device_tensor)146 bool Copy(const DeviceTensor *dst_device_tensor, const DeviceTensor *src_device_tensor) {
147   MS_EXCEPTION_IF_NULL(dst_device_tensor);
148   MS_EXCEPTION_IF_NULL(src_device_tensor);
149   if (src_device_tensor->GetSize() != dst_device_tensor->GetSize()) {
150     MS_LOG(WARNING) << "Copy size is not equal, input size:" << src_device_tensor->GetSize()
151                     << ", output size:" << dst_device_tensor->GetSize();
152   }
153 
154   // Exist the size alignment in some device, so get the min device size.
155   size_t copy_size = std::min(src_device_tensor->GetSize(), dst_device_tensor->GetSize());
156 
157   if (src_device_tensor->DeviceType() == device::DeviceAddressType::kCPU) {
158     // CPU device tensor copy to other device tensor.
159     return dst_device_tensor->SyncHostToDevice(copy_size, src_device_tensor->GetPtr());
160   } else if (dst_device_tensor->DeviceType() == device::DeviceAddressType::kCPU) {
161     // Other device tensor copy to CPU device tensor.
162     return src_device_tensor->SyncDeviceToHost(copy_size, dst_device_tensor->GetMutablePtr());
163   } else {
164     MS_LOG(ERROR) << "Invalid device type, src device type: " << src_device_tensor->DeviceType()
165                   << ", dst device type: " << dst_device_tensor->DeviceType();
166     return false;
167   }
168 }
169 
UpdateRefCount(DeviceTensor * const device_tensor,bool is_max_ref_count)170 void UpdateRefCount(DeviceTensor *const device_tensor, bool is_max_ref_count) {
171   MS_EXCEPTION_IF_NULL(device_tensor);
172   if (is_max_ref_count) {
173     device_tensor->set_original_ref_count(SIZE_MAX);
174   } else {
175     device_tensor->IncreaseOriginalRefCount();
176   }
177   device_tensor->ResetRefCount();
178 }
179 
UpdateRefCount(const AnfNodePtr & node,size_t output_idx,bool is_max_ref_count)180 void UpdateRefCount(const AnfNodePtr &node, size_t output_idx, bool is_max_ref_count) {
181   MS_EXCEPTION_IF_NULL(node);
182   auto device_tensor = AnfAlgo::GetMutableOutputAddr(node, output_idx, false);
183   UpdateRefCount(device_tensor.get(), is_max_ref_count);
184 }
185 
FetchFrontNodeByBackendNode(const AnfNodePtr & backend_node,const KernelGraphPtr & graph)186 AnfNodePtr FetchFrontNodeByBackendNode(const AnfNodePtr &backend_node, const KernelGraphPtr &graph) {
187   MS_EXCEPTION_IF_NULL(backend_node);
188   MS_EXCEPTION_IF_NULL(graph);
189 
190   // Internal parameter ---> front node.
191   auto front_node_with_index = graph->GetFrontNodeByInternalParameter(backend_node);
192   if (front_node_with_index.first != nullptr) {
193     return front_node_with_index.first;
194   }
195 
196   auto front_node = graph->GetFrontAnfByBackendAnf(backend_node);
197   // PyNative forward graph does not has front node, using backend node instead.
198   if (front_node == nullptr) {
199     front_node = backend_node;
200   }
201   return front_node;
202 }
203 
FetchFrontNodeWithIndexByGraphOutput(const KernelWithIndex & output_with_index,const KernelGraphPtr & graph)204 KernelWithIndex FetchFrontNodeWithIndexByGraphOutput(const KernelWithIndex &output_with_index,
205                                                      const KernelGraphPtr &graph) {
206   MS_EXCEPTION_IF_NULL(graph);
207   auto front_node_with_index = graph->GetFrontNodeWithIndexByGraphOutput(output_with_index);
208   // PyNative forward graph does not has front node, using backend node instead.
209   if (front_node_with_index.first == nullptr) {
210     front_node_with_index = output_with_index;
211   }
212   return front_node_with_index;
213 }
214 }  // namespace runtime
215 }  // namespace mindspore
216