Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include <sstream>
12 : #include "securec.h"
13 : #include "dfx_args_parser.h"
14 : #include "dump_memory.h"
15 : #include "adump_platform_manager.h"
16 : #include "log/adx_log.h"
17 :
18 : namespace Adx {
19 : uint64_t GetDFXInfoChunkCursor(uint8_t bufferId);
20 :
21 : namespace {
22 : constexpr uint32_t ATOMIC_INDEX_SIZE = 8;
23 : constexpr uint32_t BUFFER_ID_SHIFT_BITS = 31;
24 : constexpr uint64_t BUFFER_ID_MASK = 0x080000000;
25 : constexpr uint64_t OFFSET_MASK = 0x0FFFFFF;
26 : constexpr uint64_t MAGIC_NUM = 0xA5A5A5A500000000;
27 : constexpr uint64_t MAGIC_NUM_MASK = 0xFFFFFFFF00000000;
28 : constexpr uint64_t SPACE_MASK = 0x00000000FFFFFFFF;
29 : constexpr uint32_t ARGS_PER_STRING_MAX_LEN = 20;
30 :
31 10 : uint64_t ReadAtomicIndex(const uint8_t* data)
32 : {
33 10 : uint64_t atomicIndex = 0;
34 10 : if (memcpy_s(&atomicIndex, sizeof(atomicIndex), data, sizeof(atomicIndex)) != EOK) {
35 0 : IDE_LOGE("Read atomicIndex failed, data=%p.", data);
36 0 : return 0U;
37 : }
38 10 : return atomicIndex;
39 : }
40 : } // namespace
41 :
42 29 : DfxArgsParser::~DfxArgsParser()
43 : {
44 29 : if (hostArgsData_ != nullptr) {
45 23 : DumpMemory::FreeHost(hostArgsData_);
46 23 : hostArgsData_ = nullptr;
47 : }
48 29 : }
49 :
50 29 : int32_t DfxArgsParser::Init(void* argAddr, uint64_t argSize, const uint8_t* dfxAddr, uint16_t dfxSize)
51 : {
52 29 : IDE_CTRL_VALUE_FAILED(
53 : argAddr != nullptr && argSize != 0, return ADUMP_FAILED, "Invalid arg. argAddr=%p, argSize=%llu.", argAddr,
54 : argSize);
55 29 : IDE_CTRL_VALUE_FAILED(
56 : dfxAddr != nullptr && dfxSize != 0, return ADUMP_FAILED, "Invalid dfx. dfxAddr=%p, dfxSize=%u.", dfxAddr,
57 : dfxSize);
58 :
59 29 : argAddr_ = argAddr;
60 29 : argSize_ = argSize;
61 :
62 29 : hostArgsData_ = DumpMemory::CopyDeviceToHostEx(argAddr, argSize);
63 29 : IDE_CTRL_VALUE_FAILED(
64 : hostArgsData_ != nullptr, return ADUMP_FAILED, "Copy device args to host failed. argAddr=%p, argSize=%llu.",
65 : argAddr, argSize);
66 :
67 23 : argOnHost_ = static_cast<const void**>(hostArgsData_);
68 23 : maxArgNum_ = argSize / sizeof(uint64_t);
69 :
70 23 : dfxAddr_ = dfxAddr;
71 23 : dfxSize_ = dfxSize;
72 23 : currDfxSize_ = 0;
73 :
74 23 : LogArgsInfo();
75 23 : return ADUMP_SUCCESS;
76 : }
77 :
78 23 : void DfxArgsParser::LogArgsInfo()
79 : {
80 23 : const uint32_t argsLogTimes = (maxArgNum_ % ARGS_PER_STRING_MAX_LEN > 0) ?
81 23 : ((maxArgNum_ / ARGS_PER_STRING_MAX_LEN) + 1) :
82 0 : (maxArgNum_ / ARGS_PER_STRING_MAX_LEN);
83 50 : for (uint32_t i = 1; i <= argsLogTimes; ++i) {
84 27 : std::stringstream ss;
85 27 : uint32_t endIndex = maxArgNum_ > (i * ARGS_PER_STRING_MAX_LEN) ? (i * ARGS_PER_STRING_MAX_LEN) : maxArgNum_;
86 241 : for (uint32_t j = (i - 1) * ARGS_PER_STRING_MAX_LEN; j < endIndex; ++j) {
87 214 : ss << *(argOnHost_ + j) << ", ";
88 : }
89 27 : RecordDumpLog(StrUtils::Format(
90 : "[AIC_INFO] args(%u to %u) after execute:%s", (i - 1) * ARGS_PER_STRING_MAX_LEN, endIndex,
91 54 : ss.str().c_str()));
92 27 : }
93 23 : IDE_LOGE("[AIC_INFO] after execute:args print end");
94 23 : }
95 :
96 152 : void DfxArgsParser::RecordDumpLog(const std::string& log)
97 : {
98 152 : IDE_LOGE("%s", log.c_str());
99 152 : logRecords_.emplace_back(log + "\n");
100 152 : }
101 :
102 6 : int32_t DfxArgsParser::GetAddressBias(uint64_t& addrBias, const void* argAddr, void* baseAddr, uint64_t argsSize)
103 : {
104 6 : addrBias = reinterpret_cast<uint64_t>(argAddr) - reinterpret_cast<uint64_t>(baseAddr);
105 6 : if (addrBias >= argsSize) {
106 2 : IDE_LOGE("Address bias[%llu] >= argsSize[%llu], invalid.", addrBias, argsSize);
107 2 : return ADUMP_FAILED;
108 : }
109 4 : return ADUMP_SUCCESS;
110 : }
111 :
112 29 : int32_t DfxArgsParser::CheckAddressOverArgs(const uint64_t* address, const void** argOnHost, uint64_t maxArgNum)
113 : {
114 29 : uint64_t* endArgAddr = reinterpret_cast<uint64_t*>(argOnHost + maxArgNum);
115 29 : if (address >= endArgAddr) {
116 0 : IDE_LOGE("Address[%p] >= endArgAddr[%p], over args range.", address, endArgAddr);
117 0 : return ADUMP_FAILED;
118 : }
119 29 : return ADUMP_SUCCESS;
120 : }
121 :
122 41 : int32_t DfxArgsParser::CheckShapeDataAddress() const
123 : {
124 41 : if (shapeDataAddr_ == nullptr || shapeDataMaxAddr_ == nullptr) {
125 0 : IDE_LOGE("The shape data addr[%p] or max addr[%p] is nullptr.", shapeDataAddr_, shapeDataMaxAddr_);
126 0 : return ADUMP_FAILED;
127 : }
128 41 : if (shapeDataAddr_ >= shapeDataMaxAddr_) {
129 1 : IDE_LOGE("The shape data addr[%p] is over max addr[%p].", shapeDataAddr_, shapeDataMaxAddr_);
130 1 : return ADUMP_FAILED;
131 : }
132 40 : return ADUMP_SUCCESS;
133 : }
134 :
135 50 : bool DfxArgsParser::CheckMagicMemory(const uint8_t* address) const
136 : {
137 58 : for (uint16_t i = 0; i < 4; ++i) {
138 56 : if (*(address + i) != 0xA5) {
139 48 : return false;
140 : }
141 : }
142 2 : return true;
143 : }
144 :
145 100 : const char* DfxArgsParser::GetTensorTypeName(DfxTensorType tensorType)
146 : {
147 100 : switch (tensorType) {
148 38 : case DfxTensorType::INPUT_TENSOR:
149 38 : return "INPUT_TENSOR";
150 30 : case DfxTensorType::OUTPUT_TENSOR:
151 30 : return "OUTPUT_TENSOR";
152 4 : case DfxTensorType::WORKSPACE_TENSOR:
153 4 : return "WORKSPACE_TENSOR";
154 4 : case DfxTensorType::TILING_DATA:
155 4 : return "TILING_DATA";
156 2 : case DfxTensorType::MC2_CTX:
157 2 : return "MC2_CTX";
158 0 : case DfxTensorType::SHAPE_TENSOR:
159 0 : return "SHAPE_TENSOR";
160 18 : case DfxTensorType::GENERAL_TENSOR:
161 18 : return "GENERAL_TENSOR";
162 4 : default:
163 4 : return "UNKNOWN";
164 : }
165 : }
166 :
167 100 : const char* DfxArgsParser::GetPointerTypeName(DfxPointerType pointerType)
168 : {
169 100 : switch (pointerType) {
170 80 : case DfxPointerType::LEVEL_1_POINTER:
171 80 : return "L1_POINTER";
172 8 : case DfxPointerType::LEVEL_2_POINTER:
173 8 : return "L2_POINTER";
174 12 : case DfxPointerType::LEVEL_2_POINTER_WITH_SHAPE:
175 12 : return "L2_POINTER_WITH_SHAPE";
176 0 : case DfxPointerType::SHAPE_TENSOR_PLACEHOLD:
177 0 : return "SHAPE_TENSOR_PLACEHOLD";
178 0 : default:
179 0 : return "INVALID_POINTER";
180 : }
181 : }
182 :
183 10 : int32_t DfxArgsParser::GetShapeData(uint64_t atomicIndex)
184 : {
185 10 : uint8_t bufferId = static_cast<uint8_t>((atomicIndex & BUFFER_ID_MASK) >> BUFFER_ID_SHIFT_BITS);
186 10 : uint32_t offset = static_cast<uint32_t>(atomicIndex & OFFSET_MASK);
187 10 : uint32_t chunkSize = 0;
188 10 : uint64_t* chunkAddr = nullptr;
189 10 : if (bufferId == 0U) {
190 9 : chunkSize = DYNAMIC_RING_CHUNK_SIZE;
191 9 : chunkAddr = g_dynamicChunk;
192 : } else {
193 1 : chunkSize = STATIC_RING_CHUNK_SIZE;
194 1 : chunkAddr = g_staticChunk;
195 : }
196 10 : IDE_LOGI(
197 : "Decode atomicIndex, atomicIndex=0x%llx, bufferId=%u, offset=%u, chunkAddr=%p, chunkSize=%u.", atomicIndex,
198 : bufferId, offset, chunkAddr, chunkSize);
199 :
200 10 : IDE_CTRL_VALUE_FAILED(chunkAddr != nullptr, return ADUMP_FAILED, "GetShapeData failed, the chunk memory is null.");
201 9 : IDE_CTRL_VALUE_FAILED(
202 : offset < chunkSize, return ADUMP_FAILED,
203 : "GetShapeData failed, offset is over chunk size, atomicIndex=0x%llx, bufferId=%u, offset=%u, chunkSize=%u.",
204 : atomicIndex, bufferId, offset, chunkSize);
205 :
206 8 : uint64_t magicAndSpace = chunkAddr[offset];
207 8 : uint64_t magicNum = magicAndSpace & MAGIC_NUM_MASK;
208 8 : uint32_t space = static_cast<uint32_t>(magicAndSpace & SPACE_MASK);
209 8 : IDE_LOGI("Parse chunk header, magicAndSpace=0x%llx, magicNum=0x%llx, space=%u.", magicAndSpace, magicNum, space);
210 :
211 8 : IDE_CTRL_VALUE_FAILED(
212 : magicNum == MAGIC_NUM, return ADUMP_FAILED,
213 : "GetShapeData failed, magic is invalid, atomicIndex=0x%llx, magicAndSpace=0x%llx, magic=0x%llx, "
214 : "magicMask=0x%llx.",
215 : atomicIndex, magicAndSpace, magicNum, MAGIC_NUM_MASK);
216 6 : IDE_CTRL_VALUE_FAILED(
217 : space <= DFX_MAX_TENSOR_NUM, return ADUMP_FAILED,
218 : "GetShapeData failed, space is over max, atomicIndex=0x%llx, magicAndSpace=0x%llx, space=%u, maxSpace=%u.",
219 : atomicIndex, magicAndSpace, space, DFX_MAX_TENSOR_NUM);
220 :
221 5 : uint64_t dumpAtomicIndex = chunkAddr[offset + 1];
222 5 : uint64_t chunkCursor = GetDFXInfoChunkCursor(bufferId);
223 5 : uint64_t chunkRound = chunkCursor / chunkSize;
224 5 : uint32_t chunkOffset = static_cast<uint32_t>(chunkCursor % chunkSize);
225 5 : IDE_CTRL_VALUE_FAILED(
226 : dumpAtomicIndex == atomicIndex, return ADUMP_FAILED,
227 : "GetShapeData failed, atomic index mismatch, atomicIndex=0x%llx, dumpAtomicIndex=0x%llx, chunkRound=%llu, "
228 : "chunkOffset=%u.",
229 : atomicIndex, dumpAtomicIndex, chunkRound, chunkOffset);
230 :
231 4 : shapeDataAddr_ = chunkAddr + offset + RESERVE_SPACE;
232 4 : shapeDataMaxAddr_ = shapeDataAddr_ + space;
233 4 : std::stringstream ss;
234 59 : for (uint32_t i = 0; i < space; i++) {
235 55 : ss << *(shapeDataAddr_ + i) << ", ";
236 : }
237 4 : IDE_LOGI("The shape item size: %s", ss.str().c_str());
238 4 : return ADUMP_SUCCESS;
239 4 : }
240 :
241 6 : bool DfxArgsParser::GetIsDataTypeSizeByte(bool& isDataTypeSizeByte) const
242 : {
243 6 : auto* plat = ExceptionDumpManager::Get();
244 6 : if (plat == nullptr) {
245 : // 未注册平台沿用默认语义:视为非按字节并继续解析,保持与平台工厂化前一致
246 0 : isDataTypeSizeByte = false;
247 0 : return true;
248 : }
249 6 : isDataTypeSizeByte = plat->IsArgsDataTypeSizeByByte();
250 6 : return true;
251 : }
252 :
253 13 : int32_t DfxArgsParser::InitTensorModeInfoInner(uint32_t currArgsIndex, const uint8_t*& dfxAddr, uint64_t& currDfxSize)
254 : {
255 13 : IDE_LOGI("Find tiling data, the mode is dynamic");
256 13 : dynamicModeFlag_ = true;
257 :
258 13 : uint64_t tilingDataSize = 0;
259 13 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr, tilingDataSize, currDfxSize, dfxSize_);
260 13 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
261 :
262 13 : if (tilingDataSize < ATOMIC_INDEX_SIZE) {
263 2 : IDE_LOGE("The tiling data size[%llu] is less than the min size[%u].", tilingDataSize, ATOMIC_INDEX_SIZE);
264 2 : return ADUMP_FAILED;
265 : }
266 :
267 11 : void* tilingDataAddr = DumpMemory::CopyDeviceToHostEx(argOnHost_[currArgsIndex], tilingDataSize);
268 11 : if (tilingDataAddr == nullptr) {
269 1 : IDE_LOGE("Copy device tiling to host failed.");
270 1 : return ADUMP_FAILED;
271 : }
272 20 : HOST_RT_MEMORY_GUARD(tilingDataAddr);
273 :
274 10 : auto addr = static_cast<uint8_t*>(tilingDataAddr);
275 10 : if (isTik_) {
276 50 : for (size_t i = 4; i <= tilingDataSize - 4; ++i) {
277 50 : if (!CheckMagicMemory(addr + i)) {
278 48 : continue;
279 : }
280 2 : uint64_t atomicIndex = ReadAtomicIndex(addr + i - 4);
281 2 : if (GetShapeData(atomicIndex) == ADUMP_SUCCESS) {
282 2 : return ADUMP_SUCCESS;
283 : }
284 : }
285 0 : IDE_LOGE("Can not find shape info. tiling data addr=%p, size=%llu", argOnHost_[currArgsIndex], tilingDataSize);
286 0 : return ADUMP_FAILED;
287 : } else {
288 8 : uint64_t atomicIndex = ReadAtomicIndex(addr + tilingDataSize - ATOMIC_INDEX_SIZE);
289 8 : ret = GetShapeData(atomicIndex);
290 8 : IDE_CTRL_VALUE_FAILED(
291 : ret == ADUMP_SUCCESS, return ADUMP_FAILED, "Can not find shape info. tiling data addr=%p, size=%llu",
292 : argOnHost_[currArgsIndex], tilingDataSize);
293 : }
294 :
295 2 : return ADUMP_SUCCESS;
296 10 : }
297 :
298 23 : int32_t DfxArgsParser::InitTensorModeInfo()
299 : {
300 23 : uint64_t currDfxSize = 0;
301 23 : const uint8_t* dfxAddr = dfxAddr_;
302 23 : uint32_t currArgsIndex = 0;
303 103 : while (currDfxSize < dfxSize_) {
304 98 : std::stringstream exceptionDfxStr;
305 8658 : for (size_t i = 0; i < (dfxSize_ - currDfxSize); ++i) {
306 8560 : exceptionDfxStr << int32_t(*(dfxAddr + i)) << ", ";
307 : }
308 98 : IDE_LOGI(
309 : "current arg index[%u], Tiling current exception dfx raw data:%s ", currArgsIndex,
310 : exceptionDfxStr.str().c_str());
311 :
312 98 : if (currArgsIndex >= maxArgNum_) {
313 1 : IDE_LOGE("The current arg index[%u] is greater than the max arg number[%llu]", currArgsIndex, maxArgNum_);
314 1 : return ADUMP_FAILED;
315 : }
316 :
317 97 : uint16_t argsInfoType = 0;
318 97 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr, argsInfoType, currDfxSize, dfxSize_);
319 97 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
320 97 : uint16_t argsInfoNum = 0;
321 97 : ret = GetPointerValueByBigEndian(&dfxAddr, argsInfoNum, currDfxSize, dfxSize_);
322 97 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
323 97 : if (argsInfoNum == 0) {
324 4 : IDE_LOGE("The dfx args info num[%u] is invalid.", argsInfoNum);
325 4 : return ADUMP_FAILED;
326 : }
327 :
328 93 : if (argsInfoType == TYPE_L0_EXCEPTION_DFX_ARGS_INFO) {
329 90 : uint64_t typeInfo = 0;
330 90 : ret = GetPointerValueByBigEndian(&dfxAddr, typeInfo, currDfxSize, dfxSize_);
331 103 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
332 90 : DfxTensorType tensorType = static_cast<DfxTensorType>(typeInfo & TENSOR_TYPE_MASK);
333 90 : if (tensorType == DfxTensorType::TILING_DATA) {
334 13 : ret = InitTensorModeInfoInner(currArgsIndex, dfxAddr, currDfxSize);
335 13 : return ret;
336 : }
337 77 : currDfxSize += sizeof(uint64_t) * (argsInfoNum - 1);
338 77 : dfxAddr += sizeof(uint64_t) * (argsInfoNum - 1);
339 77 : ++currArgsIndex;
340 : } else {
341 3 : currDfxSize += sizeof(uint64_t) * argsInfoNum;
342 3 : dfxAddr += sizeof(uint64_t) * argsInfoNum;
343 : }
344 80 : IDE_LOGI("Current dfx total size is %llu", currDfxSize);
345 98 : }
346 :
347 5 : if (currDfxSize > dfxSize_) {
348 1 : IDE_LOGE("The dfx info size[%llu] is over the max size[%u].", currDfxSize, dfxSize_);
349 1 : return ADUMP_FAILED;
350 : }
351 :
352 4 : return ADUMP_SUCCESS;
353 : }
354 :
355 22 : int32_t DfxArgsParser::LoadDfxL1PtrTensor(TensorBuffer& tensor)
356 : {
357 22 : int32_t ret = ADUMP_SUCCESS;
358 22 : if (dynamicModeFlag_) {
359 10 : dfxAddr_ += sizeof(uint64_t);
360 10 : currDfxSize_ += sizeof(uint64_t);
361 10 : ret = CheckShapeDataAddress();
362 10 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
363 10 : tensor.size = *shapeDataAddr_;
364 10 : shapeDataAddr_++;
365 10 : tensors_.push_back(tensor);
366 10 : IDE_LOGE(
367 : "[Dump][Exception] tensor type:%u(%s), pointer type:%u(%s)", static_cast<uint16_t>(tensor.tensorType),
368 : GetTensorTypeName(tensor.tensorType), static_cast<uint16_t>(tensor.pointerType),
369 : GetPointerTypeName(tensor.pointerType));
370 10 : RecordDumpLog(StrUtils::Format(
371 : "[Dump][Exception] exception info dump args data, addr:%p; size:%llu bytes", tensor.addr, tensor.size));
372 : } else {
373 12 : uint64_t size = 0;
374 12 : ret = GetPointerValueByBigEndian(&dfxAddr_, size, currDfxSize_, dfxSize_);
375 12 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
376 12 : IDE_LOGI("Tensor size[%llu].", size);
377 12 : tensor.size = size;
378 :
379 12 : uint64_t dimension = 0;
380 12 : ret = GetPointerValueByBigEndian(&dfxAddr_, dimension, currDfxSize_, dfxSize_);
381 12 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
382 12 : IDE_LOGI("Tensor dimension[%llu].", dimension);
383 12 : tensor.dimension = dimension;
384 :
385 36 : for (uint64_t i = 0; i < dimension; ++i) {
386 24 : uint64_t shape = 0;
387 24 : ret = GetPointerValueByBigEndian(&dfxAddr_, shape, currDfxSize_, dfxSize_);
388 24 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
389 24 : IDE_LOGI("Tensor shape[%llu].", shape);
390 24 : tensor.shape.push_back(shape);
391 : }
392 :
393 12 : tensors_.push_back(tensor);
394 12 : IDE_LOGE(
395 : "[Dump][Exception] tensor type:%u(%s), pointer type:%u(%s)", static_cast<uint16_t>(tensor.tensorType),
396 : GetTensorTypeName(tensor.tensorType), static_cast<uint16_t>(tensor.pointerType),
397 : GetPointerTypeName(tensor.pointerType));
398 12 : RecordDumpLog(StrUtils::Format(
399 : "[Dump][Exception] exception info dump args data, addr:%p; size:%llu bytes", tensor.addr, tensor.size));
400 : }
401 :
402 22 : return ADUMP_SUCCESS;
403 : }
404 :
405 6 : int32_t DfxArgsParser::LoadDfxL2ShapePtrTensor(TensorBuffer& tensor)
406 : {
407 6 : uint64_t addrBias = 0;
408 6 : int32_t ret = GetAddressBias(addrBias, tensor.addr, argAddr_, argSize_);
409 6 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
410 :
411 4 : uint64_t* dynamicTensorAddr = reinterpret_cast<uint64_t*>(addrBias + reinterpret_cast<uint64_t>(argOnHost_));
412 4 : ret = CheckAddressOverArgs(dynamicTensorAddr, argOnHost_, maxArgNum_);
413 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
414 :
415 4 : uint64_t offset = *dynamicTensorAddr;
416 4 : dynamicTensorAddr++;
417 :
418 4 : void** tensorAddr = reinterpret_cast<void**>(reinterpret_cast<uint64_t>(argOnHost_) + addrBias + offset);
419 4 : uint64_t shapeInfoCount = (offset - sizeof(uint64_t)) / sizeof(uint64_t);
420 4 : ret = LoadTensorShapeAndSize(tensor, dynamicTensorAddr, tensorAddr, shapeInfoCount);
421 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
422 4 : shapeDataAddr_++;
423 :
424 4 : return ADUMP_SUCCESS;
425 : }
426 :
427 4 : int32_t DfxArgsParser::LoadTensorShapeAndSize(
428 : TensorBuffer& tensor, uint64_t* dynamicTensorAddr, void** tensorAddr, uint64_t shapeInfoCount)
429 : {
430 4 : int32_t ret = ADUMP_SUCCESS;
431 4 : uint64_t currShapeCount = 0;
432 14 : while (currShapeCount < shapeInfoCount) {
433 11 : ret = CheckAddressOverArgs(dynamicTensorAddr, argOnHost_, maxArgNum_);
434 11 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
435 11 : uint64_t dimAndCnt = *dynamicTensorAddr;
436 11 : if (dimAndCnt == 0) {
437 1 : IDE_LOGI("The tensor dimension and count are 0, which is an empty address.");
438 1 : break;
439 : }
440 10 : uint32_t tensorDim = static_cast<uint32_t>(dimAndCnt & TENSOR_DIMENSION_MASK);
441 10 : uint32_t tensorCount = static_cast<uint32_t>((dimAndCnt & TENSOR_COUNT_MASK) >> TENSOR_COUNT_SHIFT_BITS);
442 10 : tensor.dimension = tensorDim;
443 10 : IDE_LOGI("The tensor dimension[%u], count[%u].", tensorDim, tensorCount);
444 10 : dynamicTensorAddr++;
445 10 : currShapeCount++;
446 10 : uint64_t size = 1;
447 10 : std::vector<uint64_t> tmpShapeVec;
448 24 : for (uint32_t i = 0; i < tensorDim; ++i) {
449 14 : ret = CheckAddressOverArgs(dynamicTensorAddr, argOnHost_, maxArgNum_);
450 14 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
451 14 : size *= *dynamicTensorAddr;
452 14 : IDE_LOGI("The tensor shape[%llu].", *dynamicTensorAddr);
453 14 : tmpShapeVec.push_back(*dynamicTensorAddr);
454 14 : dynamicTensorAddr++;
455 14 : currShapeCount++;
456 : }
457 10 : tensor.shape = tmpShapeVec;
458 10 : tensor.size = size;
459 :
460 10 : const void** endArgAddr = argOnHost_ + maxArgNum_;
461 21 : for (uint32_t i = 0; i < tensorCount; ++i) {
462 11 : if (tensorAddr >= endArgAddr) {
463 0 : IDE_LOGE("Args address[%p] is over args end address[%p].", tensorAddr, endArgAddr);
464 0 : return ADUMP_FAILED;
465 : }
466 11 : tensor.addr = *tensorAddr;
467 11 : tensors_.push_back(tensor);
468 11 : RecordDumpLog(StrUtils::Format(
469 : "[Dump][Exception] exception info dump args data, addr:%p; size:%llu bytes", *tensorAddr,
470 : tensor.GetTotalByteSize()));
471 11 : tensorAddr++;
472 : }
473 10 : }
474 :
475 4 : return ADUMP_SUCCESS;
476 : }
477 :
478 32 : int32_t DfxArgsParser::LoadDfxTensor(TensorBuffer& tensor, uint16_t argsInfoNum)
479 : {
480 32 : int32_t ret = ADUMP_SUCCESS;
481 64 : RecordDumpLog(StrUtils::Format(
482 : "[Dump][Exception] begin to load normal tensor, index:%u, tensor type:%u(%s), pointer type:%u(%s)",
483 32 : tensor.argIndex, static_cast<uint16_t>(tensor.tensorType), GetTensorTypeName(tensor.tensorType),
484 32 : static_cast<uint16_t>(tensor.pointerType), GetPointerTypeName(tensor.pointerType)));
485 32 : if (tensor.pointerType == DfxPointerType::LEVEL_2_POINTER_WITH_SHAPE) {
486 6 : dfxAddr_ += sizeof(uint64_t);
487 6 : currDfxSize_ += sizeof(uint64_t);
488 6 : uint64_t dataTypeSize = 0;
489 6 : ret = GetPointerValueByBigEndian(&dfxAddr_, dataTypeSize, currDfxSize_, dfxSize_);
490 8 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
491 6 : IDE_LOGI("The tensor datatype size[%llu].", dataTypeSize);
492 6 : IDE_CTRL_VALUE_FAILED(
493 : GetIsDataTypeSizeByte(tensor.isDataTypeSizeByte), return ADUMP_FAILED, "Load data type size unit failed.");
494 6 : tensor.dataTypeSize = dataTypeSize;
495 6 : ret = LoadDfxL2ShapePtrTensor(tensor);
496 6 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
497 26 : } else if (
498 26 : tensor.pointerType == DfxPointerType::LEVEL_1_POINTER ||
499 4 : tensor.pointerType == DfxPointerType::SHAPE_TENSOR_PLACEHOLD) {
500 22 : ret = LoadDfxL1PtrTensor(tensor);
501 22 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
502 : } else {
503 4 : dfxAddr_ += sizeof(uint64_t) * (argsInfoNum - 1);
504 4 : currDfxSize_ += sizeof(uint64_t) * (argsInfoNum - 1);
505 4 : tensor.size = 0;
506 : }
507 30 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load normal tensor, index:%u", tensor.argIndex));
508 30 : return ADUMP_SUCCESS;
509 : }
510 :
511 4 : int32_t DfxArgsParser::LoadDfxWorkspace(TensorBuffer& tensor)
512 : {
513 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] begin to load workspace, index:%u", tensor.argIndex));
514 :
515 : DumpWorkspace workspace;
516 4 : workspace.addr = tensor.addr;
517 4 : workspace.argsOffset = tensor.argIndex;
518 :
519 4 : if (dynamicModeFlag_) {
520 3 : int32_t ret = CheckShapeDataAddress();
521 3 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
522 3 : workspace.bytes = *shapeDataAddr_;
523 3 : shapeDataAddr_++;
524 : } else {
525 1 : uint64_t size = 0;
526 1 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr_, size, currDfxSize_, dfxSize_);
527 1 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
528 1 : IDE_LOGI("Workspace size[%llu].", size);
529 1 : workspace.bytes = size;
530 : }
531 :
532 4 : workspaces_.push_back(workspace);
533 4 : RecordDumpLog(StrUtils::Format(
534 : "[Dump][Exception] exception info dump workspace data, addr:%p; size:%llu bytes", workspace.addr,
535 : workspace.bytes));
536 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load workspace, index:%u", tensor.argIndex));
537 :
538 4 : return ADUMP_SUCCESS;
539 : }
540 :
541 4 : int32_t DfxArgsParser::LoadDfxTilingData(TensorBuffer& tensor)
542 : {
543 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] begin to load tiling data, index:%u", tensor.argIndex));
544 4 : uint64_t tilingDataSize = 0;
545 4 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr_, tilingDataSize, currDfxSize_, dfxSize_);
546 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
547 4 : IDE_LOGI("The tiling data size=%llu.", tilingDataSize);
548 4 : tensor.size = tilingDataSize;
549 :
550 : // TBE算子无法区分tensor和workspace,当前GE框架无法识别TBE算子,
551 : // 对workspace不会添加dim和shape信息,解析到shape地址越界报错时,忽略错误
552 4 : (void)LoadDfxShapeData();
553 4 : tensors_.push_back(tensor);
554 4 : RecordDumpLog(StrUtils::Format(
555 : "[Dump][Exception] exception info dump tiling data, addr:%p; size:%llu bytes", tensor.addr, tilingDataSize));
556 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load tiling data, index:%u", tensor.argIndex));
557 4 : return ADUMP_SUCCESS;
558 : }
559 :
560 4 : int32_t DfxArgsParser::LoadDfxShapeData()
561 : {
562 4 : int32_t ret = ADUMP_SUCCESS;
563 4 : size_t tensorBufferSize = tensors_.size();
564 4 : IDE_LOGI("The tensor buffer size=%llu.", tensorBufferSize);
565 17 : for (size_t i = 0; i < tensorBufferSize; ++i) {
566 14 : DfxPointerType localPointerType = tensors_[i].pointerType;
567 23 : if ((localPointerType == DfxPointerType::LEVEL_1_POINTER) && tensors_[i].size != 0 &&
568 9 : tensors_[i].tensorType != DfxTensorType::SHAPE_TENSOR) {
569 9 : ret = CheckShapeDataAddress();
570 9 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
571 9 : uint64_t tensorDim = *shapeDataAddr_;
572 9 : IDE_LOGI("The tensor dimension[%llu].", tensorDim);
573 9 : tensors_[i].dimension = tensorDim;
574 9 : shapeDataAddr_++;
575 27 : for (uint64_t dim = 0; dim < tensorDim; ++dim) {
576 19 : ret = CheckShapeDataAddress();
577 19 : IDE_CHECK_RET(ret, {
578 : tensors_[i].dimension = 0;
579 : return ADUMP_FAILED;
580 : });
581 18 : IDE_LOGI("The tensor shape[%llu].", *shapeDataAddr_);
582 18 : tensors_[i].shape.push_back(*shapeDataAddr_);
583 18 : shapeDataAddr_++;
584 : }
585 : }
586 : }
587 :
588 3 : return ret;
589 : }
590 :
591 2 : void DfxArgsParser::LoadDfxMc2(const TensorBuffer& tensor)
592 : {
593 2 : RecordDumpLog(StrUtils::Format("[Dump][Exception] begin to load mc2, index:%u", tensor.argIndex));
594 : DumpWorkspace workspace;
595 2 : workspace.addr = tensor.addr;
596 2 : workspace.argsOffset = tensor.argIndex;
597 2 : workspace.bytes = 0;
598 2 : mc2Space_.push_back(workspace);
599 2 : shapeDataAddr_++;
600 2 : RecordDumpLog(StrUtils::Format(
601 : "[Dump][Exception] exception info dump mc2 data, addr:%p; size:%llu bytes", workspace.addr, workspace.bytes));
602 2 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load mc2, index:%u", tensor.argIndex));
603 2 : }
604 :
605 47 : int32_t DfxArgsParser::LoadDfxInfo(uint32_t& currArgsIndex)
606 : {
607 47 : uint16_t argsInfoType = 0;
608 47 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr_, argsInfoType, currDfxSize_, dfxSize_);
609 47 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
610 47 : uint16_t argsInfoNum = 0;
611 47 : ret = GetPointerValueByBigEndian(&dfxAddr_, argsInfoNum, currDfxSize_, dfxSize_);
612 47 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
613 47 : IDE_LOGI("The arg info type: %u, info num:%u", argsInfoType, argsInfoNum);
614 47 : IDE_CTRL_VALUE_FAILED(argsInfoNum != 0, return ADUMP_FAILED, "The dfx args info num[%u] is invalid.", argsInfoNum);
615 :
616 47 : if (argsInfoType == TYPE_L0_EXCEPTION_DFX_ARGS_INFO) {
617 46 : uint64_t typeInfo = 0;
618 46 : ret = GetPointerValueByBigEndian(&dfxAddr_, typeInfo, currDfxSize_, dfxSize_);
619 48 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
620 46 : DfxTensorType tensorType = static_cast<DfxTensorType>(typeInfo & TENSOR_TYPE_MASK);
621 46 : DfxPointerType pointerType =
622 46 : static_cast<DfxPointerType>((typeInfo & POINTER_TYPE_MASK) >> POINTER_TYPE_SHIFT_BITS);
623 46 : IDE_LOGI(
624 : "The arg type info: %llu, tensor type: %u(%s), pointer type: %u(%s)", typeInfo,
625 : static_cast<uint16_t>(tensorType), GetTensorTypeName(tensorType), static_cast<uint16_t>(pointerType),
626 : GetPointerTypeName(pointerType));
627 :
628 46 : TensorBuffer tensor(argOnHost_[currArgsIndex], currArgsIndex, tensorType, pointerType);
629 46 : if ((tensorType <= DfxTensorType::OUTPUT_TENSOR && tensorType > DfxTensorType::INVALID_TENSOR) ||
630 : tensorType == DfxTensorType::SHAPE_TENSOR) {
631 32 : ret = LoadDfxTensor(tensor, argsInfoNum);
632 32 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
633 14 : } else if (tensorType == DfxTensorType::WORKSPACE_TENSOR) {
634 4 : ret = LoadDfxWorkspace(tensor);
635 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
636 10 : } else if (tensorType == DfxTensorType::TILING_DATA) {
637 4 : ret = LoadDfxTilingData(tensor);
638 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
639 6 : } else if (tensorType == DfxTensorType::MC2_CTX) {
640 2 : LoadDfxMc2(tensor);
641 : } else {
642 4 : IDE_LOGE(
643 : "[Dump][Exception] args dump dfx info, addr:%p, tensor type:%u, pointer type:%u, index: %u",
644 : argOnHost_[currArgsIndex], static_cast<uint16_t>(tensorType), static_cast<uint16_t>(pointerType),
645 : currArgsIndex);
646 4 : dfxAddr_ += sizeof(uint64_t) * (argsInfoNum - 1);
647 4 : currDfxSize_ += sizeof(uint64_t) * (argsInfoNum - 1);
648 : }
649 44 : ++currArgsIndex;
650 46 : } else {
651 1 : IDE_LOGW("The dfx args info type[%u] is not allowed", argsInfoType);
652 1 : dfxAddr_ += sizeof(uint64_t) * argsInfoNum;
653 1 : currDfxSize_ += sizeof(uint64_t) * argsInfoNum;
654 : }
655 :
656 45 : return ADUMP_SUCCESS;
657 : }
658 :
659 8 : int32_t DfxArgsParser::ParseAll()
660 : {
661 8 : uint32_t currArgsIndex = 0;
662 53 : while (currDfxSize_ < dfxSize_) {
663 47 : std::stringstream exceptionDfxStr;
664 5463 : for (size_t i = 0; i < (dfxSize_ - currDfxSize_); ++i) {
665 5416 : exceptionDfxStr << int32_t(*(dfxAddr_ + i)) << ", ";
666 : }
667 47 : IDE_LOGI("Current exception dfx raw data:%s ", exceptionDfxStr.str().c_str());
668 :
669 47 : if (currArgsIndex >= maxArgNum_) {
670 0 : IDE_LOGE("The current arg index[%u] is greater than the max arg number[%llu]", currArgsIndex, maxArgNum_);
671 0 : return ADUMP_FAILED;
672 : }
673 :
674 47 : int32_t ret = LoadDfxInfo(currArgsIndex);
675 47 : if (ret != ADUMP_SUCCESS) {
676 2 : return ret;
677 : }
678 47 : }
679 :
680 6 : return ADUMP_SUCCESS;
681 : }
682 :
683 : } // namespace Adx
|