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