| @@ -0,0 +1,144 @@ | |||||
| /** | |||||
| * Copyright 2021-2021 Huawei Technologies Co., Ltd | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| */ | |||||
| #include <gmock/gmock.h> | |||||
| #include <gtest/gtest.h> | |||||
| #include <vector> | |||||
| #define private public | |||||
| #define protected public | |||||
| #include "framework/common/taskdown_common.h" | |||||
| #include "hybrid/executor/rt_callback_manager.h" | |||||
| #include "hybrid/executor/subgraph_context.h" | |||||
| #include "hybrid/node_executor/aicore/aicore_node_executor.h" | |||||
| #include "init/gelib.h" | |||||
| #undef private | |||||
| #undef protected | |||||
| using namespace std; | |||||
| using namespace testing; | |||||
| namespace ge { | |||||
| using namespace hybrid; | |||||
| class UtestAiCoreNodeExecutor : public testing::Test { | |||||
| protected: | |||||
| void SetUp() {} | |||||
| void TearDown() {} | |||||
| }; | |||||
| static ge::OpDescPtr CreateOpDesc(string name = "", string type = "", | |||||
| int in_num = 0, int out_num = 0) { | |||||
| auto op_desc = std::make_shared<ge::OpDesc>(name, type); | |||||
| op_desc->SetStreamId(0); | |||||
| static int32_t index = 0; | |||||
| op_desc->SetId(index++); | |||||
| GeTensorDesc tensor(GeShape(), FORMAT_ND, DT_INT64); | |||||
| TensorUtils::SetSize(tensor, 64); | |||||
| vector<int64_t> input_offset; | |||||
| for (int i = 0; i < in_num; ++i) { | |||||
| op_desc->AddInputDesc(tensor); | |||||
| input_offset.emplace_back(index * 64 + i * 64); | |||||
| } | |||||
| op_desc->SetInputOffset(input_offset); | |||||
| vector<int64_t> output_offset; | |||||
| for (int i = 0; i < out_num; ++i) { | |||||
| op_desc->AddOutputDesc(tensor); | |||||
| output_offset.emplace_back(index * 64 + in_num * 64 + i * 64); | |||||
| } | |||||
| op_desc->SetOutputOffset(output_offset); | |||||
| op_desc->SetWorkspace({}); | |||||
| op_desc->SetWorkspaceBytes({}); | |||||
| ge::AttrUtils::SetStr(op_desc, ge::TVM_ATTR_NAME_MAGIC, | |||||
| "RT_DEV_BINARY_MAGIC_ELF_AIVEC"); | |||||
| bool support_dynamic = true; | |||||
| ge::AttrUtils::GetBool(op_desc, "support_dynamicshape", support_dynamic); | |||||
| return op_desc; | |||||
| } | |||||
| TEST_F(UtestAiCoreNodeExecutor, callback_success) { | |||||
| dlog_setlevel(0, 0, 0); | |||||
| std::unique_ptr<AiCoreOpTask> task1(new AiCoreOpTask()); | |||||
| OpDescPtr op_desc = CreateOpDesc("Add", "Add", 2, 1); | |||||
| ge::AttrUtils::SetInt(*op_desc, ge::ATTR_NAME_UNKNOWN_SHAPE_TYPE, | |||||
| DEPEND_SHAPE_RANGE); | |||||
| domi::TaskDef task_def; | |||||
| task_def.set_type(RT_MODEL_TASK_KERNEL); | |||||
| std::vector<uint8_t> args(100, 0); | |||||
| task_def.mutable_kernel()->set_args(args.data(), args.size()); | |||||
| task_def.mutable_kernel()->set_args_size(100); | |||||
| task_def.mutable_kernel()->mutable_context()->set_kernel_type( | |||||
| ccKernelType::TE); | |||||
| uint16_t args_offset = 20; | |||||
| char *a = reinterpret_cast<char *>(&args_offset); | |||||
| task_def.mutable_kernel()->mutable_context()->set_args_offset( | |||||
| a, 2 * sizeof(uint16_t)); | |||||
| EXPECT_EQ(task1->Init(*op_desc, task_def), ge::SUCCESS); | |||||
| ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test"); | |||||
| NodePtr node = graph->AddNode(op_desc); | |||||
| std::unique_ptr<NodeItem> new_node; | |||||
| ASSERT_EQ(NodeItem::Create(node, new_node), SUCCESS); | |||||
| NodeItem *node_item = new_node.get(); | |||||
| node_item->input_start = 0; | |||||
| node_item->output_start = 0; | |||||
| node_item->is_dynamic = true; | |||||
| node_item->shape_inference_type = DEPEND_SHAPE_RANGE; | |||||
| GraphItem graph_item; | |||||
| graph_item.node_items_.emplace_back(node_item); | |||||
| graph_item.total_inputs_ = 2; | |||||
| graph_item.total_outputs_ = 1; | |||||
| GeRootModelPtr ge_root_model = std::make_shared<GeRootModel>(graph); | |||||
| ge_root_model->SetModelName("test_name"); | |||||
| HybridModel hybrid_model(ge_root_model); | |||||
| GraphExecutionContext graph_context; | |||||
| graph_context.model = &hybrid_model; | |||||
| SubgraphContext subgraph_context(&graph_item, &graph_context); | |||||
| ASSERT_EQ(subgraph_context.Init(), SUCCESS); | |||||
| graph_context.callback_manager = | |||||
| std::unique_ptr<CallbackManager>(new CallbackManager()); | |||||
| auto node_state = subgraph_context.GetOrCreateNodeState(node_item); | |||||
| ASSERT_NE(node_state, nullptr); | |||||
| auto outputs_shape = | |||||
| reinterpret_cast<uint32_t(*)[1]>(task1->shape_buffer_->GetData()); | |||||
| outputs_shape[0][0] = 2; | |||||
| outputs_shape[0][1] = 1; | |||||
| outputs_shape[0][2] = 2; | |||||
| std::vector<std::unique_ptr<AiCoreOpTask>> tasks; | |||||
| tasks.emplace_back(std::move(task1)); | |||||
| std::unique_ptr<AiCoreNodeTask> aicore_node_task; | |||||
| aicore_node_task.reset(new (std::nothrow) AiCoreNodeTask(std::move(tasks))); | |||||
| ASSERT_EQ( | |||||
| aicore_node_task->ExecuteAsync(*node_state->GetTaskContext(), nullptr), | |||||
| SUCCESS); | |||||
| std::pair<rtEvent_t, std::pair<rtCallback_t, void *>> entry; | |||||
| node_state->GetTaskContext() | |||||
| ->execution_context_->callback_manager->callback_queue_.Pop(entry); | |||||
| auto cb_func = entry.second.first; | |||||
| auto cb_args = entry.second.second; | |||||
| cb_func(cb_args); | |||||
| dlog_setlevel(0, 3, 0); | |||||
| } | |||||
| } // namespace ge | |||||