| 995 | } |
| 996 | |
| 997 | bool CPURunner::BindNodeOps(Subgraph* sub_graph) |
| 998 | { |
| 999 | std::vector<Node*>& seq_nodes = sub_graph->seq_nodes; |
| 1000 | int node_size = seq_nodes.size(); |
| 1001 | |
| 1002 | const ExecAttr* exec_attr = any_cast<const ExecAttr*>(sub_graph->GetAttr("exec_attr")); |
| 1003 | |
| 1004 | for(int i = 0; i < node_size; i++) |
| 1005 | { |
| 1006 | Node* node = seq_nodes[i]; |
| 1007 | Operator* op = node->GetOp(); |
| 1008 | |
| 1009 | if(op->GetName() == "Const" || op->GetName() == "Input") |
| 1010 | continue; |
| 1011 | |
| 1012 | node->SetAttr(ATTR_EXEC_ATTR, exec_attr); |
| 1013 | |
| 1014 | NodeOps* node_ops; |
| 1015 | |
| 1016 | node_ops = BindCustomKernel(node); |
| 1017 | |
| 1018 | if(node_ops == nullptr) |
| 1019 | { |
| 1020 | if(get_tengine_errno() == ENOTRECOVERABLE) |
| 1021 | { |
| 1022 | /* force to use custom kernel */ |
| 1023 | return false; |
| 1024 | } |
| 1025 | else |
| 1026 | { |
| 1027 | node_ops = NodeOpsRegistryManager::FindNodeOps(cpu_info_, node); |
| 1028 | } |
| 1029 | } |
| 1030 | |
| 1031 | if(node_ops == nullptr) |
| 1032 | { |
| 1033 | LOG_ERROR() << "failed to set node ops for node: " << node->GetName() << " op: " << op->GetName() << "\n"; |
| 1034 | return false; |
| 1035 | } |
| 1036 | |
| 1037 | auto dispatch = std::bind(&CPUDevice::PushAiderTask, cpu_dev_, std::placeholders::_1, std::placeholders::_2); |
| 1038 | |
| 1039 | auto wait = std::bind(&CPUDevice::WaitDone, cpu_dev_); |
| 1040 | |
| 1041 | node_ops->SetHelper(mem_alloc, mem_free, dispatch, wait); |
| 1042 | |
| 1043 | node->SetAttr(ATTR_NODE_OPS, node_ops); |
| 1044 | |
| 1045 | node_ops->exec_attr = exec_attr; |
| 1046 | |
| 1047 | node_ops->OnBind(node); |
| 1048 | } |
| 1049 | |
| 1050 | return true; |
| 1051 | } |
| 1052 | |
| 1053 | void CPURunner::AttachCPUDevice(CPUDevice* cpu_dev) |
| 1054 | { |