1 /** 2 * Copyright 2021-2022 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 #ifndef MINDSPORE_CCSRC_RUNTIME_FRAMEWORK_ACTOR_ACTOR_COMMON_H_ 18 #define MINDSPORE_CCSRC_RUNTIME_FRAMEWORK_ACTOR_ACTOR_COMMON_H_ 19 20 #include <string> 21 #include <vector> 22 #include <set> 23 #include <utility> 24 #include <thread> 25 #include <algorithm> 26 #include <map> 27 #include <memory> 28 #include "utils/hash_map.h" 29 #include "mindrt/include/actor/op_actor.h" 30 #include "include/backend/device_address.h" 31 #include "include/backend/anf_runtime_algorithm.h" 32 #include "include/common/utils/anfalgo.h" 33 #include "include/backend/kernel_graph.h" 34 #include "utils/log_adapter.h" 35 #include "ir/tensor.h" 36 #include "runtime/device/ms_device_shape_transfer.h" 37 #include "runtime/hardware/device_context_manager.h" 38 #include "include/backend/mem_reuse/mem_dynamic_allocator.h" 39 #include "include/common/profiler.h" 40 41 namespace mindspore { 42 namespace runtime { 43 using mindspore::session::KernelWithIndex; 44 using tensor::TensorPtr; 45 using DeviceTensor = mindspore::device::DeviceAddress; 46 using mindspore::device::DeviceContext; 47 using mindspore::device::KernelInfo; 48 using CompileFunc = std::function<KernelGraphPtr( 49 const GraphSegmentPtr &, const std::pair<AnfNodePtrList, AnfNodePtrList> &, const DeviceContext *, device::RunMode)>; 50 51 // The execution result of actor. 52 constexpr int kSuccess = 0; 53 constexpr int kFailure = 1; 54 55 enum class GraphExecutionStrategy { 56 kPipeline, // The actor running is triggered only by data. 57 kStep, // The actor running need be triggered by control in addition. 58 kPipelineWithExecutionOrder // The actor running is triggered by data with the persistent execution order. 59 }; 60 static const std::map<GraphExecutionStrategy, std::string> kGraphExecutionStrategyStr = { 61 {GraphExecutionStrategy::kPipeline, "pipeline"}, 62 {GraphExecutionStrategy::kStep, "step"}, 63 {GraphExecutionStrategy::kPipelineWithExecutionOrder, "pipeline_with_execution_order"}, 64 }; 65 66 const char kDataPrepareActorNameSuffix[] = "_DataPrepareActor"; 67 const char kHostDSActorNameSuffix[] = "_HostDSActor"; 68 const char kDeviceDSActorNameSuffix[] = "_DeviceDSActor"; 69 const char kSuperKernelActorNameSuffix[] = "_SuperKernelActor"; 70 const char kAnyTypeKernelActorNameSuffix[] = "_AnyTypeKernelActor"; 71 const char kLoopCountActorNameSuffix[] = "_LoopCountActor"; 72 const char kOutputActorNameSuffix[] = "_OutputActor"; 73 const char kEntranceActorNameSuffix[] = "_EntranceActor"; 74 const char kExitActorNameSuffix[] = "_ExitActor"; 75 const char kStackActorNameSuffix[] = "_StackActor"; 76 const char kFusionActorNameSuffix[] = "_FusionActor"; 77 const char kMemoryAllocActorNameSuffix[] = "_MemoryAllocActor"; 78 const char kMemoryFreeActorNameSuffix[] = "_MemoryFreeActor"; 79 const char kCopyActorNameSignFromStore[] = "_device_tensor_store:"; 80 const char kMemSwapInActorNameSuffix[] = "_MemorySwapInActor"; 81 const char kMemSwapOutActorNameSuffix[] = "_MemorySwapOutActor"; 82 const char kMemSwapActorNamePrefix[] = "MemorySwapActor_"; 83 const char kKernelInferActorNamePrefix[] = "KernelInferActor_"; 84 const char kKernelResizeActorNamePrefix[] = "KernelResizeActor_"; 85 86 enum class KernelTransformType { 87 kUnknown, 88 kDataPrepareActor, 89 kDeviceDataSourceActor, 90 kHostDataSourceActor, 91 kKernelActor, 92 kKernelInferActor, 93 kKernelResizeActor, 94 kCustomActor, 95 // Super kernel actor represents the sink executing of graph which is the combination of kernels. 96 kSuperKernelActor, 97 // Any type kernel actor represents the graph which has an any type input. 98 kAnyTypeKernelActor, 99 kCopyActor, 100 kLoopCountActor, 101 kOutputActor, 102 kDeviceTensorStore, 103 // Internal parameter is the output of previous kernel graph which is related to the input of next kernel graph. 104 kInternalParameter, 105 // Control flow actor type. 106 kSwitchActor, 107 kGatherActor, 108 kEntranceActor, 109 kExitActor, 110 kStackActor, 111 // RPC actor type. 112 kSendActor, 113 kRecvActor, 114 // Fusion actor type. 115 kFusionActor, 116 // Memory actor type. 117 kMemoryAllocActor, 118 kMemoryFreeActor, 119 kMemorySwapActor, 120 // Inner control flow actor type. 121 kConditionGatherActor, 122 kConditionSwitchActor 123 }; 124 125 #define SET_OPCONTEXT_FAIL_RET_WITH_ERROR(op_context, message) \ 126 do { \ 127 if ((op_context).error_info_.empty()) { \ 128 (op_context).error_info_ = message; \ 129 } \ 130 (op_context).SetFailed(kFailure); \ 131 return; \ 132 } while (0); 133 134 #define SET_OPCONTEXT_SUCCESS_RET(op_context) \ 135 do { \ 136 (op_context).SetSuccess(kSuccess); \ 137 return; \ 138 } while (0); 139 140 #define SET_OPCONTEXT_FAIL_RET_WITH_ERROR_BY_STRATEGY(strategy, op_context, message) \ 141 do { \ 142 if ((strategy) == GraphExecutionStrategy::kStep) { \ 143 MS_LOG(EXCEPTION) << (message); \ 144 } \ 145 if ((op_context).error_info_.empty()) { \ 146 (op_context).error_info_ = message; \ 147 } \ 148 (op_context).SetFailed(kFailure); \ 149 return; \ 150 } while (0); 151 152 #define SET_OPCONTEXT_MEMORY_ALLOC_FAIL_BY_STRATEGY(strategy, op_context, device_context, kernel_name, alloc_size) \ 153 do { \ 154 std::string message = "#umsg#Memory not enough:#umsg#"; \ 155 if ((device_context).device_context_key().device_name_ == "CPU") { \ 156 message += "Memory isn't enough and alloc failed, kernel name: " + (kernel_name) + \ 157 ", alloc size: " + std::to_string(alloc_size) + "B."; \ 158 } else { \ 159 message += "Device(id:" + std::to_string((device_context).device_context_key().device_id_) + \ 160 ") memory isn't enough and alloc failed, kernel name: " + (kernel_name) + \ 161 ", alloc size: " + std::to_string(alloc_size) + "B."; \ 162 } \ 163 if ((strategy) == GraphExecutionStrategy::kStep) { \ 164 MS_LOG(EXCEPTION) << message; \ 165 } else { \ 166 MS_LOG(ERROR) << message; \ 167 } \ 168 if ((op_context).error_info_.empty()) { \ 169 (op_context).error_info_ = message; \ 170 } \ 171 (op_context).SetFailed(kFailure); \ 172 return; \ 173 } while (0); 174 175 enum MemoryType { 176 kOutputMem = 0, 177 kWorkspaceMem = 1, 178 }; 179 180 struct KernelMemoryTraceBlock { KernelMemoryTraceBlockKernelMemoryTraceBlock181 KernelMemoryTraceBlock(const CNodePtr &kernel, void *start, size_t size, MemoryType mem_type, size_t index) 182 : kernel_(kernel), 183 start_(reinterpret_cast<uint8_t *>(start)), 184 end_(reinterpret_cast<uint8_t *>(start) + size), 185 size_(size), 186 mem_type_(mem_type), 187 index_(index), 188 in_memory_trace_block_index_(0), 189 offset_in_memory_trace_block_(0) {} 190 191 CNodePtr kernel_; 192 uint8_t *start_; 193 uint8_t *end_; 194 size_t size_; 195 MemoryType mem_type_; 196 size_t index_; 197 198 size_t in_memory_trace_block_index_; 199 size_t offset_in_memory_trace_block_; 200 }; 201 202 struct MemoryTraceBlock { MemoryTraceBlockMemoryTraceBlock203 MemoryTraceBlock(uint8_t *start, size_t size) : start_(start), end_(start + size), size_(size) {} 204 205 uint8_t *start_; 206 uint8_t *end_; 207 size_t size_; 208 }; 209 210 using KernelMemoryTraceBlockPtr = std::shared_ptr<KernelMemoryTraceBlock>; 211 using MemoryTraceBlockPtr = std::shared_ptr<MemoryTraceBlock>; 212 213 class MemoryTraceManager { 214 public: GetInstance()215 static MemoryTraceManager &GetInstance() { 216 static MemoryTraceManager instance; 217 return instance; 218 } 219 220 void ReserveKernelMemoryBlocks(size_t size, const DeviceContext *device_context); 221 222 void PickMemoryTrackInfoForGraph(uint32_t graph_id); 223 224 void AddKernelMemoryTraceBlock(const KernelMemoryTraceBlockPtr &block, const DeviceContext *device_context); 225 226 const std::shared_ptr<std::map<const DeviceContext *, std::vector<MemoryTraceBlockPtr>>> &GetMergeBlocks(); 227 228 const std::shared_ptr<mindspore::HashMap<CNodePtr, std::vector<KernelMemoryTraceBlockPtr>>> &GetAllKernelBlocksnfo(); 229 230 void MergeBlocks(); 231 232 void Clear(); 233 234 private: 235 MemoryTraceManager() = default; 236 ~MemoryTraceManager() = default; 237 DISABLE_COPY_AND_ASSIGN(MemoryTraceManager); 238 239 void MergeBlocksForSameDeviceContext(std::vector<KernelMemoryTraceBlockPtr> *kernel_memory_trace_blocks, 240 std::vector<MemoryTraceBlockPtr> *merged_memory_trace_blocks); 241 242 std::shared_ptr<std::map<const DeviceContext *, std::vector<KernelMemoryTraceBlockPtr>>> kernel_memory_trace_blocks_; 243 std::shared_ptr<std::map<const DeviceContext *, std::vector<MemoryTraceBlockPtr>>> merged_memory_trace_blocks_; 244 std::shared_ptr<mindspore::HashMap<CNodePtr, std::vector<KernelMemoryTraceBlockPtr>>> kernel_to_block_; 245 246 std::map<uint32_t, std::shared_ptr<std::map<const DeviceContext *, std::vector<KernelMemoryTraceBlockPtr>>>> 247 graph_to_kernel_memory_trace_blocks_; 248 std::map<uint32_t, std::shared_ptr<std::map<const DeviceContext *, std::vector<MemoryTraceBlockPtr>>>> 249 graph_to_merged_memory_trace_blocks_; 250 std::map<uint32_t, std::shared_ptr<mindspore::HashMap<CNodePtr, std::vector<KernelMemoryTraceBlockPtr>>>> 251 graph_to_kernel_blocks_; 252 }; 253 254 // Encapsulate the actor APIs associated with execution. 255 class ActorDispatcher { 256 public: 257 template <typename T, typename Arg0, typename Arg1> Send(const AID & aid,void (T::* method)(Arg0),Arg1 && arg)258 static void Send(const AID &aid, void (T::*method)(Arg0), Arg1 &&arg) { 259 if (is_multi_thread_execution_) { 260 Async(aid, method, arg); 261 } else { 262 // The single thread execution doesn't need to switch threads and calls function directly. 263 auto actor_manager = ActorMgr::GetActorMgrRef(); 264 MS_EXCEPTION_IF_NULL(actor_manager); 265 auto base_actor = actor_manager->GetActor(aid); 266 T *actor = static_cast<T *>(base_actor.get()); 267 MS_EXCEPTION_IF_NULL(actor); 268 (actor->*method)(arg); 269 } 270 } 271 272 template <typename T, typename... Args0, typename... Args1> Send(const AID & aid,void (T::* method)(Args0...),Args1 &&...args)273 static void Send(const AID &aid, void (T::*method)(Args0...), Args1 &&... args) { 274 if (is_multi_thread_execution_) { 275 auto tuple = std::make_tuple(std::forward<Args1>(args)...); 276 Async(aid, method, std::move(tuple)); 277 } else { 278 // The single thread execution doesn't need to switch threads and calls function directly. 279 auto actor_manager = ActorMgr::GetActorMgrRef(); 280 MS_EXCEPTION_IF_NULL(actor_manager); 281 auto base_actor = actor_manager->GetActor(aid); 282 T *actor = static_cast<T *>(base_actor.get()); 283 MS_EXCEPTION_IF_NULL(actor); 284 (actor->*method)(std::forward<Args1>(args)...); 285 } 286 } 287 288 template <typename T, typename Arg0, typename Arg1> SendSync(const AID & aid,void (T::* method)(Arg0),Arg1 && arg)289 static void SendSync(const AID &aid, void (T::*method)(Arg0), Arg1 &&arg) { 290 auto actor_manager = ActorMgr::GetActorMgrRef(); 291 MS_EXCEPTION_IF_NULL(actor_manager); 292 auto base_actor = actor_manager->GetActor(aid); 293 T *actor = static_cast<T *>(base_actor.get()); 294 MS_EXCEPTION_IF_NULL(actor); 295 (actor->*method)(arg); 296 } 297 298 template <typename T, typename... Args0, typename... Args1> SendSync(const AID & aid,void (T::* method)(Args0...),Args1 &&...args)299 static void SendSync(const AID &aid, void (T::*method)(Args0...), Args1 &&... args) { 300 auto actor_manager = ActorMgr::GetActorMgrRef(); 301 auto base_actor = actor_manager->GetActor(aid); 302 T *actor = static_cast<T *>(base_actor.get()); 303 MS_EXCEPTION_IF_NULL(actor); 304 (actor->*method)(std::forward<Args1>(args)...); 305 } 306 307 template <typename T, typename... Args0, typename... Args1> SendSync(OpActor<DeviceTensor> * to_actor,void (T::* method)(Args0...),Args1 &&...args)308 static void SendSync(OpActor<DeviceTensor> *to_actor, void (T::*method)(Args0...), Args1 &&... args) { 309 T *actor = static_cast<T *>(to_actor); 310 MS_EXCEPTION_IF_NULL(actor); 311 (actor->*method)(std::forward<Args1>(args)...); 312 } 313 set_is_multi_thread_execution(bool is_multi_thread_execution)314 static void set_is_multi_thread_execution(bool is_multi_thread_execution) { 315 is_multi_thread_execution_ = is_multi_thread_execution; 316 } is_multi_thread_execution()317 static bool is_multi_thread_execution() { return is_multi_thread_execution_; } 318 set_enable_multi_stream(bool enable_multi_stream)319 static void set_enable_multi_stream(bool enable_multi_stream) { enable_multi_stream_ = enable_multi_stream; } enable_multi_stream()320 static bool enable_multi_stream() { return enable_multi_stream_; } 321 has_kernel_need_user_data()322 static bool has_kernel_need_user_data() { return has_kernel_need_user_data_; } set_has_kernel_need_user_data(bool has_kernel_need_user_data)323 static void set_has_kernel_need_user_data(bool has_kernel_need_user_data) { 324 has_kernel_need_user_data_ = has_kernel_need_user_data; 325 } 326 is_memory_allocation_sync()327 static bool is_memory_allocation_sync() { return is_memory_allocation_sync_; } set_is_memory_allocation_sync(bool is_memory_allocation_sync)328 static void set_is_memory_allocation_sync(bool is_memory_allocation_sync) { 329 is_memory_allocation_sync_ = is_memory_allocation_sync; 330 } 331 is_memory_free_sync()332 static bool is_memory_free_sync() { return is_memory_free_sync_; } set_is_memory_free_sync(bool is_memory_free_sync)333 static void set_is_memory_free_sync(bool is_memory_free_sync) { is_memory_free_sync_ = is_memory_free_sync; } 334 set_enable_runtime_multi_pipeline(bool enable_runtime_multi_pipeline)335 static void set_enable_runtime_multi_pipeline(bool enable_runtime_multi_pipeline) { 336 enable_runtime_multi_pipeline_ = enable_runtime_multi_pipeline; 337 } set_enable_static_shape(bool enable_static_shape)338 static void set_enable_static_shape(bool enable_static_shape) { enable_static_shape_ = enable_static_shape; } enable_static_shape()339 static bool enable_static_shape() { return enable_static_shape_; } enable_runtime_multi_pipeline()340 static bool enable_runtime_multi_pipeline() { return enable_runtime_multi_pipeline_; } 341 set_enable_async_launch_kernel(bool enable_async_launch_kernel)342 static void set_enable_async_launch_kernel(bool enable_async_launch_kernel) { 343 enable_async_launch_kernel_ = enable_async_launch_kernel; 344 } enable_async_launch_kernel()345 static bool enable_async_launch_kernel() { return enable_async_launch_kernel_; } 346 set_disable_kbk_sub_graph_execute(bool disable_kbk_sub_graph_execute)347 static void set_disable_kbk_sub_graph_execute(bool disable_kbk_sub_graph_execute) { 348 disable_kbk_sub_graph_execute_ = disable_kbk_sub_graph_execute; 349 } disable_kbk_sub_graph_execute()350 static bool disable_kbk_sub_graph_execute() { return disable_kbk_sub_graph_execute_; } 351 set_enable_trace_dynamic_memory(bool enable_trace_dynamic_memory)352 static void set_enable_trace_dynamic_memory(bool enable_trace_dynamic_memory) { 353 enable_trace_dynamic_memory_ = enable_trace_dynamic_memory; 354 } enable_trace_dynamic_memory()355 static bool enable_trace_dynamic_memory() { return enable_trace_dynamic_memory_; } 356 set_enable_use_trace_memory(bool enable_use_trace_memory)357 static void set_enable_use_trace_memory(bool enable_use_trace_memory) { 358 enable_use_trace_memory_ = enable_use_trace_memory; 359 } enable_use_trace_memory()360 static bool enable_use_trace_memory() { return enable_use_trace_memory_; } 361 362 // The first five executions are for warm-up, the next five executions are statistics of multi thread execution 363 // time, and the next next five executions are statistics of single thread execution time. The first 30 step which 364 // do search if there are cpu kernels. 365 static constexpr size_t kMultiThreadExecutionCountBegin{31}; 366 static constexpr size_t kMultiThreadExecutionCountEnd{40}; 367 static constexpr size_t kSingleThreadExecutionCountBegin{41}; 368 static constexpr size_t kSingleThreadExecutionCountEnd{50}; 369 // The single thread execution constraint. 370 static constexpr size_t kSingleThreadExecutionActorMaxNum{100}; 371 372 private: 373 ActorDispatcher() = default; 374 ~ActorDispatcher() = default; 375 DISABLE_COPY_AND_ASSIGN(ActorDispatcher); 376 377 // Decide whether use the multi thread to execute actors. 378 // There are scenarios with small network and data, and the performance of multi thread execution is not as good as 379 // that of single thread, so single thread execution is required at this time. 380 static bool is_multi_thread_execution_; 381 382 // Indicate whether use multi stream to execute. 383 static bool enable_multi_stream_; 384 385 // Indicate whether the actor set which is running contains kernel which need user data. 386 static bool has_kernel_need_user_data_; 387 388 // Decide whether alloc and free memory synchronously. 389 // The memory manager actor will not send and recv message if true. 390 static bool is_memory_allocation_sync_; 391 static bool is_memory_free_sync_; 392 393 static bool enable_runtime_multi_pipeline_; 394 static bool enable_static_shape_; 395 static bool enable_async_launch_kernel_; 396 static bool disable_kbk_sub_graph_execute_; 397 static bool enable_trace_dynamic_memory_; 398 static bool enable_use_trace_memory_; 399 }; 400 401 bool IsRunningFailed(const OpContext<DeviceTensor> *context); 402 403 void ComputeThreadNums(size_t *actor_thread_num, size_t *actor_and_kernel_thread_num); 404 405 bool IsDeviceQueueDSActor(const AnfNodePtr &node, GraphExecutionStrategy strategy = GraphExecutionStrategy::kPipeline); 406 407 // Host parameters are parameters of root funcgraph, in control flow, only the parameters of the root funcgraph are 408 // in the host data source. 409 bool IsHostQueueDSActor(const AnfNodePtr &node, const KernelGraphPtr &graph = nullptr, 410 const std::vector<AnfNodePtr> &host_parameters = {}, 411 GraphExecutionStrategy strategy = GraphExecutionStrategy::kPipeline); 412 413 bool IsCustomActor(const AnfNodePtr &node); 414 415 bool IsKernelActor(const AnfNodePtr &node, GraphExecutionStrategy strategy = GraphExecutionStrategy::kPipeline); 416 417 bool IsSwitchActor(const AnfNodePtr &node); 418 419 // The skip kernel doesn't run, it exists in the inplace optimizer. 420 bool IsSkippedKernelActor(const AnfNodePtr &node); 421 422 bool IsRpcActor(const AnfNodePtr &node); 423 424 bool IsInnerControlFlowActor(const AnfNodePtr &node); 425 // Internal parameter is not the origin parameter of func graph, it is the output of previous kernel graph which is 426 // related to the input of this kernel graph. 427 bool IsInternalParameter(const AnfNodePtr &node, const KernelGraphPtr &graph); 428 429 // Judge whether the device tensor of the node is persistent or not. 430 bool IsPersistentDeviceTensor(const AnfNodePtr &node); 431 432 bool IsControlFlowActor(KernelTransformType actor_type); 433 434 bool IsMemoryActor(KernelTransformType actor_type); 435 436 // Judge whether skip the launch by the env MS_KERNEL_LAUNCH_SKIP. 437 bool IsSkippedLaunch(const CNodePtr &kernel, const KernelGraphPtr &kernel_graph); 438 439 // Whether enable asynchronously infer shape and resize kernel mod by KernelInferActor and KernelResizeActor. 440 bool EnableAsyncInfer(); 441 442 bool EnableTraceMemory(); 443 444 void ResetTraceMemoryStatus(); 445 446 // Kernel by kernel sub graph execute mode need not send actor message by kernel actor, just launch all kernels in 447 // super kernel actor directly. 448 bool EnableKbkSubGraphExecute(); 449 450 // If enable async launch kernel, wait all kernels launch task finish. 451 // If enable infer->resize->launch pipeline, also wait all infer, resize and launch task finish. 452 bool WaitRuntimePipelineFinish(const OpContext<DeviceTensor> *context, bool wait_kernel_launch_finish = true); 453 454 size_t GetDefragMemoryStepFreq(); 455 456 // Copy data from src_device_tensor to dst_device_tensor. 457 bool Copy(const DeviceTensor *dst_device_tensor, const DeviceTensor *src_device_tensor); 458 459 void UpdateRefCount(DeviceTensor *const device_tensor, bool is_max_ref_count = false); 460 // Update the reference count of device tensor by the output index of node. 461 void UpdateRefCount(const AnfNodePtr &node, size_t output_idx, bool is_max_ref_count = false); 462 463 void FreeMemoryByDeviceContext(DeviceTensor *const device_tensor, const DeviceContext *device_context); 464 // The memory free for the pynative bprop graph which is managed by the value node. 465 void FreeMemoryByValueNode(const std::vector<std::weak_ptr<ValueNode>> &held_by_nodes, DeviceTensor *device_tensor); 466 467 KernelTransformType FetchKernelTransformType(const AnfNodePtr &node, const KernelGraphPtr &graph, 468 const std::vector<AnfNodePtr> &host_parameters = {}, 469 GraphExecutionStrategy strategy = GraphExecutionStrategy::kPipeline); 470 std::string FetchActorName(KernelTransformType kernel_type, const std::string &actor_set_name, 471 const AnfNodePtr &node = nullptr, const KernelGraphPtr &graph = nullptr); 472 473 // Fetch the input indexes which may be modified that exist in the input ref parameter. 474 std::set<size_t> FetchModifiableRefInputIndex(const CNodePtr &node); 475 // Fetch the output indexes which may be modified that exist in the ref node. 476 std::set<size_t> FetchModifiableRefOutputIndex(const CNodePtr &node, const KernelGraphPtr &graph); 477 478 // Check whether this process is parameter server and enable embedding cache. 479 bool is_embedding_cache_server(); 480 481 bool IsTwoPhaseInfer(); 482 std::string GetActorIdByKernel(const AnfNodePtr &node); 483 std::string GenerateActorIdByKernel(const AnfNodePtr &node); 484 } // namespace runtime 485 } // namespace mindspore 486 487 #endif // MINDSPORE_CCSRC_RUNTIME_FRAMEWORK_ACTOR_ACTOR_COMMON_H_ 488