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