* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ------------------------------------------------------------------------- */
#include "runtime/inject_helpers/ArgsContext.h"
#define private public
#include "runtime/inject_helpers/KernelContext.h"
#undef private
#include <elf.h>
#include <string>
#include <vector>
#include <sys/stat.h>
#include <sys/types.h>
#include <gtest/gtest.h>
#include "acl_rt_impl/AscendclImplOrigin.h"
#include "runtime/RuntimeOrigin.h"
#include "utils/ElfLoader.h"
#include "utils/FileSystem.h"
#include "utils/PipeCall.h"
#include "mockcpp/mockcpp.hpp"
#include "runtime/inject_helpers/ArgsContext.h"
#include "runtime/inject_helpers/MemoryDataCollect.h"
#include "runtime/inject_helpers/RegisterContext.h"
#include "runtime/inject_helpers/LaunchManager.h"
#include "runtime/inject_helpers/DeviceContext.h"
#include "runtime/inject_helpers/ArgsManager.h"
#include "core/FuncSelector.h"
using namespace std;
constexpr mode_t EXEC_AUTHORITY = 0740;
namespace {
class KernelContextTest : public testing::Test {
public:
static void SetUpTestCase() {}
void SetUp() override
{
KernelContext::Instance().Reset();
}
void TearDown() override
{
KernelContext::Instance().Reset();
GlobalMockObject::verify();
ArgsManager::Instance().Clear();
LaunchManager::Local().Clear();
}
};
aclError AclrtMallocHostStub(void **hostPtr, size_t size) {
*hostPtr = malloc(size);
return ACL_ERROR_NONE;
}
aclError AclrtFreeHostStub(void *hostPtr) {
free(hostPtr);
return ACL_ERROR_NONE;
}
rtError_t RtMemcpyStub(void *dst, uint64_t destMax, const void *src, uint64_t cnt, rtMemcpyKind_t kind)
{
copy_n(static_cast<const uint8_t*>(src), cnt, static_cast<uint8_t*>(dst));
return RT_ERROR_NONE;
}
aclError MemcpyStub(void *dst, size_t destMax, const void *src, size_t count, aclrtMemcpyKind kind)
{
copy_n(static_cast<const uint8_t*>(src), count, static_cast<uint8_t*>(dst));
return RT_ERROR_NONE;
}
RTS_API rtError_t RtMallocHostStub(void **hostPtr, uint64_t size, uint16_t moduleId)
{
*hostPtr = malloc(size);
return RT_ERROR_NONE;
}
rtError_t RtFreeHostStub(void *hostPtr)
{
free(hostPtr);
return RT_ERROR_NONE;
}
vector<uint8_t> MockDyanmicAscendcKernelMetaSection()
{
vector<uint8_t> metaData;
const static uint32_t DATA[] = {
0x01000400, 0x03000000, 0x04005c00, 0x00050002,
0x00000000, 0x00010002, 0xffffffff, 0xffffffff,
0x00050002, 0x00000000, 0x00010002, 0xffffffff,
0xffffffff, 0x00050002, 0x00000000, 0x00010003,
0xffffffff, 0xffffffff, 0x00050001, 0x00000000,
0x00010004, 0x00050002, 0x00000000, 0x00010007,
0x00000000, 0x00000010, 0x08000400, 0x100b0000,
};
int num = sizeof(DATA);
const uint8_t *src = reinterpret_cast<const uint8_t*>(DATA);
for (int i = 0; i < num / sizeof(uint32_t); i++) {
metaData.push_back(static_cast<uint8_t>((DATA[i] >> 24) & 0xFF));
metaData.push_back(static_cast<uint8_t>((DATA[i] >> 16) & 0xFF));
metaData.push_back(static_cast<uint8_t>((DATA[i] >> 8) & 0xFF));
metaData.push_back(static_cast<uint8_t>(DATA[i] & 0xFF));
}
return metaData;
}
}
TEST_F(KernelContextTest, save_null_args_expect_return_and_got_empty_mem_info)
{
string tempOutput = "temp_test_dir";
auto &inst = KernelContext::Instance();
inst.Reset();
inst.SetArgsSize(nullptr);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos.size(), 0);
}
TEST_F(KernelContextTest, save_multi_args_expect_return_and_got_multi_mem_info)
{
string tempOutput = "temp_test_dir";
auto &inst = KernelContext::Instance();
rtArgsSizeInfo sizeInfo;
vector<uint64_t> sizeInfoData{1717, 11ULL<<32|2, 64, 128};
sizeInfo.infoAddr = sizeInfoData.data();
sizeInfo.atomicIndex = 0;
inst.SetArgsSize(&sizeInfo);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos.size(), 2);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos[0].length, 64);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos[1].length, 128);
}
TEST_F(KernelContextTest, save_dump_null_args_expect_return_and_no_data_dump)
{
string tempOutput = "temp_test_dir";
auto &inst = KernelContext::Instance();
inst.AddLaunchEvent(nullptr, 0, 1, nullptr, nullptr);
MkdirRecusively(tempOutput);
KernelContext::ContextConfig config;
inst.GetDeviceContext().DumpKernelArgs(tempOutput, 0, config);
ASSERT_FALSE(IsPathExists(tempOutput + "input_0.bin"));
inst.Reset();
RemoveAll(tempOutput);
}
TEST_F(KernelContextTest, fake_sink_kernel_args_then_dump_kernel_args_expect_return_true)
{
string tempOutput = "temp_test_dir";
MOCKER_CPP(&KernelContext::DeviceContext::GetPcStartAddr,
bool(KernelContext::DeviceContext::*)(KernelContext::KernelHandleArgs const &, uint64_t&) const)
.stubs().will(returnValue(true));
MOCKER(&KernelContext::GetNameByTilingKey).stubs().will(returnValue(string("kernelName")));
MOCKER(&aclrtMemcpyImplOrigin).stubs().will(invoke(MemcpyStub));
MOCKER(&aclrtMallocHostImplOrigin).stubs().will(invoke(AclrtMallocHostStub));
MOCKER(&aclrtFreeHostImplOrigin).stubs().will(invoke(AclrtFreeHostStub));
auto &inst = KernelContext::Instance();
uint32_t stm{};
auto &streamInfo = LaunchManager::GetOrCreateStreamInfo(&stm);
streamInfo.binded = true;
rtArgsEx_t argsInfo{};
vector<uint64_t> argsPtr(3);
vector<vector<uint64_t>> argsData(argsPtr.size(), vector<uint64_t>(100, 1));
for (int i = 0; i < argsPtr.size(); i++) {
argsPtr[i] = reinterpret_cast<uint64_t>(&argsData[i]);
}
argsInfo.args = static_cast<void *>(argsPtr.data());
inst.AddLaunchEvent(nullptr, 0, 1, &argsInfo, &stm);
auto &memInfo = inst.GetOpMemInfo();
memInfo.inputParamsAddrInfos.push_back(KernelContext::AddrInfo{0, 1, MemInfoSrc::EXTRA});
memInfo.inputParamsAddrInfos.push_back(KernelContext::AddrInfo{0, 2, MemInfoSrc::EXTRA});
memInfo.inputParamsAddrInfos.push_back(KernelContext::AddrInfo{0, 3, MemInfoSrc::EXTRA});
inst.GetDeviceContext().ArchiveMemInfo();
MkdirRecusively(tempOutput);
KernelContext::ContextConfig config;
ASSERT_TRUE(inst.GetDeviceContext().DumpKernelArgs(tempOutput, 0, config));
ASSERT_TRUE(IsPathExists(tempOutput + "/input_0.bin"));
RemoveAll(tempOutput);
}
TEST_F(KernelContextTest, fake_zero_length_sink_kernel_args_then_dump_kernel_args_expect_return_true)
{
string tempOutput = "temp_test_dir";
MOCKER_CPP(&KernelContext::DeviceContext::GetPcStartAddr,
bool(KernelContext::DeviceContext::*)(KernelContext::KernelHandleArgs const &, uint64_t&) const)
.stubs().will(returnValue(true));
MOCKER(&KernelContext::GetNameByTilingKey).stubs().will(returnValue(string("kernelName")));
MOCKER(&aclrtMemcpyImplOrigin).stubs().will(invoke(MemcpyStub));
MOCKER(&aclrtMallocHostImplOrigin).stubs().will(invoke(AclrtMallocHostStub));
MOCKER(&aclrtFreeHostImplOrigin).stubs().will(invoke(AclrtFreeHostStub));
auto &inst = KernelContext::Instance();
uint32_t stm{};
auto &streamInfo = LaunchManager::GetOrCreateStreamInfo(&stm);
streamInfo.binded = true;
rtArgsEx_t argsInfo{};
vector<uint64_t> argsPtr(1);
vector<vector<uint64_t>> argsData(argsPtr.size(), vector<uint64_t>(100, 0));
for (int i = 0; i < argsPtr.size(); i++) {
argsPtr[i] = reinterpret_cast<uint64_t>(&argsData[i]);
}
argsInfo.args = static_cast<void *>(argsPtr.data());
inst.AddLaunchEvent(nullptr, 0, 1, &argsInfo, &stm);
auto &memInfo = inst.GetOpMemInfo();
memInfo.inputParamsAddrInfos.push_back(KernelContext::AddrInfo{0, 0, MemInfoSrc::EXTRA});
inst.GetDeviceContext().ArchiveMemInfo();
MkdirRecusively(tempOutput);
KernelContext::ContextConfig config;
ASSERT_TRUE(inst.GetDeviceContext().DumpKernelArgs(tempOutput, 0, config));
ASSERT_FALSE(IsPathExists(tempOutput + "/input_0.bin"));
RemoveAll(tempOutput);
}
TEST_F(KernelContextTest, save_dump_valid_args_expect_return_and_normal_data_dump)
{
string tempOutput = "temp_test_dir/";
auto &inst = KernelContext::Instance();
MkdirRecusively(tempOutput);
MOCKER(&rtMemcpyOrigin).stubs().will(invoke(RtMemcpyStub));
MOCKER(&rtMallocHostOrigin).stubs().will(invoke(RtMallocHostStub));
MOCKER(&rtFreeHostOrigin).stubs().will(invoke(RtFreeHostStub));
MOCKER(&aclrtMemcpyImplOrigin).stubs().will(invoke(MemcpyStub));
MOCKER(&aclrtMallocHostImplOrigin).stubs().will(invoke(AclrtMallocHostStub));
MOCKER(&aclrtFreeHostImplOrigin).stubs().will(invoke(AclrtFreeHostStub));
int argsNum = 2;
uint64_t skipNum = 0;
int argsSize0 = 64, argsSize1 = 128;
int tilingSize = 256;
rtArgsSizeInfo sizeInfo;
vector<uint64_t> sizeInfoData{1717, skipNum<<32|argsNum, argsSize0, argsSize1};
sizeInfo.infoAddr = sizeInfoData.data();
sizeInfo.atomicIndex = 0;
inst.SetArgsSize(&sizeInfo);
vector<uint64_t> argsBuff(argsNum + tilingSize / sizeof(uint64_t), 12);
vector<uint8_t> args0(argsSize0 / sizeof(uint8_t));
vector<uint8_t> args1(argsSize1 / sizeof(uint8_t));
argsBuff[0] = (uint64_t)args0.data();
argsBuff[1] = (uint64_t)args1.data();
rtArgsEx_t argsInfo;
argsInfo.args = argsBuff.data();
argsInfo.tilingDataOffset = argsNum * 8;
argsInfo.tilingAddrOffset = 0;
argsInfo.argsSize = argsBuff.size() * sizeof(uint64_t);
rtDevBinary_t binary;
inst.ParseMetaDataFromBinary(binary, &argsInfo);
inst.ArchiveMemInfo();
inst.AddLaunchEvent(nullptr, 0, 1, &argsInfo, nullptr);
KernelContext::ContextConfig config;
inst.GetDeviceContext().DumpKernelArgs(tempOutput, 0, config);
ASSERT_TRUE(IsPathExists(tempOutput + "input_0.bin"));
ASSERT_TRUE(IsPathExists(tempOutput + "input_1.bin"));
ASSERT_TRUE(IsPathExists(tempOutput + "input_tiling.bin"));
RemoveAll(tempOutput);
inst.Reset();
}
TEST_F(KernelContextTest, build_names_with_valid_kernel_binary_expect_get_kernel_name_by_tiling_key_success)
{
KernelContext::Instance().Reset();
string mockContent = ("0000 g F .text 0000a8 Abs_d2db_high_performance_21474\n"
"0010 g F .text 0000f8 Abs_cc2c_high_performance_3333\n"
"0020 g F .text 000af8 Abs_dd3d_high_performance_4444\n");
MOCKER(&PipeCall).stubs().with(any(), outBound(mockContent)).will(returnValue(true));
char *ascendHomePath = "ascend_home_path";
MOCKER(&secure_getenv).stubs().will(returnValue(ascendHomePath));
string mocKObjdumpDir = JoinPath({ascendHomePath, "compiler", "ccec_compiler", "bin"});
MkdirRecusively(mocKObjdumpDir);
string mocKObjdumpPath = JoinPath({mocKObjdumpDir, "llvm-objdump"});
WriteBinary(mocKObjdumpPath, mockContent.data(), mockContent.length());
chmod(mocKObjdumpPath.c_str(), EXEC_AUTHORITY);
ASSERT_TRUE(IsPathExists(mocKObjdumpPath));
MOCKER(&WriteBinary).stubs().will(returnValue(1UL));
auto &inst = KernelContext::Instance();
string tempOutput = "temp_test_dir/";
vector<uint8_t> hdlData(tempOutput.size());
void *handle = hdlData.data();
rtDevBinary_t bin;
bin.data = mockContent.data();
bin.length = mockContent.length();
inst.AddHdlRegisterEvent(handle, &bin);
uint64_t tilignKey = 21474;
string expect = "Abs_d2db_high_performance_21474";
string got = inst.GetNameByTilingKey(handle, tilignKey);
ASSERT_EQ(expect, got);
tilignKey = 3333;
expect = "Abs_cc2c_high_performance_3333";
got = inst.GetNameByTilingKey(handle, tilignKey);
ASSERT_EQ(expect, got);
tilignKey = 4444;
expect = "Abs_dd3d_high_performance_4444";
got = inst.GetNameByTilingKey(handle, tilignKey);
ASSERT_EQ(expect, got);
RemoveAll(mocKObjdumpDir);
}
TEST_F(KernelContextTest, input_null_then_call_add_register_event_expect_return)
{
uint64_t originSize = KernelContext::Instance().GetNextRegisterId();
KernelContext::Instance().AddHdlRegisterEvent(nullptr, nullptr);
ASSERT_EQ(KernelContext::Instance().GetNextRegisterId(), originSize);
}
TEST_F(KernelContextTest, setDeviceId_return_value_without_convert)
{
DeviceContext::Local().SetDeviceId(10);
MOCKER(&IsOpProf).stubs().will(returnValue(true));
MessageOfProfConfig config;
config.isSimulator = true;
ProfConfig::Instance().Init(config);
ASSERT_EQ(10, DeviceContext::Local().GetDeviceId());
}
TEST_F(KernelContextTest, input_no_register_event_then_save_expect_false)
{
KernelContext::Instance().Reset();
ASSERT_FALSE(KernelContext::Instance().Save(""));
}
TEST_F(KernelContextTest, input_no_launch_event_then_save_expect_false)
{
KernelContext::Instance().Reset();
vector<uint8_t> handleData{1, 2, 3};
const KernelHandle *hdl = handleData.data();
rtDevBinary_t bin{};
KernelContext::Instance().AddHdlRegisterEvent(hdl, &bin);
ASSERT_FALSE(KernelContext::Instance().Save(""));
}
TEST_F(KernelContextTest, mock_reg_launch_event_then_save_expect_true)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_RESERVED));
uint64_t originLaunchSize = KernelContext::Instance().GetDeviceContext().launchEvents_.size();
uint64_t originRegisterSize = KernelContext::Instance().registerEvents_.size();
bool(KernelContext::*funcPtr)(uint64_t, const string&) = &KernelContext::DumpKernelObject;
MOCKER(funcPtr).stubs().will(returnValue(true));
MOCKER(&KernelContext::DeviceContext::DumpKernelArgs).stubs().will(returnValue(true));
MOCKER(&GetSymInfoFromBinary).stubs().will(returnValue(true));
nlohmann::json jsonData;
jsonData["bin_path"] = "abc";
MOCKER(&KernelContext::ContextConfig::ToJson).stubs().with(outBound(jsonData)).will(returnValue(true));
MOCKER(&WriteBinary).stubs().will(returnValue(jsonData.dump().length()));
KernelContext::Instance().ArchiveMemInfo();
vector<uint8_t> handleData{1, 2, 3};
const KernelHandle *hdl = handleData.data();
rtDevBinary_t bin;
vector<char> data(8, 1);
bin.data = data.data();
bin.length = data.size();
bin.magic = 15;
KernelContext::Instance().AddHdlRegisterEvent(hdl, &bin);
KernelContext::Instance().AddLaunchEvent(hdl, 111, 8, nullptr, nullptr);
auto launchId = KernelContext::Instance().GetLaunchId();
EXPECT_EQ(KernelContext::Instance().GetDeviceContext().launchEvents_.size(), originLaunchSize + 1);
EXPECT_EQ(KernelContext::Instance().registerEvents_.size(), originRegisterSize + 1);
EXPECT_TRUE(KernelContext::Instance().Save("./", launchId));
EXPECT_TRUE(KernelContext::Instance().SaveAicore("./", launchId));
}
TEST_F(KernelContextTest, set_null_hdl_then_test_dump_kernel_object_expect_fail)
{
EXPECT_FALSE(KernelContext::Instance().DumpKernelObject(nullptr, "", ""));
}
size_t CheckResult(const string &filename, const char *data, uint64_t length)
{
Elf64_Ehdr header{};
vector<char> buffer(data, data + length);
EXPECT_TRUE(ElfLoader::LoadHeader(buffer, header));
EXPECT_EQ(header.e_flags, FLAG_A2_AIV);
return length;
}
TEST_F(KernelContextTest, runtime_get_pcstart_failed_expect_get_pcstart_by_stub_func_fail)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_RESERVED));
uint64_t pcStartAddr;
ASSERT_FALSE(KernelContext::Instance().GetPcStartAddr(KernelContext::StubFuncPtr{nullptr}, pcStartAddr));
}
TEST_F(KernelContextTest, call_rtKernelGetAddrAndPrefCntOrigin_failed_expect_get_pcstart_by_stub_func_fail)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_RESERVED));
auto &context = KernelContext::Instance();
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::StubFuncPtr{nullptr}, pcStartAddr));
}
TEST_F(KernelContextTest, get_stub_func_info_failed_expect_get_pcstart_by_stub_func_fail)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_NONE));
MOCKER(&KernelContext::GetStubFuncInfo).stubs().will(returnValue(false));
auto &context = KernelContext::Instance();
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::StubFuncPtr{nullptr}, pcStartAddr));
}
TEST_F(KernelContextTest, get_register_event_failed_expect_get_pcstart_by_stub_func_fail)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_NONE));
MOCKER(&KernelContext::GetStubFuncInfo).stubs().will(returnValue(true));
MOCKER(&KernelContext::GetRegisterEvent).stubs().will(returnValue(false));
auto &context = KernelContext::Instance();
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::StubFuncPtr{nullptr}, pcStartAddr));
}
TEST_F(KernelContextTest, register_binary_with_empty_kernel_names_expect_get_pcstart_by_stub_func_fail)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_NONE));
MOCKER(&KernelContext::GetStubFuncInfo).stubs().will(returnValue(true));
MOCKER(&KernelContext::GetRegisterEvent).stubs().will(returnValue(true));
MOCKER(&GetSymInfoFromBinary).stubs();
auto &context = KernelContext::Instance();
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::StubFuncPtr{nullptr}, pcStartAddr));
}
bool GetValidNameFromBinary(const char *data,
uint64_t length,
std::vector<std::string> &kernelNames,
std::vector<uint64_t> &kernelOffsets)
{
kernelNames.emplace_back("valid_kernel_1234_mix_aic");
kernelOffsets.emplace_back(0);
return true;
}
TEST_F(KernelContextTest, register_binary_with_valid_kernel_names_expect_get_pcstart_by_stub_func_success)
{
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_NONE));
MOCKER(&GetSymInfoFromBinary).stubs().will(invoke(GetValidNameFromBinary));
auto &context = KernelContext::Instance();
auto hdl = reinterpret_cast<KernelHandle const *>(0x1234);
rtDevBinary_t bin {};
context.AddHdlRegisterEvent(hdl, &bin);
context.AddFuncRegisterEvent(hdl, nullptr, "valid_kernel_1234_mix_aic", "valid_kernel_1234_mix_aic", 0);
uint64_t pcStartAddr;
ASSERT_TRUE(context.GetPcStartAddr(KernelContext::StubFuncPtr{nullptr}, pcStartAddr));
context.Reset();
}
TEST_F(KernelContextTest, hdl_to_regid_empty_expect_get_pcstart_by_hdl_fail)
{
uint64_t pcStartAddr;
ASSERT_FALSE(KernelContext::Instance().GetPcStartAddr(KernelContext::KernelHandlePtr{nullptr}, pcStartAddr));
}
TEST_F(KernelContextTest, register_binary_with_empty_kernel_names_expect_get_pcstart_by_hdl_fail)
{
std::vector<std::string> kernelNames;
MOCKER(&GetSymInfoFromBinary).stubs().will(returnValue(true));
auto &context = KernelContext::Instance();
auto hdl = reinterpret_cast<KernelHandle const *>(0x1234);
rtDevBinary_t bin {};
context.AddHdlRegisterEvent(hdl, &bin);
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::KernelHandlePtr{hdl}, pcStartAddr));
}
bool GetInvalidNameFromBinary(const char *data,
uint64_t length,
std::vector<std::string> &kernelNames,
std::vector<uint64_t> &kernelOffsets)
{
kernelNames.emplace_back("invalidkernel_mix_aic");
kernelOffsets.emplace_back(0);
return true;
}
TEST_F(KernelContextTest, register_binary_with_invalid_kernel_names_expect_get_pcstart_by_hdl_fail)
{
MOCKER(&GetSymInfoFromBinary).stubs().will(invoke(GetInvalidNameFromBinary));
auto &context = KernelContext::Instance();
auto hdl = reinterpret_cast<KernelHandle const *>(0x1234);
rtDevBinary_t bin {};
context.AddHdlRegisterEvent(hdl, &bin);
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::KernelHandlePtr{hdl}, pcStartAddr));
}
TEST_F(KernelContextTest, register_binary_with_valid_kernel_names_expect_get_pcstart_by_hdl_success)
{
MOCKER(&GetSymInfoFromBinary).stubs().will(invoke(GetValidNameFromBinary));
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_NONE));
auto &context = KernelContext::Instance();
auto hdl = reinterpret_cast<KernelHandle const *>(0x1234);
rtDevBinary_t bin {};
context.AddHdlRegisterEvent(hdl, &bin);
uint64_t pcStartAddr;
ASSERT_TRUE(context.GetPcStartAddr(KernelContext::KernelHandlePtr{hdl}, pcStartAddr));
}
TEST_F(KernelContextTest, runtime_get_pcstart_failed_expect_get_pcstart_by_hdl_fail)
{
MOCKER(&GetSymInfoFromBinary).stubs().will(invoke(GetValidNameFromBinary));
MOCKER(&rtKernelGetAddrAndPrefCntOrigin).stubs().will(returnValue(RT_ERROR_RESERVED));
auto &context = KernelContext::Instance();
auto hdl = reinterpret_cast<KernelHandle const *>(0x1234);
rtDevBinary_t bin {};
context.AddHdlRegisterEvent(hdl, &bin);
uint64_t pcStartAddr;
ASSERT_FALSE(context.GetPcStartAddr(KernelContext::KernelHandlePtr{hdl}, pcStartAddr));
}
TEST_F(KernelContextTest, add_launch_event_then_test_get_dev_binary_expect_success)
{
vector<uint8_t> handleData{1, 2, 3};
const KernelHandle *hdl = handleData.data();
rtDevBinary_t bin;
vector<char> data(8, 1);
bin.data = data.data();
bin.length = data.size();
bin.magic = 15;
KernelContext::Instance().AddHdlRegisterEvent(hdl, &bin);
KernelContext::Instance().AddLaunchEvent(hdl, 111, 8, nullptr, nullptr);
EXPECT_TRUE(KernelContext::Instance().GetDevBinary(KernelContext::KernelHandlePtr{hdl}, bin));
}
TEST_F(KernelContextTest, add_stub_launch_event_then_test_get_dev_binary_expect_success)
{
vector<uint8_t> handleData{1, 2, 3};
const StubFunc *hdl = handleData.data();
rtDevBinary_t bin;
vector<char> data(8, 1);
bin.data = data.data();
bin.length = data.size();
bin.magic = 15;
KernelContext::Instance().AddHdlRegisterEvent(hdl, &bin);
KernelContext::Instance().AddFuncRegisterEvent(hdl, hdl, nullptr, nullptr, 0);
KernelContext::Instance().AddLaunchEvent(hdl, 8, nullptr, nullptr);
EXPECT_TRUE(KernelContext::Instance().GetDevBinary(KernelContext::StubFuncPtr{hdl}, bin));
}
void GetContextConfig(KernelContext::ContextConfig &config, int magic)
{
config.binPath = "aicore.0.bin";
config.blockDim = 8;
config.visibleDevId = 1;
config.devId = 0;
config.isFFTS = true;
config.inputPathList = {"input1", "input2", "input3"};
config.inputSizeList = {8, 16, 0};
config.kernelName = "mix_abc";
config.magic = magic;
config.tilingDataPath = "tiling_data.path";
config.tilingDataSize = 200;
config.hasTilingKey = true;
config.tilingKey = 111;
}
TEST_F(KernelContextTest, input_valid_config_then_call_to_json_expect_correct_result)
{
KernelContext::ContextConfig config;
GetContextConfig(config, rtDevBinaryMagicElfAivec);
nlohmann::json jsonData;
ASSERT_TRUE(config.ToJson(jsonData));
string expect = R"+*({"bin_path":"aicore.0.bin","block_dim":"8","device_id":"0",)+*";
expect += R"+*("ffts":"Y","input_path":"input1;input2;input3","input_size":"8;16;0",)+*";
expect += R"+*("kernel_name":"mix_abc","magic":"RT_DEV_BINARY_MAGIC_ELF_AIVEC",)+*";
expect += R"+*("tiling_data_path":"tiling_data.path;200","tiling_key":"111"})+*";
string result = jsonData.dump();
EXPECT_EQ(result, expect);
}
TEST_F(KernelContextTest, input_valid_aicube_config_then_call_to_json_expect_correct_result)
{
KernelContext::ContextConfig config;
GetContextConfig(config, rtDevBinaryMagicElfAicube);
nlohmann::json jsonData;
ASSERT_TRUE(config.ToJson(jsonData));
string expect = R"+*({"bin_path":"aicore.0.bin","block_dim":"8","device_id":"0",)+*";
expect += R"+*("ffts":"Y","input_path":"input1;input2;input3","input_size":"8;16;0",)+*";
expect += R"+*("kernel_name":"mix_abc","magic":"RT_DEV_BINARY_MAGIC_ELF_AICUBE",)+*";
expect += R"+*("tiling_data_path":"tiling_data.path;200","tiling_key":"111"})+*";
string result = jsonData.dump();
EXPECT_EQ(result, expect);
}
TEST_F(KernelContextTest, input_valid_mix_config_then_call_to_json_expect_correct_result)
{
KernelContext::ContextConfig config;
GetContextConfig(config, rtDevBinaryMagicElf);
nlohmann::json jsonData;
ASSERT_TRUE(config.ToJson(jsonData));
string expect = R"+*({"bin_path":"aicore.0.bin","block_dim":"8","device_id":"0",)+*";
expect += R"+*("ffts":"Y","input_path":"input1;input2;input3","input_size":"8;16;0",)+*";
expect += R"+*("kernel_name":"mix_abc","magic":"RT_DEV_BINARY_MAGIC_ELF",)+*";
expect += R"+*("tiling_data_path":"tiling_data.path;200","tiling_key":"111"})+*";
string result = jsonData.dump();
EXPECT_EQ(result, expect);
}
TEST_F(KernelContextTest, input_empty_tiling_config_then_call_to_json_expect_correct_result)
{
KernelContext::ContextConfig config;
GetContextConfig(config, rtDevBinaryMagicElf);
config.tilingDataPath.clear();
nlohmann::json jsonData;
ASSERT_TRUE(config.ToJson(jsonData));
string expect = R"+*({"bin_path":"aicore.0.bin","block_dim":"8","device_id":"0",)+*";
expect += R"+*("ffts":"Y","input_path":"input1;input2;input3","input_size":"8;16;0",)+*";
expect += R"+*("kernel_name":"mix_abc","magic":"RT_DEV_BINARY_MAGIC_ELF",)+*";
expect += R"+*("tiling_key":"111"})+*";
string result = jsonData.dump();
EXPECT_EQ(result, expect);
}
TEST_F(KernelContextTest, GetStubFuncInfo_return_false)
{
KernelContext::StubFuncPtr stubFunc;
KernelContext::StubFuncInfo stubFuncInfo;
KernelContext::Instance().stubInfo_;
KernelContext::Instance().GetStubFuncInfo(stubFunc, stubFuncInfo);
}
TEST_F(KernelContextTest, input_no_launch_event_then_save_aicore_expect_false)
{
KernelContext::Instance().Reset();
vector<uint8_t> handleData{1, 2, 3};
const KernelHandle *hdl = handleData.data();
rtDevBinary_t bin{};
KernelContext::Instance().AddHdlRegisterEvent(hdl, &bin);
ASSERT_FALSE(KernelContext::Instance().SaveAicore(""));
}
TEST_F(KernelContextTest, get_dump_context_bin_is_nullptr)
{
KernelContext::Instance().Reset();
rtDevBinary_t binary;
binary.data = nullptr;
binary.length = 0;
KernelContext::Instance().ParseMetaDataFromBinary(binary);
ASSERT_TRUE(KernelContext::Instance().GetOpMemInfo().inputParamsAddrInfos.empty());
}
TEST_F(KernelContextTest, get_dump_context_dynamic_kernel)
{
KernelContext::Instance().Reset();
rtDevBinary_t binary;
std::vector<uint8_t> metaData = {0x01, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
0x00, 00, 00, 04, 00, 0x50, 00, 00, 0x05, 00, 02, 00, 00, 00, 00, 00, 01, 00, 01,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 00, 05, 00, 02, 00, 00, 00, 00,
00, 01, 00, 01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 00, 05, 00, 02, 00,
00, 00, 00, 00, 01, 00, 01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 00, 05,
00, 02, 00, 00, 00, 00, 00, 01, 00, 07, 00, 00, 00, 00, 00, 00, 00, 0x20};
MOCKER(&GetMetaSection).stubs().with(any(), any(), outBound(metaData))
.will(returnValue(metaData.size()));
KernelContext::Instance().ParseMetaDataFromBinary(binary);
ASSERT_EQ(KernelContext::Instance().GetOpMemInfo().inputParamsAddrInfos.size(), 3);
}
TEST_F(KernelContextTest, get_dump_context_static_kernel)
{
KernelContext::Instance().Reset();
rtDevBinary_t binary;
std::vector<uint8_t> metaData = {0x01, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00,
0x00, 0x00, 00, 00, 04, 00, 0x50, 00, 00, 0x05, 00, 02, 00, 00, 00, 00, 00, 01,
00, 01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 00, 05, 00, 02, 00, 00,
00, 00, 00, 01, 00, 01, 00, 00, 00, 00, 00, 0x00, 0x00, 0x20, 00, 05, 00, 02,
00, 00, 00, 00, 00, 01, 00, 01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
00, 05, 00, 02, 00, 00, 00, 00, 00, 01, 00, 07, 00, 00, 00, 00, 00, 00, 00, 0x20};
MOCKER(&GetMetaSection).stubs().with(any(), any(), outBound(metaData))
.will(returnValue(metaData.size()));
KernelContext::Instance().ParseMetaDataFromBinary(binary);
ASSERT_EQ(KernelContext::Instance().GetOpMemInfo().inputParamsAddrInfos.size(), 3);
ASSERT_EQ(KernelContext::Instance().GetOpMemInfo().inputParamsAddrInfos[0].length, 32);
}
TEST_F(KernelContextTest, mock_dynamic_ascendc_kernel_valid_meta_section_then_parse_it_expect_success)
{
rtDevBinary_t binary;
auto metaData = MockDyanmicAscendcKernelMetaSection();
MOCKER(&GetMetaSection).stubs().with(any(), any(), outBound(metaData))
.will(returnValue(metaData.size()));
rtArgsEx_t argsInfo{};
const size_t tilingSize = 32;
vector<uint64_t> argsPtr(4 + tilingSize);
argsPtr.back() = 0xA5A5A5A50000;
const size_t addInputSize = 32768;
vector<vector<uint64_t>> argsData(4, vector<uint64_t>(addInputSize, 1));
for (int i = 0; i < argsData.size(); i++) {
argsPtr[i] = reinterpret_cast<uint64_t>(&argsData[i]);
}
argsInfo.args = static_cast<void *>(argsPtr.data());
argsInfo.args = static_cast<void *>(argsPtr.data());
argsInfo.argsSize = argsPtr.size() * sizeof(uint64_t);
argsInfo.tilingDataOffset = sizeof(uint64_t) * 4;
auto &inst = KernelContext::Instance();
size_t argsSpace = 96;
vector<uint64_t> adumpData(argsSpace, 1);
AdumpInfo context{adumpData.data(), argsSpace};
ArgsManager::Instance().AddAdumpInfo(0, context);
inst.ParseMetaDataFromBinary(binary, &argsInfo);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos.size(), 4);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos[0].length, 1);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos[1].length, 1);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos[2].length, 1);
ASSERT_EQ(inst.GetOpMemInfo().inputParamsAddrInfos[3].length, 1);
}
TEST_F(KernelContextTest, mock_no_adump_addr_then_parse_it_expect_fail)
{
rtDevBinary_t binary;
auto metaData = MockDyanmicAscendcKernelMetaSection();
MOCKER(&GetMetaSection).stubs().with(any(), any(), outBound(metaData))
.will(returnValue(metaData.size()));
rtArgsEx_t argsInfo{};
const size_t tilingSize = 32;
vector<uint64_t> argsPtr(4 + tilingSize);
argsPtr.back() = 0xA5A5A5A50000;
const size_t addInputSize = 32768;
vector<vector<uint64_t>> argsData(4, vector<uint64_t>(addInputSize, 1));
for (int i = 0; i < argsPtr.size(); i++) {
argsPtr[i] = reinterpret_cast<uint64_t>(&argsData[i]);
}
argsInfo.args = static_cast<void *>(argsPtr.data());
argsInfo.argsSize = argsPtr.size() * sizeof(uint64_t);
argsInfo.tilingDataOffset = sizeof(uint64_t) * 4;
auto &inst = KernelContext::Instance();
inst.ParseMetaDataFromBinary(binary, &argsInfo);
ASSERT_TRUE(inst.GetOpMemInfo().inputParamsAddrInfos.empty());
}
TEST_F(KernelContextTest, get_tik_atomic_index)
{
KernelContext::Instance().Reset();
rtArgsEx_t argsInfo;
argsInfo.tilingDataOffset = 4;
vector<uint8_t> v = {0x01, 0x01, 0x01, 0x02, 0xA5, 0xA5, 0xA5, 0xA5, 0x01, 0x01, 0x01, 0x01};
argsInfo.args = v.data();
rtDevBinary_t binary;
std::vector<uint8_t> metaData = {0x01, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00,
0x00, 0x00, 00, 00, 04, 00, 0x50, 00, 00, 0x05, 00, 02, 00, 00, 00, 00, 00, 01,
00, 01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 00, 05, 00, 02, 00, 00,
00, 00, 00, 01, 00, 01, 00, 00, 00, 00, 0x00, 0x00, 0x00, 0x20, 00, 05, 00, 02,
00, 00, 00, 00, 00, 01, 00, 01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
00, 05, 00, 02, 00, 00, 00, 00, 00, 01, 00, 07, 00, 00, 00, 00, 00, 00, 00, 0x20};
MOCKER(&GetMetaSection).stubs().with(any(), any(), outBound(metaData))
.will(returnValue(metaData.size()));
KernelContext::Instance().GetOpMemInfo().tilingDataSize = 8;
KernelContext::Instance().GetOpMemInfo().isTik = true;
ArgsManager::Instance().AddAdumpInfo(0xA5A5A5A501010101, {nullptr, 0});
KernelContext::Instance().ParseMetaDataFromBinary(binary, &argsInfo);
ASSERT_EQ(KernelContext::Instance().GetOpMemInfo().inputParamsAddrInfos.size(), 0);
}
TEST_F(KernelContextTest, get_meta_section)
{
using GetSectionHeadersFunc = bool(*)(rtDevBinary_t const &, std::map<std::string, Elf64_Shdr> &);
GetSectionHeadersFunc getSectionHeaders = &GetSectionHeaders;
MOCKER(getSectionHeaders).stubs().will(returnValue(true));
std::vector<uint8_t> metaData;
rtDevBinary_t binary;
ASSERT_EQ(GetMetaSection(binary, "abc", metaData), 0);
}
TEST_F(KernelContextTest, mock_valid_section_head_then_test_get_meta_section_expect_success)
{
Elf64_Shdr dummySectionHeader {};
dummySectionHeader.sh_offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Shdr) + sizeof(Elf64_Shdr);
dummySectionHeader.sh_size = 5;
dummySectionHeader.sh_name = 5;
vector<uint8_t> binaryData(1000);
rtDevBinary_t binary;
binary.data = binaryData.data();
binary.length = binaryData.size();
std::map<std::string, Elf64_Shdr> headers = {
{".ascend.meta.kernel_name", dummySectionHeader}
};
using GetSectionHeadersFunc = bool(*)(rtDevBinary_t const &, std::map<std::string, Elf64_Shdr> &);
GetSectionHeadersFunc getSectionHeaders = &GetSectionHeaders;
MOCKER(getSectionHeaders).stubs().with(any(), outBound(headers)).
will(returnValue(true));
std::vector<uint8_t> metaData;
ASSERT_EQ(GetMetaSection(binary, "kernel_name", metaData), dummySectionHeader.sh_size);
}
TEST_F(KernelContextTest, mock_ffts_size_info_then_set_args_size_expect_success)
{
rtArgsSizeInfo_t sizeInfo;
vector<uint64_t> argsData = {
0, 1ULL << 32 | 2,
1ULL << 56 | 1,
2ULL << 56 | 1,
};
sizeInfo.infoAddr = static_cast<void *>(argsData.data());
KernelContext::Instance().GetDeviceContext().SetArgsSize(&sizeInfo);
ASSERT_TRUE(KernelContext::Instance().GetDeviceContext().GetOpMemInfo().isFFTS);
}
TEST_F(KernelContextTest, mock_rt_report_then_repeat_subscribe_expect_ok)
{
MOCKER(&rtSetDeviceOrigin).stubs().will(returnValue(RT_ERROR_NONE));
MOCKER(&aclrtProcessReportImplOrigin).stubs().will(returnValue(ACL_ERROR_NONE));
MOCKER(&aclrtSubscribeReportImplOrigin).stubs().will(returnValue(ACL_ERROR_NONE));
uint64_t stm{};
auto &inst = KernelContext::Instance();
ASSERT_TRUE(inst.GetDeviceContext().SubscribeReport(&stm));
auto &streamInfo = LaunchManager::GetOrCreateStreamInfo(&stm);
ASSERT_TRUE(streamInfo.subscribed);
ASSERT_TRUE(inst.GetDeviceContext().SubscribeReport(&stm));
}
TEST_F(KernelContextTest, mock_rt_report_fail_then_subscribe_expect_ok)
{
MOCKER(&rtSetDeviceOrigin).stubs().will(returnValue(RT_ERROR_NONE));
MOCKER(&aclrtProcessReportImplOrigin).stubs().will(returnValue(ACL_ERROR_INTERNAL_ERROR));
MOCKER(&aclrtSubscribeReportImplOrigin).stubs().will(returnValue(ACL_ERROR_NONE));
uint64_t stm{};
auto &inst = KernelContext::Instance();
ASSERT_TRUE(inst.GetDeviceContext().SubscribeReport(&stm));
}
TEST_F(KernelContextTest, mock_sym_info_then_set_dbi_binary_expect_true)
{
MOCKER(&GetSymInfoFromBinary).stubs().will(returnValue(true));
vector<uint8_t> handleData{1, 2, 3};
const KernelHandle *hdl = handleData.data();
rtDevBinary_t bin{};
KernelContext::Instance().AddHdlRegisterEvent(hdl, &bin);
ASSERT_TRUE(KernelContext::Instance().SetDbiBinary(0, bin));
}
TEST_F(KernelContextTest, mock_get_pc_start_addr_then_update_pc_start_expect_success)
{
MOCKER_CPP(&KernelContext::DeviceContext::GetPcStartAddr,
bool(KernelContext::DeviceContext::*)(KernelContext::KernelHandleArgs const &, uint64_t&) const)
.stubs().will(returnValue(true));
KernelContext::Instance().AddLaunchEvent(nullptr, 0, 1, nullptr, nullptr);
KernelContext::KernelHandleArgs args{};
ASSERT_TRUE(KernelContext::Instance().GetDeviceContext().UpdatePcStartAddrByDbi(0, args));
}