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 <iostream>
12 : #include <unordered_map>
13 : #include <unordered_set>
14 : #include <sstream>
15 : #include <functional>
16 : #include <map>
17 : #include <mutex>
18 : #include <inttypes.h>
19 : #include "runtime/mem.h"
20 : #include "runtime/base.h"
21 : #include "runtime/dev.h"
22 : #include "log/hdc_log.h"
23 : #include "fp16_t.h"
24 : #include "bfloat16.h"
25 : #include "hifloat.h"
26 : #include "dump_memory.h"
27 : #include "sys_utils.h"
28 : #include "dump_printf_platform.h"
29 : #include "dump_datatype.h"
30 : #include "dump_printf.h"
31 :
32 : using namespace Adx;
33 : namespace {
34 : constexpr size_t ADX_SIMT_BLOCK_NUM = 72U;
35 : constexpr size_t ADX_PRINT_ARG_LEN = 8U;
36 : constexpr size_t ADX_ASSERT_LEN = 1024U;
37 : constexpr size_t ADX_MAX_STR_LEN = 1024U * 1024U;
38 : constexpr size_t ADX_SIMT_PRINT_LEN = 2U * 1024U;
39 : constexpr size_t ADX_MAX_LOG_LENGTH = 256U;
40 : constexpr uint32_t ADX_OFF_LIMIT_RSV = 7U;
41 : constexpr uint32_t ADX_SIMT_MAX_THREAD_NUM = 2048U;
42 : constexpr size_t ADX_ONE_LINE_NUM = 30U;
43 : constexpr uint16_t ADX_INT16_SIZE = 2U;
44 : constexpr uint16_t ADX_INT32_SIZE = 4U;
45 : constexpr uint16_t ADX_INT64_SIZE = 8U;
46 : constexpr uint64_t ADX_INPUT_NUM_MASK = 0x00000000ffffffff;
47 : constexpr uint64_t ADX_SIZE_MASK = 0x00ffffffffffffff;
48 : constexpr uint64_t ADX_FFTS_ADDR_OFFSET = 32U;
49 : constexpr uint64_t ADX_SIZE_BITS_OFFSET = 56U;
50 : constexpr uint64_t ADX_WORKSPACE_SIZE_FLAG = 4U;
51 : constexpr uint64_t ADX_DYNAMIC_INPUT_FLAG = 2U;
52 : constexpr uint32_t ADX_DUMP_AND_PRINT_MAGIC_NUM = 0x5AA5BCCDU;
53 : static bool g_adxPrintConfigFlag = false;
54 : static std::mutex g_adxPrintConfigMtx;
55 : constexpr uint32_t TIMEOUT_THRESHOLD = 500U;
56 : } // namespace
57 :
58 : template <typename T>
59 44 : std::string AdxToHex(T num)
60 : {
61 44 : std::stringstream stream;
62 44 : stream << std::hex << num;
63 88 : return stream.str();
64 44 : }
65 :
66 : template <typename T>
67 2 : std::string AdxToStr(T num)
68 : {
69 2 : std::stringstream stream;
70 2 : stream << num;
71 4 : return stream.str();
72 2 : }
73 :
74 : template <typename T>
75 33 : inline T AdxParseParam(const uint8_t* beginAddr, const size_t paramIndex)
76 : {
77 33 : const T* paramAddr = (const T*)(beginAddr + paramIndex * ADX_PRINT_ARG_LEN);
78 33 : return *paramAddr;
79 : }
80 :
81 88 : inline int32_t AdxConvertToStd(uint8_t data) { return static_cast<int32_t>(data); }
82 :
83 8 : inline int32_t AdxConvertToStd(int8_t data) { return static_cast<int32_t>(data); }
84 :
85 : template <typename T>
86 12 : inline T AdxConvertToStd(const T& data)
87 : {
88 12 : return data;
89 : }
90 :
91 4 : inline float AdxConvertToStd(Adx::fp16_t data) { return data.toFloat(); }
92 :
93 8 : inline float AdxConvertToStd(Adx::BFloat16 data) { return data.GetValue(); }
94 :
95 8 : inline float AdxConvertToStd(Adx::HiFloat8 data) { return data.GetValue(); }
96 :
97 8 : inline float AdxConvertToStd(Adx::Fp8E5M2 data) { return data.GetValue(); }
98 :
99 8 : inline float AdxConvertToStd(Adx::Fp8E4M3 data) { return data.GetValue(); }
100 :
101 8 : inline float AdxConvertToStd(Adx::Fp8E8M0 data) { return data.GetValue(); }
102 :
103 1 : static void AdxPrintBoolTensor(const void* data, const size_t dataNum)
104 : {
105 1 : const uint8_t* nums = static_cast<const uint8_t*>(data);
106 1 : std::cout << "[";
107 1 : std::string tensorData = "[";
108 9 : for (size_t i = 0U; i < dataNum; ++i) {
109 8 : if (bool(nums[i])) {
110 4 : std::cout << 1;
111 4 : tensorData += "1";
112 : } else {
113 4 : std::cout << 0;
114 4 : tensorData += "0";
115 : }
116 8 : if (i == dataNum - 1U) { // dataNum一定满足>=1
117 1 : std::cout << "]" << std::endl;
118 1 : tensorData += "]";
119 1 : IDE_LOGI("DumpTensor: %s", tensorData.c_str());
120 : } else {
121 7 : std::cout << ", ";
122 7 : tensorData += ", ";
123 7 : if ((i != 0U) && (i % ADX_ONE_LINE_NUM == 0U)) {
124 0 : std::cout << std::endl;
125 0 : IDE_LOGI("DumpTensor: %s", tensorData.c_str());
126 0 : tensorData.clear();
127 : }
128 : }
129 : }
130 1 : }
131 :
132 : template <typename T>
133 13 : void AdxPrintTensor(const void* data, const size_t dataNum)
134 : {
135 13 : const T* nums = (const T*)data;
136 13 : std::cout << "[";
137 13 : std::string tensorData = "[";
138 77 : for (size_t i = 0U; i < dataNum; ++i) {
139 64 : const auto num = AdxConvertToStd(nums[i]);
140 64 : std::cout << std::to_string(num);
141 64 : tensorData += std::to_string(num);
142 64 : if (i == dataNum - 1U) { // dataNum一定满足>=1
143 13 : std::cout << "]" << std::endl;
144 13 : tensorData += "]";
145 13 : IDE_LOGI("DumpTensor: %s", tensorData.c_str());
146 : } else {
147 51 : std::cout << ", ";
148 51 : tensorData += ", ";
149 51 : if ((i != 0U) && (i % ADX_ONE_LINE_NUM == 0U)) {
150 0 : std::cout << std::endl;
151 0 : IDE_LOGI("DumpTensor: %s", tensorData.c_str());
152 0 : tensorData.clear();
153 : }
154 : }
155 : }
156 13 : }
157 :
158 : template <typename T>
159 4 : static size_t AdumpPrintValidElems(
160 : const void* data, const size_t dataNum, const std::vector<size_t>& tmpShape, std::string& tensorContent,
161 : const bool flag)
162 : {
163 4 : const T* dumpTensor = static_cast<const T*>(data);
164 4 : size_t cnt = 0U;
165 92 : for (size_t i = 0; i < dataNum; i++) {
166 88 : cnt = 0U;
167 416 : for (size_t s : tmpShape) {
168 240 : if ((i + 1) % s == 0) {
169 26 : cnt++;
170 : }
171 : }
172 88 : tensorContent += std::to_string(AdxConvertToStd(dumpTensor[i]));
173 88 : if (cnt > 0U) {
174 17 : tensorContent += std::string(cnt, ']');
175 17 : if (flag) {
176 3 : tensorContent += ",\n";
177 : }
178 17 : if (i != dataNum - 1) {
179 14 : if (!flag) {
180 12 : tensorContent += ",\n";
181 : }
182 28 : tensorContent += std::string(cnt, '[');
183 : }
184 71 : } else if (i != dataNum - 1) {
185 70 : tensorContent += ",";
186 : }
187 : }
188 4 : return cnt;
189 : }
190 :
191 3 : static void AdxPrintExtraElems(
192 : const size_t totalEleNum, const size_t dataNum, size_t& cnt, const std::vector<size_t>& tmpShape,
193 : std::string& tensorContent)
194 : {
195 3 : if (dataNum % tmpShape.back() == 0) {
196 4 : tensorContent += std::string(cnt, '[');
197 : } else {
198 1 : tensorContent += ",";
199 : }
200 41 : for (size_t i = dataNum; i < totalEleNum; i++) {
201 38 : cnt = 0U;
202 160 : for (size_t s : tmpShape) {
203 84 : if ((i + 1) % s == 0) {
204 10 : cnt++;
205 : }
206 : }
207 38 : tensorContent += "-";
208 38 : if (cnt > 0U) {
209 6 : tensorContent += std::string(cnt, ']');
210 6 : if (i != totalEleNum - 1) {
211 3 : tensorContent += ",\n";
212 6 : tensorContent += std::string(cnt, '[');
213 : }
214 32 : } else if (i != totalEleNum - 1) {
215 32 : tensorContent += ",";
216 : }
217 : }
218 3 : }
219 :
220 1 : static size_t AdumpPrintValidBoolElems(
221 : const void* data, const size_t dataNum, const std::vector<size_t>& tmpShape, std::string& tensorContent,
222 : const bool flag)
223 : {
224 1 : const uint8_t* dumpTensor = static_cast<const uint8_t*>(data);
225 1 : size_t cnt = 0U;
226 17 : for (size_t i = 0; i < dataNum; i++) {
227 16 : cnt = 0U;
228 80 : for (size_t s : tmpShape) {
229 48 : if ((i + 1) % s == 0) {
230 6 : cnt++;
231 : }
232 : }
233 16 : tensorContent += (static_cast<bool>(dumpTensor[i])) ? "1" : "0";
234 16 : if (cnt > 0U) {
235 4 : tensorContent += std::string(cnt, ']');
236 4 : tensorContent += (flag) ? ",\n" : "";
237 4 : if (i != dataNum - 1) {
238 3 : tensorContent += (!flag) ? ",\n" : "";
239 6 : tensorContent += std::string(cnt, '[');
240 : }
241 12 : } else if (i != dataNum - 1) {
242 12 : tensorContent += ",";
243 : }
244 : }
245 1 : return cnt;
246 : }
247 :
248 23 : static std::string AdumpToString(aclDataType dataType)
249 : {
250 : static std::map<aclDataType, std::string> dtype = {
251 0 : {ACL_DT_UNDEFINED, "undefined"},
252 0 : {ACL_FLOAT, "float32"},
253 0 : {ACL_FLOAT16, "float16"},
254 0 : {ACL_INT8, "int8"},
255 0 : {ACL_INT32, "int32"},
256 0 : {ACL_UINT8, "uint8"},
257 0 : {ACL_INT16, "int16"},
258 0 : {ACL_UINT16, "uint16"},
259 0 : {ACL_UINT32, "uint32"},
260 0 : {ACL_INT64, "int64"},
261 0 : {ACL_UINT64, "uint64"},
262 0 : {ACL_DOUBLE, "double"},
263 0 : {ACL_BOOL, "bool"},
264 0 : {ACL_STRING, "string"},
265 0 : {ACL_COMPLEX64, "complex64"},
266 0 : {ACL_COMPLEX128, "complex128"},
267 0 : {ACL_BF16, "bfloat16"},
268 0 : {ACL_HIFLOAT8, "hifloat8"},
269 0 : {ACL_FLOAT8_E5M2, "float8_e5m2"},
270 0 : {ACL_FLOAT8_E4M3FN, "float8_e4m3fn"},
271 46 : {ACL_FLOAT8_E8M0, "float8_e8m0"}};
272 23 : auto iter = dtype.find(dataType);
273 23 : if (iter != dtype.end()) {
274 46 : return (iter->second).c_str();
275 : } else {
276 0 : return "Unknown aclDataType";
277 : }
278 1 : }
279 :
280 : #ifdef __cplusplus
281 : extern "C" {
282 : #endif
283 :
284 17 : static std::string AdxGetCoreTypeId(const uint32_t core, const uint8_t coreType)
285 : {
286 17 : if (coreType == 1U) { // AIC场景
287 4 : return "AIC-" + std::to_string(core - AdxGetCoreTypeIDOffset());
288 : }
289 13 : return "AIV-" + std::to_string(core); // AIV+MIX场景
290 : }
291 :
292 : static const std::unordered_map<GeDataType, std::function<void(const void*, const size_t)>> ADX_PRINT_CALLS{
293 : {GeDataType::DT_UINT8, AdxPrintTensor<uint8_t>},
294 : {GeDataType::DT_INT8, AdxPrintTensor<int8_t>},
295 : {GeDataType::DT_INT16, AdxPrintTensor<int16_t>},
296 : {GeDataType::DT_UINT16, AdxPrintTensor<uint16_t>},
297 : {GeDataType::DT_INT32, AdxPrintTensor<int32_t>},
298 : {GeDataType::DT_UINT32, AdxPrintTensor<uint32_t>},
299 : {GeDataType::DT_INT64, AdxPrintTensor<int64_t>},
300 : {GeDataType::DT_UINT64, AdxPrintTensor<uint64_t>},
301 : {GeDataType::DT_FLOAT, AdxPrintTensor<float>},
302 : {GeDataType::DT_FLOAT16, AdxPrintTensor<Adx::fp16_t>},
303 : {GeDataType::DT_BF16, AdxPrintTensor<Adx::BFloat16>},
304 : {GeDataType::DT_HIFLOAT8, AdxPrintTensor<Adx::HiFloat8>},
305 : {GeDataType::DT_FLOAT8_E5M2, AdxPrintTensor<Adx::Fp8E5M2>},
306 : {GeDataType::DT_FLOAT8_E4M3FN, AdxPrintTensor<Adx::Fp8E4M3>},
307 : {GeDataType::DT_FLOAT8_E8M0, AdxPrintTensor<Adx::Fp8E8M0>},
308 : {GeDataType::DT_BOOL, AdxPrintBoolTensor},
309 : };
310 :
311 : static const std::unordered_map<
312 : GeDataType,
313 : std::function<size_t(const void*, const size_t, const std::vector<size_t>&, std::string&, const size_t)>>
314 : ADX_PRINT_BY_SHAPE_CALLS{
315 : {GeDataType::DT_UINT8, AdumpPrintValidElems<uint8_t>},
316 : {GeDataType::DT_INT8, AdumpPrintValidElems<int8_t>},
317 : {GeDataType::DT_INT16, AdumpPrintValidElems<int16_t>},
318 : {GeDataType::DT_UINT16, AdumpPrintValidElems<uint16_t>},
319 : {GeDataType::DT_INT32, AdumpPrintValidElems<int32_t>},
320 : {GeDataType::DT_UINT32, AdumpPrintValidElems<uint32_t>},
321 : {GeDataType::DT_INT64, AdumpPrintValidElems<int64_t>},
322 : {GeDataType::DT_UINT64, AdumpPrintValidElems<uint64_t>},
323 : {GeDataType::DT_FLOAT, AdumpPrintValidElems<float>},
324 : {GeDataType::DT_FLOAT16, AdumpPrintValidElems<Adx::fp16_t>},
325 : {GeDataType::DT_BOOL, AdumpPrintValidBoolElems},
326 : {GeDataType::DT_BF16, AdumpPrintValidElems<Adx::BFloat16>},
327 : {GeDataType::DT_HIFLOAT8, AdumpPrintValidElems<Adx::HiFloat8>},
328 : {GeDataType::DT_FLOAT8_E5M2, AdumpPrintValidElems<Adx::Fp8E5M2>},
329 : {GeDataType::DT_FLOAT8_E4M3FN, AdumpPrintValidElems<Adx::Fp8E4M3>},
330 : {GeDataType::DT_FLOAT8_E8M0, AdumpPrintValidElems<Adx::Fp8E8M0>}};
331 :
332 7 : static void AdxPrintFormatD(
333 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
334 : {
335 : (void)maxLen;
336 7 : const int64_t paramInfo = AdxParseParam<int64_t>(paramBegin, paramIndex);
337 7 : (void)printf("%lld", (long long)paramInfo);
338 7 : printInfo += std::to_string(paramInfo);
339 7 : }
340 :
341 6 : static void AdxPrintFormatI(
342 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
343 : {
344 : (void)maxLen;
345 6 : const int64_t paramInfo = AdxParseParam<int64_t>(paramBegin, paramIndex);
346 6 : (void)printf("%lli", (long long)paramInfo);
347 6 : printInfo += std::to_string(paramInfo);
348 6 : }
349 :
350 3 : static void AdxPrintFormatF(
351 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
352 : {
353 : (void)maxLen;
354 3 : const float paramInfo = AdxParseParam<float>(paramBegin, paramIndex);
355 3 : (void)printf("%f", paramInfo);
356 3 : printInfo += std::to_string(paramInfo);
357 3 : }
358 :
359 1 : static void AdxPrintFormatFUpper(
360 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
361 : {
362 : (void)maxLen;
363 1 : const float paramInfo = AdxParseParam<float>(paramBegin, paramIndex);
364 1 : (void)printf("%F", paramInfo);
365 1 : printInfo += std::to_string(paramInfo);
366 1 : }
367 :
368 7 : static void AdxPrintFormatU(
369 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
370 : {
371 : (void)maxLen;
372 7 : const uint64_t paramInfo = AdxParseParam<uint64_t>(paramBegin, paramIndex);
373 7 : (void)printf("%llu", (long long unsigned)paramInfo);
374 7 : printInfo += std::to_string(paramInfo);
375 7 : }
376 :
377 1 : static void AdxPrintFormatP(
378 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
379 : {
380 : (void)maxLen;
381 1 : const void* paramInfo = AdxParseParam<void*>(paramBegin, paramIndex);
382 1 : (void)printf("%p", paramInfo);
383 1 : printInfo += AdxToStr(paramInfo);
384 1 : }
385 :
386 4 : static void AdxPrintFormatX(
387 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
388 : {
389 : (void)maxLen;
390 4 : const int64_t paramInfo = AdxParseParam<int64_t>(paramBegin, paramIndex);
391 4 : (void)printf("%llx", (long long unsigned)paramInfo);
392 4 : printInfo += AdxToHex(paramInfo);
393 4 : }
394 :
395 4 : static void AdxPrintFormatXUpper(
396 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
397 : {
398 : (void)maxLen;
399 4 : const int64_t paramInfo = AdxParseParam<int64_t>(paramBegin, paramIndex);
400 4 : (void)printf("%llX", (long long unsigned)paramInfo);
401 4 : printInfo += AdxToHex(paramInfo);
402 4 : }
403 :
404 1 : static void AdxPrintFormatS(
405 : const uint8_t* paramBegin, std::string& printInfo, const size_t paramIndex, const size_t maxLen)
406 : {
407 1 : const uint64_t* offsetAddr = (const uint64_t*)(paramBegin + paramIndex * ADX_PRINT_ARG_LEN);
408 1 : const char* data = ((const char*)offsetAddr) + (*offsetAddr);
409 1 : const size_t dataLen = strnlen(data, ADX_MAX_STR_LEN);
410 1 : IDE_LOGD("Get string param length %zu bytes, max length is %zu bytes.", dataLen, maxLen);
411 1 : if (dataLen > maxLen) {
412 0 : return;
413 : }
414 1 : (void)printf("%s", data);
415 1 : printInfo += AdxToStr(data);
416 : }
417 :
418 : static const std::unordered_map<
419 : std::string, std::function<void(const uint8_t*, std::string&, const size_t, const size_t)>>
420 : ADX_PRINT_FORMAT_CALLS{{"d", AdxPrintFormatD}, {"ld", AdxPrintFormatD}, {"lld", AdxPrintFormatD},
421 : {"i", AdxPrintFormatI}, {"li", AdxPrintFormatI}, {"lli", AdxPrintFormatI},
422 : {"f", AdxPrintFormatF}, {"F", AdxPrintFormatFUpper}, {"u", AdxPrintFormatU},
423 : {"lu", AdxPrintFormatU}, {"llu", AdxPrintFormatU}, {"p", AdxPrintFormatP},
424 : {"x", AdxPrintFormatX}, {"lx", AdxPrintFormatX}, {"llx", AdxPrintFormatX},
425 : {"X", AdxPrintFormatXUpper}, {"lX", AdxPrintFormatXUpper}, {"llX", AdxPrintFormatXUpper},
426 : {"s", AdxPrintFormatS}};
427 :
428 : static const std::unordered_map<GeDataType, uint16_t> ADX_DATA_TYPE_SIZE{
429 : {GeDataType::DT_UINT8, 1U},
430 : {GeDataType::DT_INT8, 1U},
431 : {GeDataType::DT_BOOL, 1U},
432 : {GeDataType::DT_INT16, ADX_INT16_SIZE},
433 : {GeDataType::DT_UINT16, ADX_INT16_SIZE},
434 : {GeDataType::DT_INT32, ADX_INT32_SIZE},
435 : {GeDataType::DT_UINT32, ADX_INT32_SIZE},
436 : {GeDataType::DT_INT64, ADX_INT64_SIZE},
437 : {GeDataType::DT_UINT64, ADX_INT64_SIZE},
438 : {GeDataType::DT_FLOAT, ADX_INT32_SIZE},
439 : {GeDataType::DT_FLOAT16, ADX_INT16_SIZE},
440 : {GeDataType::DT_BF16, ADX_INT16_SIZE},
441 : {GeDataType::DT_HIFLOAT8, 1U},
442 : {GeDataType::DT_FLOAT8_E5M2, 1U},
443 : {GeDataType::DT_FLOAT8_E4M3FN, 1U},
444 : {GeDataType::DT_FLOAT8_E8M0, 1U}};
445 :
446 21 : static void GetDataTypeSize(uint32_t dataType, uint16_t& size)
447 : {
448 21 : const auto& iter = ADX_DATA_TYPE_SIZE.find(static_cast<GeDataType>(dataType));
449 21 : if (iter != ADX_DATA_TYPE_SIZE.end()) {
450 19 : size = iter->second;
451 : } else {
452 2 : const std::string dtype = AdumpToString((aclDataType)dataType);
453 2 : IDE_LOGW("Dump tensor doesn't support dtype of %s.", dtype.c_str());
454 2 : }
455 21 : }
456 :
457 5 : static void AdxDumpPrintTensorWithShape(
458 : const AdxDumpMessageHead* const tensorHead, const std::vector<size_t>& shape, const size_t totalNum,
459 : const size_t elementsNum)
460 : {
461 5 : IDE_LOGI("print tensor by shape, totalNum is %zu, elementsNum is %zu.", totalNum, elementsNum);
462 5 : const auto& iter = ADX_PRINT_BY_SHAPE_CALLS.find(static_cast<GeDataType>(tensorHead->dataType));
463 5 : if (iter != ADX_PRINT_BY_SHAPE_CALLS.end()) {
464 5 : const uint8_t* const data = (const uint8_t*)(tensorHead) + sizeof(AdxDumpMessageHead);
465 5 : if (totalNum != 0) {
466 5 : std::vector<size_t> tmpShape = shape;
467 13 : for (int i = tmpShape.size() - 2; i >= 0 && shape.size() >= 2U; i--) {
468 8 : tmpShape[i] *= tmpShape[i + 1];
469 : }
470 5 : std::string tensorContent = std::string(tmpShape.size(), '[');
471 5 : size_t cnt = 0U;
472 5 : if (totalNum == elementsNum) {
473 2 : cnt = (iter->second)(static_cast<const void*>(data), elementsNum, tmpShape, tensorContent, false);
474 : } else {
475 3 : cnt = (iter->second)(static_cast<const void*>(data), elementsNum, tmpShape, tensorContent, true);
476 3 : AdxPrintExtraElems(totalNum, elementsNum, cnt, tmpShape, tensorContent);
477 : }
478 5 : std::cout << tensorContent << std::endl;
479 5 : IDE_LOGI("DumpTensor: %s", tensorContent.c_str());
480 5 : }
481 : } else {
482 0 : const std::string dtype = AdumpToString(static_cast<aclDataType>(tensorHead->dataType));
483 0 : IDE_LOGW("Dump tensor doesn't support dtype of %s.", dtype.c_str());
484 0 : }
485 5 : }
486 :
487 5 : static void AdxDumpJugdeShape(
488 : const std::vector<size_t>& shape, const size_t actualDataNum, const AdxDumpMessageHead* const tensorHead)
489 : {
490 5 : size_t totalNum = 1U;
491 5 : std::string shapeStr = "[";
492 18 : for (size_t i = 0U; i < shape.size(); i++) {
493 13 : totalNum *= shape[i];
494 13 : shapeStr += std::to_string(shape[i]);
495 13 : if (i + 1 < shape.size()) {
496 8 : shapeStr += ", ";
497 : } else {
498 5 : shapeStr += "]";
499 : }
500 : }
501 5 : if (totalNum < actualDataNum) {
502 1 : printf("shape is %s, dumpSize is %zu, dumpSize is greater than shapeSize.\n", shapeStr.c_str(), actualDataNum);
503 1 : AdxDumpPrintTensorWithShape(tensorHead, shape, totalNum, totalNum);
504 4 : } else if (totalNum > actualDataNum) {
505 3 : printf("shape is %s, dumpSize is %zu, data is not enough.\n", shapeStr.c_str(), actualDataNum);
506 3 : AdxDumpPrintTensorWithShape(tensorHead, shape, totalNum, actualDataNum);
507 : } else {
508 1 : AdxDumpPrintTensorWithShape(tensorHead, shape, totalNum, actualDataNum);
509 : }
510 10 : return;
511 5 : }
512 :
513 14 : static void AdxDumpPrintTensorWithoutShape(const AdxDumpMessageHead* const tensorHead, const size_t dataNum)
514 : {
515 14 : const auto& iter = ADX_PRINT_CALLS.find(static_cast<GeDataType>(tensorHead->dataType));
516 14 : if (iter != ADX_PRINT_CALLS.end()) {
517 14 : const uint8_t* const data = (const uint8_t*)(tensorHead) + sizeof(AdxDumpMessageHead);
518 14 : (iter->second)(static_cast<const void*>(data), dataNum);
519 : } else {
520 0 : const std::string dtype = AdumpToString((aclDataType)tensorHead->dataType);
521 0 : IDE_LOGW("Dump tensor doesn't support dtype of %s.", dtype.c_str());
522 0 : }
523 14 : }
524 :
525 21 : static void AdxPrintTensorInfo(const AdxDumpInfoHead* dumpHead, std::vector<size_t>& shape)
526 : {
527 21 : IDE_LOGI("Dump tensor length %u bytes.", dumpHead->infoLen);
528 21 : if (static_cast<size_t>(dumpHead->infoLen) < sizeof(AdxDumpMessageHead)) {
529 2 : return;
530 : }
531 :
532 21 : const AdxDumpMessageHead* const tensorHead = (const AdxDumpMessageHead*)dumpHead->infoMsg;
533 21 : const std::string dtype = AdumpToString((aclDataType)tensorHead->dataType);
534 21 : const uint32_t actualDumpNum = tensorHead->rsv;
535 21 : uint16_t dtypeSize = 0U;
536 21 : const uint32_t dataType = tensorHead->dataType;
537 21 : GetDataTypeSize(dataType, dtypeSize);
538 21 : if (dtypeSize == 0U) {
539 2 : IDE_LOGW("Dump tensor doesn't support dtype of %s.", dtype.c_str());
540 2 : return;
541 : }
542 19 : const size_t actualDataNum = (actualDumpNum == 0U) ?
543 19 : (static_cast<size_t>(dumpHead->infoLen) - sizeof(AdxDumpMessageHead)) / dtypeSize :
544 : static_cast<size_t>(actualDumpNum);
545 19 : const auto& positionIter = POSITION_MAP.find(tensorHead->position);
546 : const std::string position =
547 19 : (positionIter != POSITION_MAP.end()) ? positionIter->second : std::to_string(tensorHead->position);
548 19 : const std::string addrToHex = AdxToHex(tensorHead->addr);
549 19 : std::cout << "DumpTensor: desc=" << std::dec << tensorHead->desc << ", addr=" << addrToHex;
550 19 : std::cout << ", data_type=" << dtype << ", position=" << position << ", dump_size=" << actualDataNum << std::endl;
551 19 : IDE_LOGI(
552 : "DumpTensor: desc=%u, addr=%s, data_type=%s, position=%s, dump_size=%zu.", tensorHead->desc, addrToHex.c_str(),
553 : dtype.c_str(), position.c_str(), actualDataNum);
554 :
555 19 : if (!shape.empty()) {
556 5 : AdxDumpJugdeShape(shape, actualDataNum, tensorHead);
557 5 : shape = {};
558 : } else {
559 14 : AdxDumpPrintTensorWithoutShape(tensorHead, actualDataNum);
560 : }
561 21 : }
562 :
563 1 : static void AdxPrintToLog(std::string& printInfo, const bool isAssert)
564 : {
565 1 : const size_t strLength = printInfo.size();
566 4 : for (size_t i = 0; i < strLength; i += ADX_MAX_LOG_LENGTH) {
567 3 : const size_t subInfoLen = (i + ADX_MAX_LOG_LENGTH) > strLength ? (strLength - i) : ADX_MAX_LOG_LENGTH;
568 3 : if (isAssert) {
569 0 : IDE_LOGE("%s", printInfo.substr(i, subInfoLen).c_str());
570 : } else {
571 3 : IDE_LOGI("PrintInfo: %s", printInfo.substr(i, subInfoLen).c_str());
572 : }
573 : }
574 1 : }
575 :
576 36 : static std::string AdxGetFormat(const char* format)
577 : {
578 36 : std::string temp;
579 36 : if ((*format) == 'l') {
580 10 : temp += std::string(format, 1);
581 10 : format++;
582 10 : if (((*format) != '\0') && ((*format) == 'l')) {
583 5 : temp += std::string(format, 1);
584 5 : format++;
585 5 : if ((*format) != '\0') {
586 5 : temp += std::string(format, 1);
587 5 : return temp;
588 : }
589 5 : } else if ((*format) != '\0') {
590 5 : temp += std::string(format, 1);
591 5 : return temp;
592 : }
593 : }
594 26 : temp += std::string(format, 1);
595 26 : return temp;
596 0 : }
597 :
598 1 : static void AdxPrint(
599 : const char* format, const uint8_t* paramBegin, const size_t maxLen, const size_t paramNum, const bool isAssert)
600 : {
601 1 : size_t paramIndex = 0U;
602 1 : std::string printInfo = "";
603 419 : while ((*format) != '\0') {
604 419 : if ((*format) == '%') {
605 36 : format++;
606 36 : const std::string& tempFormat = AdxGetFormat(format);
607 36 : const auto& iter = ADX_PRINT_FORMAT_CALLS.find(tempFormat);
608 36 : if (iter != ADX_PRINT_FORMAT_CALLS.end()) {
609 35 : paramIndex++;
610 35 : if (paramIndex >= paramNum) {
611 1 : IDE_LOGW(
612 : "Dump print formatting num %zu too much, must be smaller than %zu", paramIndex + 1U, paramNum);
613 1 : break;
614 : }
615 34 : (iter->second)(paramBegin, printInfo, paramIndex, maxLen);
616 : // if条件进来,ADX_PRINT_FORMAT_CALLS中存在tempFormat,size必不为0
617 34 : format += tempFormat.size() - 1;
618 : } else {
619 1 : IDE_LOGW("Dump print format %s is illegal.", tempFormat.c_str());
620 1 : (void)printf("%%");
621 1 : (void)printf("%s", tempFormat.c_str());
622 1 : printInfo += "%" + tempFormat;
623 : }
624 36 : } else {
625 383 : std::cout << *format;
626 383 : printInfo += *format;
627 : }
628 418 : format++;
629 : }
630 1 : AdxPrintToLog(printInfo, isAssert);
631 1 : }
632 :
633 1 : static void AdxPrintPrintInfo(const AdxDumpInfoHead* dumpHead, const bool isAssert)
634 : {
635 1 : IDE_LOGD("Get dump print data length[%u bytes].", dumpHead->infoLen);
636 1 : if (static_cast<size_t>(dumpHead->infoLen) < ADX_PRINT_ARG_LEN) {
637 0 : return;
638 : }
639 1 : const size_t strOffset = *((const size_t*)dumpHead->infoMsg);
640 1 : const size_t argsNum = strOffset / ADX_PRINT_ARG_LEN;
641 1 : const char* str = (const char*)(dumpHead->infoMsg + strOffset);
642 1 : const size_t strLen = strnlen(str, ADX_MAX_STR_LEN);
643 :
644 1 : IDE_LOGD("Get print str len[%zu bytes]", strLen);
645 1 : if (strLen > static_cast<size_t>(dumpHead->infoLen)) {
646 0 : return;
647 : }
648 1 : AdxPrint(str, (const uint8_t*)dumpHead->infoMsg, static_cast<size_t>(dumpHead->infoLen), argsNum, isAssert);
649 : }
650 :
651 6 : static void AdxGetShapeInfo(const AdxDumpInfoHead* dumpHead, std::vector<size_t>& shape)
652 : {
653 6 : const AdxDumpShapeMessageHead* const shapeHead = (const AdxDumpShapeMessageHead*)dumpHead->infoMsg;
654 20 : for (size_t i = 0U; i < shapeHead->dim; i++) {
655 14 : shape.push_back(shapeHead->shape[i]);
656 : }
657 6 : }
658 :
659 1166 : static void AdxPrintPrint(const AdxDumpInfoHead* dumpHead, const bool isAssert, std::vector<size_t>& shapeInfo)
660 : {
661 1166 : if (!isAssert) {
662 886 : if (dumpHead->type == AdxDumpType::DUMP_SCALAR) {
663 1 : AdxPrintPrintInfo(dumpHead, isAssert);
664 885 : } else if (dumpHead->type == AdxDumpType::DUMP_TENSOR) {
665 21 : AdxPrintTensorInfo(dumpHead, shapeInfo);
666 864 : } else if (dumpHead->type == AdxDumpType::DUMP_SHAPE) {
667 6 : AdxGetShapeInfo(dumpHead, shapeInfo);
668 : }
669 : } else {
670 280 : if (dumpHead->type == AdxDumpType::DUMP_ASSERT) {
671 0 : AdxPrintPrintInfo(dumpHead, isAssert);
672 : }
673 : }
674 1166 : }
675 :
676 17 : static std::string AdxGetCoreType(const uint8_t coreType, const uint8_t mixFlag)
677 : {
678 17 : IDE_LOGD("DumpMeta: coreType is %u, mixFlag is %u.", coreType, mixFlag);
679 21 : static const std::map<uint8_t, std::string> CORE_TYPE_MAP{{1, "AIC"}, {2, "AIV"}};
680 17 : std::string strCoreType;
681 17 : if (mixFlag == 0U) {
682 14 : const auto& iter = CORE_TYPE_MAP.find(coreType);
683 14 : if (iter != CORE_TYPE_MAP.end()) {
684 4 : strCoreType = iter->second;
685 : }
686 : } else {
687 3 : strCoreType = "MIX";
688 : }
689 17 : return strCoreType;
690 1 : }
691 :
692 1 : static void AdxPrintTimeStampInfo(const AdxDumpInfoHead* dumpHead, MsprofAicTimeStampInfo* timeStampInfo)
693 : {
694 1 : const uint8_t* info = (const uint8_t*)(dumpHead->infoMsg);
695 1 : timeStampInfo->descId = *(reinterpret_cast<const uint32_t*>(info));
696 1 : info += sizeof(uint32_t);
697 1 : uint32_t rsv = *(reinterpret_cast<const uint32_t*>(info));
698 1 : info += sizeof(uint32_t);
699 1 : timeStampInfo->syscyc = *(reinterpret_cast<const uint64_t*>(info));
700 1 : info += sizeof(uint64_t);
701 1 : timeStampInfo->curPc = *(reinterpret_cast<const uint64_t*>(info));
702 :
703 1 : if (!g_adxPrintConfigFlag) {
704 1 : (void)printf(
705 : "descId is %u, rsv is %u, timeStamp is %" PRIu64 ", pcPtr is %" PRIu64 ".\n", timeStampInfo->descId, rsv,
706 : timeStampInfo->syscyc, timeStampInfo->curPc);
707 : }
708 1 : IDE_LOGI(
709 : "descId is %u, rsv is %u, timeStamp is %" PRIu64 ", pcPtr is %" PRIu64 ".", timeStampInfo->descId, rsv,
710 : timeStampInfo->syscyc, timeStampInfo->curPc);
711 1 : }
712 :
713 17 : static void AdxPrintHeadInfo(const uint8_t* blockData, const char* opType, const bool isAssert)
714 : {
715 17 : const AdxBlockInfo* blockInfo = (const AdxBlockInfo*)(blockData);
716 17 : const std::string magicToHex = AdxToHex(blockInfo->magic);
717 17 : const AdxDumpMeta* dumpMeta = (const AdxDumpMeta*)(blockData + sizeof(AdxBlockInfo));
718 17 : const std::string coreTypeId = AdxGetCoreTypeId(blockInfo->core, dumpMeta->coreType);
719 17 : const std::string coreType = AdxGetCoreType(dumpMeta->coreType, dumpMeta->mixFlag);
720 17 : if (!isAssert) {
721 13 : std::cout << "opType=" << opType << ", ";
722 13 : IDE_LOGI("PrintInfo: opType=%s", opType);
723 : }
724 17 : if (blockInfo->rsv == ADX_OFF_LIMIT_RSV) {
725 7 : std::cout << "Remain block space is not enough, printing information may be incomplete!" << std::endl;
726 7 : IDE_LOGI("PrintInfo: Remain block space is not enough, printing information may be incomplete!");
727 : }
728 17 : std::cout << "DumpHead: " << coreTypeId << ", CoreType=" << coreType << ", block dim=" << dumpMeta->blockDim;
729 17 : std::cout << ", total_block_num=" << blockInfo->blockNum;
730 17 : std::cout << ", block_remain_len=" << blockInfo->remainLen << ", block_initial_space=" << blockInfo->len;
731 17 : std::cout << ", rsv=" << blockInfo->rsv << ", magic=" << magicToHex;
732 17 : std::cout << std::endl;
733 17 : IDE_LOGI(
734 : "PrintInfo: DumpHead: %s, CoreType=%s, block dim=%d, "
735 : "total_block_num=%u, block_remain_len=%u, block_initial_space=%u, rsv=%u, magic=%s",
736 : coreTypeId.c_str(), coreType.c_str(), dumpMeta->blockDim, blockInfo->blockNum, blockInfo->remainLen,
737 : blockInfo->len, blockInfo->rsv, magicToHex.c_str());
738 17 : }
739 :
740 0 : static void AdxPrintSimtHeadInfo(const uint8_t* blockData, const char* opType)
741 : {
742 0 : const AdxBlockInfo* blockInfo = Adx::SysUtils::ReinterpretCast<const AdxBlockInfo, const uint8_t>(blockData);
743 0 : const std::string magicToHex = AdxToHex(blockInfo->magic);
744 : const AdxSimtDumpMeta* dumpMeta =
745 0 : Adx::SysUtils::ReinterpretCast<const AdxSimtDumpMeta, const uint8_t>(blockData + sizeof(AdxBlockInfo));
746 0 : const uint32_t threadId = dumpMeta->threadId;
747 :
748 0 : std::cout << "opType=" << opType << ", blockId=" << blockInfo->core << ", threadId=" << threadId << std::endl;
749 0 : if (threadId == 0) {
750 0 : IDE_LOGD(
751 : "Simt print info: opType=%s, blockId: %d, threadId=%d, "
752 : "total_block_num=%u, block_remain_len=%u, block_initial_space=%u, rsv=%u, magic=%s",
753 : opType, blockInfo->core, threadId, blockInfo->blockNum, blockInfo->remainLen, blockInfo->len,
754 : blockInfo->rsv, magicToHex.c_str());
755 : }
756 :
757 0 : if (blockInfo->rsv == ADX_OFF_LIMIT_RSV) {
758 0 : std::cout << "Remain block space is not enough, printing information may be incomplete!" << std::endl;
759 0 : IDE_LOGI("Simt print info: Remain block space is not enough, printing information may be incomplete!");
760 : }
761 0 : }
762 :
763 20 : static void AdxPrintBlockInfo(
764 : const uint8_t* blockData, size_t blockDataLen, const char* opType, const bool isAssert,
765 : std::vector<MsprofAicTimeStampInfo>& timeStampInfo)
766 : {
767 20 : const AdxBlockInfo* blockInfo = (const AdxBlockInfo*)(blockData);
768 20 : const size_t maxDataLen = blockDataLen - sizeof(AdxBlockInfo) - sizeof(AdxDumpMeta);
769 20 : if (static_cast<size_t>(blockInfo->remainLen) > maxDataLen) {
770 1 : IDE_LOGW(
771 : "Block info remain length %u bytes illegal, must small than %zu bytes.", blockInfo->remainLen, maxDataLen);
772 1 : return;
773 : }
774 :
775 19 : bool flag = false;
776 19 : const uint8_t* beginAddr = blockData + sizeof(AdxBlockInfo) + sizeof(AdxDumpMeta);
777 19 : const size_t dataLen = maxDataLen - static_cast<size_t>(blockInfo->remainLen);
778 19 : size_t offset = 0UL;
779 19 : std::vector<size_t> shape;
780 1186 : while ((offset + sizeof(AdxDumpInfoHead)) <= dataLen) {
781 1172 : auto dumpHead = (const AdxDumpInfoHead*)(beginAddr + offset);
782 1172 : if ((!flag) && ((dumpHead->type != AdxDumpType::DUMP_TIMESTAMP) ||
783 1 : ((dumpHead->type == AdxDumpType::DUMP_TIMESTAMP) && (!g_adxPrintConfigFlag)))) {
784 17 : AdxPrintHeadInfo(blockData, opType, isAssert);
785 17 : flag = true;
786 : }
787 1172 : offset += sizeof(AdxDumpInfoHead);
788 1172 : offset += static_cast<size_t>(dumpHead->infoLen); // uint32转为size_t的,大小范围一定不会发生反转
789 1172 : if (offset > dataLen) {
790 5 : IDE_LOGW("Dump data info length %u bytes illegal.", dumpHead->infoLen);
791 5 : return;
792 : }
793 :
794 1167 : if ((dumpHead->type == AdxDumpType::DUMP_TIMESTAMP) && !isAssert) {
795 : MsprofAicTimeStampInfo timeInfo;
796 1 : timeInfo.blockId = blockInfo->core;
797 1 : AdxPrintTimeStampInfo(dumpHead, &timeInfo);
798 1 : timeStampInfo.push_back(timeInfo);
799 1 : } else {
800 : // 获取到shape信息时, 按照shape打印tensor
801 1166 : AdxPrintPrint(dumpHead, isAssert, shape);
802 : }
803 : }
804 14 : return;
805 19 : }
806 :
807 0 : static void AdxPrintSimtBlockInfo(const uint8_t* blockData, size_t blockDataLen, const char* opType)
808 : {
809 0 : const AdxBlockInfo* blockInfo = Adx::SysUtils::ReinterpretCast<const AdxBlockInfo, const uint8_t>(blockData);
810 0 : const size_t maxDataLen = blockDataLen - sizeof(AdxBlockInfo) - sizeof(AdxSimtDumpMeta);
811 0 : if (static_cast<size_t>(blockInfo->remainLen) > maxDataLen) {
812 0 : IDE_LOGW("Block info remainLen(%u) is illegal, must be small than %zu.", blockInfo->remainLen, maxDataLen);
813 0 : return;
814 : }
815 :
816 0 : const uint8_t* beginAddr = blockData + sizeof(AdxBlockInfo) + sizeof(AdxSimtDumpMeta);
817 0 : const size_t dataLen = maxDataLen - static_cast<size_t>(blockInfo->remainLen);
818 0 : size_t offset = 0UL;
819 :
820 0 : if ((offset + sizeof(AdxDumpInfoHead)) <= dataLen) {
821 0 : AdxPrintSimtHeadInfo(blockData, opType);
822 : }
823 :
824 0 : while ((offset + sizeof(AdxDumpInfoHead)) <= dataLen) {
825 0 : auto dumpHead = Adx::SysUtils::ReinterpretCast<const AdxDumpInfoHead, const uint8_t>(beginAddr + offset);
826 :
827 0 : offset += sizeof(AdxDumpInfoHead);
828 0 : offset += static_cast<size_t>(dumpHead->infoLen);
829 0 : if (offset > dataLen) {
830 0 : IDE_LOGW("Dump data info len(%u) is illegal.", dumpHead->infoLen);
831 0 : return;
832 : }
833 :
834 0 : if (dumpHead->type != AdxDumpType::DUMP_SIMT) {
835 0 : IDE_LOGW("Dump type(%u) is not DUMP_SIMT, just skip", dumpHead->type);
836 0 : continue;
837 : }
838 :
839 0 : AdxPrintPrintInfo(dumpHead, false);
840 : }
841 : }
842 :
843 13 : static void AdxPrintDumpdata(
844 : const std::vector<uint8_t>& printData, size_t dumpWorkSpaceSize, const char* opType, const bool isAssert,
845 : std::vector<MsprofAicTimeStampInfo>& timeStampInfo)
846 : {
847 13 : const uint8_t* const addr = printData.data();
848 13 : const AdxBlockInfo* blockInfo = (const AdxBlockInfo*)(addr);
849 :
850 13 : size_t blockDataLen = blockInfo->len;
851 13 : IDE_LOGI("dumpWorkSpaceSize is %zu bytes, blockDataLen is %zu bytes.", dumpWorkSpaceSize, blockDataLen);
852 13 : if ((blockDataLen == 0U) || ((blockDataLen != ADX_MAX_STR_LEN) && (blockDataLen != ADX_ASSERT_LEN))) {
853 3 : const uint32_t* dataAddr = (const uint32_t*)printData.data();
854 771 : for (size_t i = 0U; (i + 4) < dumpWorkSpaceSize / sizeof(uint32_t); i++) { // magic和len隔了4个uint32_t
855 771 : if (*(dataAddr + i + 4) == ADX_DUMP_AND_PRINT_MAGIC_NUM) { // magic和len隔了4个uint32_t
856 3 : blockDataLen = *(dataAddr + i);
857 3 : break;
858 : }
859 : }
860 : }
861 :
862 13 : IDE_LOGD("printType is %d, 1 is assert, 0 is printf, blockDataLen is %zu.", isAssert, blockDataLen);
863 :
864 13 : if ((blockDataLen != ADX_MAX_STR_LEN) && (blockDataLen != ADX_ASSERT_LEN)) {
865 1 : IDE_LOGE("blockDataLen %zu bytes is illegal.", blockDataLen);
866 1 : return;
867 : }
868 :
869 12 : size_t blockNum = AdxGetBlockNum();
870 912 : for (size_t i = 0U; i < blockNum; i++) {
871 900 : const AdxBlockInfo* info = (const AdxBlockInfo*)(addr + blockDataLen * i);
872 900 : if (info->magic != ADX_DUMP_AND_PRINT_MAGIC_NUM) {
873 880 : IDE_LOGW("Block info[%zu] is illegal, magic is %u.", i, info->magic);
874 880 : continue;
875 : }
876 20 : AdxPrintBlockInfo(addr + blockDataLen * i, blockDataLen, opType, isAssert, timeStampInfo);
877 : }
878 :
879 12 : if (!AdxEnableSimtDump(dumpWorkSpaceSize)) {
880 12 : return;
881 : }
882 :
883 0 : const uint8_t* const simtAddr = addr + blockNum * blockDataLen;
884 0 : const AdxBlockInfo* simtBlockInfo = Adx::SysUtils::ReinterpretCast<const AdxBlockInfo, const uint8_t>(simtAddr);
885 0 : size_t simtBlockDataLen = simtBlockInfo->len;
886 0 : if (simtBlockDataLen != ADX_SIMT_PRINT_LEN) {
887 0 : IDE_LOGW("Simt block info length %zu is illegal.", simtBlockDataLen);
888 0 : return;
889 : }
890 :
891 0 : for (size_t i = 0U; i < ADX_SIMT_BLOCK_NUM; i++) {
892 0 : for (uint32_t j = 0U; j < ADX_SIMT_MAX_THREAD_NUM; j++) {
893 0 : uint32_t threadOffset = i * ADX_SIMT_MAX_THREAD_NUM + j;
894 0 : const AdxBlockInfo* info = Adx::SysUtils::ReinterpretCast<const AdxBlockInfo, const uint8_t>(
895 0 : simtAddr + simtBlockDataLen * threadOffset);
896 :
897 0 : if (info->magic != ADX_DUMP_AND_PRINT_MAGIC_NUM) {
898 0 : continue;
899 : }
900 :
901 0 : AdxPrintSimtBlockInfo(simtAddr + simtBlockDataLen * threadOffset, simtBlockDataLen, opType);
902 : }
903 : }
904 : }
905 :
906 12 : static rtError_t AdxGetWorkspaceData(
907 : void* printData, const void* workSpaceAddr, const size_t dumpWorkSpaceSize, aclrtStream stream,
908 : bool enableSync = true)
909 : {
910 12 : int32_t timeout = GetStreamSynchronizeTimeout();
911 12 : if (enableSync) {
912 12 : auto rtRet = rtStreamSynchronizeWithTimeout(stream, timeout);
913 12 : if (rtRet != RT_ERROR_NONE) {
914 2 : IDE_LOGE("Synchronize stream failed, error code is %d.", rtRet);
915 2 : printf(
916 : "ERROR: Synchronize stream failed, error code is %d, please check plog for more information.\n", rtRet);
917 : }
918 : }
919 12 : auto rtRet = rtMemcpy(printData, dumpWorkSpaceSize, workSpaceAddr, dumpWorkSpaceSize, RT_MEMCPY_DEVICE_TO_HOST);
920 12 : if (rtRet != RT_ERROR_NONE) {
921 1 : IDE_LOGE(
922 : "Call rtMemcpy failed, ret: 0x%X, ori[%p], dts[%p], size[%lu bytes]. ", rtRet, workSpaceAddr, printData,
923 : dumpWorkSpaceSize);
924 : }
925 12 : return rtRet;
926 : }
927 :
928 11 : void AdxPrintWorkSpace(
929 : const void* workSpaceAddr, const size_t dumpWorkSpaceSize, aclrtStream stream, const char* opType,
930 : bool enableSync = true)
931 : {
932 11 : std::vector<uint8_t> printData(dumpWorkSpaceSize);
933 11 : if (AdxGetWorkspaceData(printData.data(), workSpaceAddr, dumpWorkSpaceSize, stream, enableSync) == RT_ERROR_NONE) {
934 10 : std::vector<MsprofAicTimeStampInfo> timeStampInfo;
935 10 : AdxPrintDumpdata(printData, dumpWorkSpaceSize, opType, false, timeStampInfo);
936 10 : }
937 11 : }
938 :
939 2 : void AdxPrintSetConfig(const Adx::AdumpPrintConfig& config)
940 : {
941 2 : const std::lock_guard<std::mutex> lock(g_adxPrintConfigMtx);
942 2 : g_adxPrintConfigFlag = config.printEnable;
943 2 : }
944 :
945 1 : void AdxPrintTimeStamp(
946 : const void* workSpaceAddr, const size_t dumpWorkSpaceSize, aclrtStream stream, const char* opType,
947 : std::vector<MsprofAicTimeStampInfo>& timeStampInfo)
948 : {
949 1 : std::vector<uint8_t> printData(dumpWorkSpaceSize);
950 1 : if (AdxGetWorkspaceData(printData.data(), workSpaceAddr, dumpWorkSpaceSize, stream, true) == RT_ERROR_NONE) {
951 1 : AdxPrintDumpdata(printData, dumpWorkSpaceSize, opType, false, timeStampInfo);
952 : }
953 1 : }
954 :
955 2 : static bool AdxGetWorkspaceInfoForAssert(
956 : rtExceptionArgsInfo_t& argsInfo, rtArgsSizeInfo& sizeInfo, void** workSpaceAddr, uint64_t& workSpaceSize)
957 : {
958 2 : uint64_t* infoAddr = reinterpret_cast<uint64_t*>(sizeInfo.infoAddr); // atomic
959 2 : IDE_LOGD("rtArgsSizeInfo is %p.", infoAddr);
960 2 : if (infoAddr == nullptr) {
961 0 : IDE_LOGW("Get sizeInfo addr is nullptr, unable to resolve assert info.");
962 0 : return false;
963 : }
964 2 : infoAddr++;
965 2 : uint64_t addrNum = *infoAddr;
966 2 : bool hasFftsAddr = false;
967 2 : hasFftsAddr = (((*infoAddr) >> ADX_FFTS_ADDR_OFFSET) == 1ULL) ? true : false;
968 : // 标记ffts地址
969 2 : if (hasFftsAddr) {
970 1 : addrNum &= ADX_INPUT_NUM_MASK;
971 : }
972 2 : infoAddr++;
973 2 : uint64_t offset = 0U;
974 2 : bool hasWorkSpaceSizeFlag = false;
975 9 : for (size_t i = 0; i < addrNum; i++) {
976 : // 标记workspace
977 9 : if (((*infoAddr) >> ADX_SIZE_BITS_OFFSET) == ADX_WORKSPACE_SIZE_FLAG) {
978 2 : workSpaceSize = (*infoAddr) & ADX_SIZE_MASK;
979 2 : hasWorkSpaceSizeFlag = true;
980 2 : break;
981 : }
982 : // 标记动态输入个数
983 7 : if (((*infoAddr) >> ADX_SIZE_BITS_OFFSET) == ADX_DYNAMIC_INPUT_FLAG) {
984 1 : uint64_t dynamicTensorNum = (*infoAddr) & ADX_SIZE_MASK;
985 1 : IDE_LOGD("[Assert] Get dynamicTensorNum is %lu.", dynamicTensorNum);
986 1 : infoAddr += dynamicTensorNum;
987 : }
988 7 : offset += 1;
989 7 : ++infoAddr;
990 : }
991 2 : if (!hasWorkSpaceSizeFlag) {
992 0 : return false;
993 : }
994 : // 获取workspace地址 argsInfo.argAddr args的首地址
995 2 : uint64_t* argsAddr =
996 2 : hasFftsAddr ? ((uint64_t*)argsInfo.argAddr + offset + 1U) : ((uint64_t*)argsInfo.argAddr + offset);
997 :
998 2 : auto rtRet = rtMemcpy(workSpaceAddr, sizeof(uint64_t), argsAddr, sizeof(uint64_t), RT_MEMCPY_DEVICE_TO_HOST);
999 2 : if (rtRet != RT_ERROR_NONE) {
1000 1 : IDE_LOGE(
1001 : "Call rtMemcpy failed, ret: 0x%X, ori[%p], dts[%p], size[%lu bytes].", rtRet, argsAddr, workSpaceAddr,
1002 : sizeof(uint64_t));
1003 1 : return false;
1004 : }
1005 1 : return true;
1006 : }
1007 :
1008 2 : static void AdxPrintAssert(const void* workSpaceAddr, const size_t dumpWorkSpaceSize)
1009 : {
1010 2 : IDE_LOGD("[Assert] workSpaceAddr[%p], dumpWorkSpaceSize[%llu].", workSpaceAddr, dumpWorkSpaceSize);
1011 2 : std::vector<uint8_t> printData(dumpWorkSpaceSize);
1012 : auto rtRet =
1013 2 : rtMemcpy(printData.data(), dumpWorkSpaceSize, workSpaceAddr, dumpWorkSpaceSize, RT_MEMCPY_DEVICE_TO_HOST);
1014 2 : if (rtRet != RT_ERROR_NONE) {
1015 0 : IDE_LOGW("Call rtMemcpy failed, ret: 0x%X", rtRet);
1016 0 : return;
1017 : }
1018 2 : std::vector<MsprofAicTimeStampInfo> timeStampInfo;
1019 2 : AdxPrintDumpdata(printData, dumpWorkSpaceSize, "", true, timeStampInfo);
1020 2 : }
1021 :
1022 2 : static bool AdxGetFftsWorkspaceInfoForAssert(
1023 : uint16_t contextId, rtExceptionArgsInfo_t& argsInfo, rtArgsSizeInfo& sizeInfos, void** workSpaceAddr,
1024 : uint64_t& workSpaceSize)
1025 : {
1026 2 : constexpr uint32_t contextBeginIndex = 2u; // 2 is atomic + totalSize
1027 2 : uint64_t* sizeInfo = reinterpret_cast<uint64_t*>(sizeInfos.infoAddr);
1028 2 : IDE_LOGD("rtArgsSizeInfo is %p.", sizeInfo);
1029 2 : if (sizeInfo == nullptr) {
1030 0 : IDE_LOGW("Get sizeInfo addr is nullptr, unable to resolve assert info.");
1031 0 : return false;
1032 : }
1033 2 : const uint64_t totalContextSizeNum = sizeInfo[1];
1034 2 : uint32_t sizeBeginIndex = 0U;
1035 2 : for (uint64_t sizeInfoIdx = contextBeginIndex; sizeInfoIdx < (totalContextSizeNum + contextBeginIndex);
1036 : ++sizeInfoIdx) {
1037 2 : if (sizeInfo[sizeInfoIdx] == contextId) {
1038 2 : sizeBeginIndex = sizeInfoIdx + 3; // 3 - context id | args size | input num
1039 2 : break;
1040 : }
1041 : }
1042 :
1043 2 : uint64_t offset = 0U;
1044 2 : uint64_t* infoAddr = sizeInfo + sizeBeginIndex;
1045 2 : bool hasWorkSpaceSizeFlag = false;
1046 21 : for (size_t i = sizeBeginIndex; i < totalContextSizeNum; i++) {
1047 : // 标记workspace
1048 20 : if (((*infoAddr) >> ADX_SIZE_BITS_OFFSET) == ADX_WORKSPACE_SIZE_FLAG) {
1049 1 : workSpaceSize = (*infoAddr) & ADX_SIZE_MASK;
1050 1 : hasWorkSpaceSizeFlag = true;
1051 1 : break;
1052 : }
1053 : // 标记动态输入个数
1054 19 : if (((*infoAddr) >> ADX_SIZE_BITS_OFFSET) == ADX_DYNAMIC_INPUT_FLAG) {
1055 2 : uint64_t dynamicTensorNum = (*infoAddr) & ADX_SIZE_MASK;
1056 2 : IDE_LOGD("[Assert] Get dynamicTensorNum is %lu.", dynamicTensorNum);
1057 2 : infoAddr += dynamicTensorNum;
1058 : }
1059 19 : offset += 1;
1060 19 : ++infoAddr;
1061 : }
1062 2 : IDE_LOGD(
1063 : "[Assert] sizeBeginIndex is %lu, offset is %lu, totalContextSizeNum is %lu.", sizeBeginIndex, offset,
1064 : totalContextSizeNum);
1065 2 : if (!hasWorkSpaceSizeFlag) {
1066 1 : IDE_LOGE("[Assert] not find workSpaceSize.");
1067 1 : return false;
1068 : }
1069 :
1070 : // 获取workspace地址 argsInfo.argAddr args的首地址
1071 1 : uint64_t* argsAddr = (uint64_t*)argsInfo.argAddr + offset;
1072 1 : auto rtRet = rtMemcpy(workSpaceAddr, sizeof(uint64_t), argsAddr, sizeof(uint64_t), RT_MEMCPY_DEVICE_TO_HOST);
1073 1 : if (rtRet != RT_ERROR_NONE) {
1074 0 : IDE_LOGE(
1075 : "Call rtMemcpy failed, ret: 0x%X, ori[%p], dts[%p], size[%lu].", rtRet, argsAddr, workSpaceAddr,
1076 : sizeof(uint64_t));
1077 0 : return false;
1078 : }
1079 1 : return true;
1080 : }
1081 :
1082 8 : bool AdxCheckAtomicIndex(const rtExceptionArgsInfo_t& exceptionArgsInfo)
1083 : {
1084 8 : if (exceptionArgsInfo.sizeInfo.infoAddr == nullptr) {
1085 2 : IDE_LOGE("infoAddr is null");
1086 2 : return false;
1087 : }
1088 :
1089 6 : uint64_t* sizeInfo = static_cast<uint64_t*>(exceptionArgsInfo.sizeInfo.infoAddr);
1090 6 : if (sizeInfo < Adx::g_chunk || sizeInfo > (Adx::g_chunk + Adx::RING_CHUNK_SIZE - 1)) {
1091 1 : IDE_LOGE("[Assert] the size info[%p] address may out of the chunk[%p] address range.", sizeInfo, Adx::g_chunk);
1092 1 : return false;
1093 : }
1094 5 : if (sizeInfo[0] != exceptionArgsInfo.sizeInfo.atomicIndex) {
1095 1 : IDE_LOGE(
1096 : "[Dump][Exception] args exception atomic index between %llu and %llu is different.", sizeInfo[0],
1097 : exceptionArgsInfo.sizeInfo.atomicIndex);
1098 1 : return false;
1099 : }
1100 4 : return true;
1101 : }
1102 :
1103 10 : void AdxAssertCallBack(rtExceptionInfo_t* exceptionInfo)
1104 : {
1105 10 : uint32_t timeout = 0U;
1106 10 : rtError_t ret = rtGetOpExecuteTimeoutV2(&timeout);
1107 10 : if (ret != ACL_RT_SUCCESS) {
1108 0 : IDE_LOGE("Get operator timeout failed, ret: %d", ret);
1109 : } else {
1110 10 : IDE_LOGI("Get operator timeout %ums", timeout);
1111 10 : if (timeout < TIMEOUT_THRESHOLD) {
1112 0 : IDE_LOGI(
1113 : "Operator timeout %ums, enable fast recovery, skip parsing printf/assert/DumpTensor content.", timeout);
1114 7 : return;
1115 : }
1116 : }
1117 10 : void* workSpaceAddr = nullptr;
1118 10 : uint64_t dumpWorkSpaceSize = 0U;
1119 10 : bool res = false;
1120 10 : if (exceptionInfo != nullptr) {
1121 9 : rtExceptionExpandType_t exceptionTaskType = exceptionInfo->expandInfo.type;
1122 9 : rtExceptionArgsInfo_t exceptionArgsInfo{};
1123 9 : if (exceptionTaskType == RT_EXCEPTION_AICORE) {
1124 2 : exceptionArgsInfo = exceptionInfo->expandInfo.u.aicoreInfo.exceptionArgs;
1125 7 : } else if (exceptionTaskType == RT_EXCEPTION_FFTS_PLUS) {
1126 5 : exceptionArgsInfo = exceptionInfo->expandInfo.u.fftsPlusInfo.exceptionArgs;
1127 2 : } else if (exceptionTaskType == RT_EXCEPTION_FUSION) {
1128 1 : exceptionArgsInfo = exceptionInfo->expandInfo.u.fusionInfo.u.aicoreCcuInfo.exceptionArgs;
1129 : } else {
1130 1 : IDE_LOGW("Exception type[%d] is not supported.", static_cast<int32_t>(exceptionTaskType));
1131 7 : return;
1132 : }
1133 :
1134 8 : if (!AdxCheckAtomicIndex(exceptionArgsInfo)) {
1135 4 : return;
1136 : }
1137 :
1138 4 : if (exceptionTaskType == RT_EXCEPTION_FFTS_PLUS) {
1139 2 : IDE_LOGD("[Assert] opType is mix fftsplus.");
1140 2 : res = AdxGetFftsWorkspaceInfoForAssert(
1141 2 : exceptionInfo->expandInfo.u.fftsPlusInfo.contextId, exceptionArgsInfo, exceptionArgsInfo.sizeInfo,
1142 : &workSpaceAddr, dumpWorkSpaceSize);
1143 : } else {
1144 2 : res = AdxGetWorkspaceInfoForAssert(
1145 : exceptionArgsInfo, exceptionArgsInfo.sizeInfo, &workSpaceAddr, dumpWorkSpaceSize);
1146 : }
1147 4 : if (res) {
1148 2 : AdxPrintAssert(workSpaceAddr, dumpWorkSpaceSize);
1149 2 : return;
1150 : }
1151 : }
1152 : }
1153 : #ifdef __cplusplus
1154 : }
1155 : #endif
|