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 : #include "dump_task.h"
11 :
12 : #include <algorithm>
13 : #include <regex>
14 : #include <sstream>
15 : #include <vector>
16 : #include <dlfcn.h>
17 : #include "aicpusd_drv_manager.h"
18 : #include "aicpusd_status.h"
19 : #include "aicpusd_monitor.h"
20 : #include "aicpusd_model_execute.h"
21 : #include "common/aicpusd_util.h"
22 : #include "securec.h"
23 : #include "metadef_types.h"
24 :
25 : namespace AicpuSchedule {
26 :
27 : // slice size for dump file, 128MByes
28 : const uint64_t DUMP_SLICE_SIZE = 128UL << 20U;
29 : const std::string KFC_DUMP_KERNEL_NAME = "AicpuKfcDumpSrvLaunch";
30 :
31 131 : OpDumpTask::OpDumpTask(const int32_t hostPid, const uint32_t deviceId)
32 131 : : taskDumpNum_(0U),
33 131 : endGraph_(false),
34 131 : inputTotalSize_(0U),
35 131 : outputTotalSize_(0U),
36 131 : opBufferTotalSize_(0U),
37 131 : opWorkspaceTotalSize_(0U),
38 131 : buff_(nullptr),
39 131 : buffSize_(0U),
40 131 : offset_(0U),
41 131 : skipAddressConversion_(false),
42 131 : hostPid_(hostPid),
43 131 : deviceId_(deviceId),
44 131 : dumpMode_(DumpMode::TENSOR_DUMP_DATA) {}
45 :
46 45 : StatusCode OpDumpTask::GetDumpNumber(uint64_t &dumpNum)
47 : {
48 45 : if (optionalParam_.hasStepId) {
49 32 : if (optionalParam_.stepIdAddr == nullptr) {
50 0 : aicpusd_err("op name[%s], step id addr is null", opName_.c_str());
51 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
52 : }
53 32 : const uint64_t stepId = *(optionalParam_.stepIdAddr);
54 32 : aicpusd_info("op name[%s], step id is[%llu]", opName_.c_str(), stepId);
55 32 : uint64_t iterationsPerLoop = 0U;
56 32 : uint64_t loopCond = 0U;
57 32 : if (optionalParam_.hasIterationsPerLoop) {
58 30 : if (optionalParam_.iterationsPerLoopAddr == nullptr) {
59 0 : aicpusd_err("op name[%s], iterations per loop addr is null", opName_.c_str());
60 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
61 : }
62 30 : iterationsPerLoop = *(optionalParam_.iterationsPerLoopAddr);
63 30 : aicpusd_info("op name[%s], iterations per loop is[%llu]", opName_.c_str(), iterationsPerLoop);
64 : }
65 32 : if (optionalParam_.hasLoopCond) {
66 30 : if (optionalParam_.loopCondAddr == nullptr) {
67 1 : aicpusd_err("op name[%s], loop cond addr is null", opName_.c_str());
68 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
69 : }
70 29 : loopCond = *(optionalParam_.loopCondAddr);
71 29 : aicpusd_info("op name[%s], loop cond is[%llu]", opName_.c_str(), loopCond);
72 : }
73 31 : aicpusd_info("op name[%s], step id[%llu], iterations per loop[%llu], loop cond[%llu]",
74 : opName_.c_str(), stepId, iterationsPerLoop, loopCond);
75 : // overflow does not matter
76 31 : dumpNum = (stepId * (iterationsPerLoop + 1U)) + loopCond;
77 : } else {
78 13 : dumpNum = taskDumpNum_;
79 : }
80 :
81 44 : return AICPU_SCHEDULE_OK;
82 : }
83 :
84 40 : StatusCode OpDumpTask::PreProcessOutput(const aicpu::dump::Task &task,
85 : ::toolkit::dumpdata::DumpData &dumpData)
86 : {
87 40 : const auto &outputsFromMapInfo = task.output();
88 88 : for (int64_t i = 0; i < outputsFromMapInfo.size(); ++i) {
89 48 : const auto &item = outputsFromMapInfo.at(i);
90 48 : ::toolkit::dumpdata::OpOutput * const opOutput = dumpData.add_output();
91 48 : if (opOutput == nullptr) {
92 0 : aicpusd_err("op name[%s], call protobuf function to add output elem failed", opName_.c_str());
93 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
94 : }
95 48 : opOutput->set_data_type(static_cast<::toolkit::dumpdata::OutputDataType>(item.data_type()));
96 48 : const auto format = item.format();
97 48 : opOutput->set_format(static_cast<::toolkit::dumpdata::OutputFormat>(ge::GetPrimaryFormat(format)));
98 48 : opOutput->set_sub_format(ge::GetSubFormat(format));
99 48 : opOutput->set_offset(static_cast<::toolkit::dumpdata::OutputDataType>(item.offset()));
100 :
101 48 : const int32_t addrType = item.addr_type();
102 48 : std::vector<uint64_t> outputShape;
103 48 : std::vector<uint64_t> outputOriginshape;
104 48 : if (addrType != aicpu::dump::NOTILING_ADDR) {
105 41 : const auto dims = item.shape().dim();
106 41 : ::toolkit::dumpdata::Shape * const outShape = opOutput->mutable_shape();
107 88 : for (const auto dim : dims) {
108 47 : outShape->add_dim(dim);
109 47 : outputShape.push_back(dim);
110 : }
111 41 : const auto originalDims = item.origin_shape().dim();
112 41 : ::toolkit::dumpdata::Shape * const outOriginalShape = opOutput->mutable_original_shape();
113 57 : for (const auto dim : originalDims) {
114 16 : outOriginalShape->add_dim(dim);
115 16 : outputOriginshape.push_back(dim);
116 : }
117 41 : opOutput->set_size(item.size());
118 41 : outputTotalSize_ += item.size();
119 41 : }
120 :
121 48 : if (!item.original_name().empty()) {
122 35 : ::toolkit::dumpdata::OriginalOp * const orgOp = opOutput->mutable_original_op();
123 35 : orgOp->set_name(item.original_name());
124 35 : orgOp->set_output_index(static_cast<uint32_t>(item.original_output_index()));
125 35 : orgOp->set_data_type(static_cast<::toolkit::dumpdata::OutputDataType>(item.original_output_data_type()));
126 35 : orgOp->set_format(static_cast<::toolkit::dumpdata::OutputFormat>(item.original_output_format()));
127 : }
128 :
129 48 : const auto &dim_rangeFromOutput = item.dim_range();
130 56 : for (int64_t i = 0; i < dim_rangeFromOutput.size(); ++i) {
131 8 : const auto &item = dim_rangeFromOutput.at(i);
132 8 : ::toolkit::dumpdata::DimRange * const dimRange = opOutput->add_dim_range();
133 8 : if (dimRange == nullptr) {
134 0 : aicpusd_err("op name[%s], call protobuf function to add dim_range elem failed, i[%lld],"
135 : " dim_range_size[%zu]", opName_.c_str(), i, dim_rangeFromOutput.size());
136 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
137 : }
138 8 : dimRange->set_dim_start(item.dim_start());
139 8 : dimRange->set_dim_end(item.dim_end());
140 : }
141 48 : outputsBaseAddr_.push_back(item.address());
142 48 : outputsAddrType_.push_back(item.addr_type());
143 48 : outputSize_.push_back(item.size());
144 48 : outputOffset_.push_back(item.offset());
145 48 : outputsDataType_.push_back(item.data_type());
146 48 : outputsFormat_.push_back(ge::GetPrimaryFormat(format));
147 48 : outputsShape_.push_back(outputShape);
148 48 : outputsOriginShape_.push_back(outputOriginshape);
149 48 : aicpusd_info("PreProcessOutput op name[%s], output[%ld], value is[%lx], value type[%d]", opName_.c_str(), i, item.address(), item.addr_type());
150 48 : }
151 40 : return AICPU_SCHEDULE_OK;
152 : }
153 :
154 39 : StatusCode OpDumpTask::PreProcessInput(const aicpu::dump::Task &task,
155 : ::toolkit::dumpdata::DumpData &dumpData)
156 : {
157 39 : const auto &inputsFromMapInfo = task.input();
158 74 : for (int64_t i = 0; i < inputsFromMapInfo.size(); ++i) {
159 35 : const auto &item = inputsFromMapInfo.at(i);
160 35 : ::toolkit::dumpdata::OpInput * const opInput = dumpData.add_input();
161 35 : if (opInput == nullptr) {
162 0 : aicpusd_err("op name[%s], call protobuf function to add input elem failed", opName_.c_str());
163 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
164 : }
165 35 : opInput->set_data_type(static_cast<::toolkit::dumpdata::OutputDataType>(item.data_type()));
166 35 : const auto format = item.format();
167 35 : opInput->set_format(static_cast<::toolkit::dumpdata::OutputFormat>(ge::GetPrimaryFormat(format)));
168 35 : opInput->set_sub_format(ge::GetSubFormat(format));
169 35 : opInput->set_offset(static_cast<::toolkit::dumpdata::OutputDataType>(item.offset()));
170 :
171 35 : const int32_t addrType = item.addr_type();
172 35 : std::vector<uint64_t> inputshape;
173 35 : std::vector<uint64_t> inputOriginShape;
174 35 : if (addrType != aicpu::dump::NOTILING_ADDR) {
175 28 : const auto dims = item.shape().dim();
176 28 : ::toolkit::dumpdata::Shape * const inShape = opInput->mutable_shape();
177 56 : for (const auto dim : dims) {
178 28 : inShape->add_dim(dim);
179 28 : inputshape.push_back(dim);
180 : }
181 28 : const auto originalDims = item.origin_shape().dim();
182 28 : ::toolkit::dumpdata::Shape * const inOriginalShape = opInput->mutable_original_shape();
183 40 : for (const auto dim : originalDims) {
184 12 : inOriginalShape->add_dim(dim);
185 12 : inputOriginShape.push_back(dim);
186 : }
187 28 : opInput->set_size(item.size());
188 28 : inputTotalSize_ += item.size();
189 28 : }
190 35 : inputsBaseAddr_.push_back(item.address());
191 35 : inputsAddrType_.push_back(item.addr_type());
192 35 : inputsSize_.push_back(item.size());
193 35 : inputsOffset_.push_back(item.offset());
194 35 : inputsDataType_.push_back(item.data_type());
195 35 : inputsFormat_.push_back(ge::GetPrimaryFormat(format));
196 35 : inputsShape_.push_back(inputshape);
197 35 : inputsOriginShape_.push_back(inputOriginShape);
198 35 : aicpusd_info("PreProcessInput op name[%s], input[%ld], value is[%lx], value type[%d]", opName_.c_str(), i, item.address(), item.addr_type());
199 35 : }
200 39 : return AICPU_SCHEDULE_OK;
201 : }
202 :
203 38 : StatusCode OpDumpTask::PreProcessOpBuffer(const aicpu::dump::Task &task,
204 : ::toolkit::dumpdata::DumpData &dumpData)
205 : {
206 38 : const auto &opsBufferFromMapInfo = task.buffer();
207 51 : for (int64_t i = 0; i < opsBufferFromMapInfo.size(); ++i) {
208 13 : const auto &item = opsBufferFromMapInfo.at(i);
209 13 : ::toolkit::dumpdata::OpBuffer * const opBuffer = dumpData.add_buffer();
210 13 : if (opBuffer == nullptr) {
211 0 : aicpusd_err("op name[%s], call protobuf function to add op buffer elem failed", opName_.c_str());
212 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
213 : }
214 :
215 13 : opBuffer->set_buffer_type(static_cast<::toolkit::dumpdata::BufferType>(item.buffer_type()));
216 13 : opBuffer->set_size(item.size());
217 13 : opBufferTotalSize_ += item.size();
218 13 : opBufferAddr_.push_back(item.address());
219 : }
220 38 : return AICPU_SCHEDULE_OK;
221 : }
222 :
223 39 : StatusCode OpDumpTask::PreProcessWorkspace(const aicpu::dump::Task &task,
224 : ::toolkit::dumpdata::DumpData &dumpData)
225 : {
226 39 : const auto &opsWorkspaceFromMapInfo = task.space();
227 40 : for (int64_t i = 0; i < opsWorkspaceFromMapInfo.size(); ++i) {
228 1 : const auto &item = opsWorkspaceFromMapInfo.at(i);
229 1 : ::toolkit::dumpdata::Workspace * const opWorkspace = dumpData.add_space();
230 1 : if (opWorkspace == nullptr) {
231 0 : aicpusd_err("op name[%s], call protobuf function to add op Workspace elem failed", opName_.c_str());
232 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
233 : }
234 :
235 1 : opWorkspace->set_type(static_cast<::toolkit::dumpdata::Workspace::SpaceType>(item.type()));
236 1 : opWorkspace->set_size(item.size());
237 1 : opWorkspaceTotalSize_ += item.size();
238 1 : opWorkspaceAddr_.push_back(item.data_addr());
239 1 : opWorkspaceSize_.push_back(item.size());
240 : }
241 39 : return AICPU_SCHEDULE_OK;
242 : }
243 :
244 :
245 7 : StatusCode OpDumpTask::UpdatePreProcessFftsPlusInputAndOutput(const aicpu::dump::Context &item)
246 : {
247 7 : const auto &inputFromContext = item.input();
248 7 : uint32_t inputFromContextSize = static_cast<uint32_t>(inputFromContext.size());
249 7 : if (inputFromContextSize != static_cast<uint32_t>(baseDumpData_.input_size())) {
250 1 : aicpusd_err("inputFromContextSize[%u], baseDumpData_.input_size[%u]",
251 : inputFromContextSize, baseDumpData_.input_size());
252 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
253 : }
254 6 : inputTotalSize_ = 0;
255 14 : for (uint32_t j = 0U; j < inputFromContextSize; ++j) {
256 8 : const auto &itemInput = inputFromContext.at(j);
257 8 : uint64_t dataAddr = itemInput.address();
258 8 : uint64_t size = itemInput.size();
259 8 : baseDumpData_.mutable_input(j)->set_address(dataAddr);
260 8 : baseDumpData_.mutable_input(j)->set_size(size);
261 8 : inputsBaseAddr_[j] = dataAddr;
262 8 : inputsSize_[j] = size;
263 8 : inputTotalSize_ += size;
264 8 : aicpusd_info("size[%llu]", size);
265 : }
266 6 : const auto &outputFromContext = item.output();
267 6 : uint32_t outputFromContextSize = static_cast<uint32_t>(outputFromContext.size());
268 6 : if (outputFromContextSize != static_cast<uint32_t>(baseDumpData_.output_size())) {
269 1 : aicpusd_err("outputFromContextSize[%u], baseDumpData_.output_size[%u]",
270 : outputFromContextSize, baseDumpData_.output_size());
271 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
272 : }
273 5 : outputTotalSize_ = 0;
274 14 : for (uint32_t j = 0U; j < outputFromContextSize; ++j) {
275 9 : const auto &itemOutput = outputFromContext.at(j);
276 9 : uint64_t dataAddr = itemOutput.address();
277 9 : uint64_t size = itemOutput.size();
278 9 : baseDumpData_.mutable_output(j)->set_address(dataAddr);
279 9 : baseDumpData_.mutable_output(j)->set_size(size);
280 9 : outputsBaseAddr_[j] = dataAddr;
281 9 : outputSize_[j] = size;
282 9 : outputTotalSize_ += size;
283 9 : aicpusd_info("size[%llu]", size);
284 : }
285 5 : aicpusd_info("PreProcessFFTSPLUSInputAndOutput inputTotalSize[%llu], outputTotalSize[%llu]",
286 : inputTotalSize_, outputTotalSize_);
287 5 : return AICPU_SCHEDULE_OK;
288 : }
289 :
290 38 : StatusCode OpDumpTask::PreProcessOpMappingInfo(const aicpu::dump::Task &task,
291 : const std::string &basePath,
292 : const MappingInfoOptionalParam ¶m,
293 : const DumpStep &dumpStep,
294 : const DumpMode dumpMode,
295 : const bool skipAddressConversion)
296 : {
297 38 : aicpusd_info("Base path[%s], has model name[%d], model name[%s], has model id[%d], model id[%u].",
298 : basePath.c_str(), param.hasModelName, param.modelName.c_str(), param.hasModelId, param.modelId);
299 38 : const std::lock_guard<std::mutex> queLock(dumpMtx_);
300 38 : baseDumpPath_ = basePath;
301 38 : optionalParam_ = param;
302 38 : dumpStep_ = dumpStep;
303 38 : skipAddressConversion_ = skipAddressConversion;
304 : // single op no task id and stream id
305 38 : taskInfo_.taskId_ = task.task_id();
306 38 : taskInfo_.streamId_ = task.stream_id();
307 38 : taskInfo_.contextId_ = task.context_id();
308 38 : taskType_ = task.tasktype();
309 38 : endGraph_ = task.end_graph();
310 :
311 38 : ::toolkit::dumpdata::DumpData dumpData;
312 : // version 2.0
313 : dumpData.set_version("2.0");
314 :
315 38 : const auto &attrsFromMapInfo = task.attr();
316 42 : for (int64_t i = 0; i < attrsFromMapInfo.size(); ++i) {
317 4 : const auto &item = attrsFromMapInfo.at(i);
318 4 : ::toolkit::dumpdata::OpAttr * const OpAttr = dumpData.add_attr();
319 4 : if (OpAttr == nullptr) {
320 0 : aicpusd_err("op name[%s], call protobuf function to add attr elem failed", opName_.c_str());
321 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
322 : }
323 4 : OpAttr->set_name(item.name());
324 4 : OpAttr->set_value(item.value());
325 : }
326 38 : StatusCode ret = PreProcessInput(task, dumpData);
327 38 : if (ret != AICPU_SCHEDULE_OK) {
328 0 : return ret;
329 : }
330 38 : ret = PreProcessOutput(task, dumpData);
331 38 : if (ret != AICPU_SCHEDULE_OK) {
332 0 : return ret;
333 : }
334 38 : ret = PreProcessOpBuffer(task, dumpData);
335 38 : if (ret != AICPU_SCHEDULE_OK) {
336 0 : return ret;
337 : }
338 38 : ret = PreProcessWorkspace(task, dumpData);
339 38 : if (ret != AICPU_SCHEDULE_OK) {
340 0 : return ret;
341 : }
342 :
343 38 : dumpMode_ = dumpMode;
344 38 : opName_ = task.op().op_name();
345 38 : opType_ = task.op().op_type();
346 38 : dumpData.set_op_name(opName_);
347 38 : aicpusd_info("[stream id:%u, task id:%u, context id:%u] op name[%s], op type[%s]",
348 : taskInfo_.streamId_, taskInfo_.taskId_, taskInfo_.contextId_, opName_.c_str(), opType_.c_str());
349 38 : baseDumpData_ = std::move(dumpData);
350 38 : taskDumpNum_ = 0U;
351 38 : return AICPU_SCHEDULE_OK;
352 38 : }
353 :
354 47 : void OpDumpTask::GetInputDataAddr(uint64_t &dataAddr, const int32_t i)
355 : {
356 47 : const uint64_t baseAddr = inputsBaseAddr_.at(static_cast<size_t>(i));
357 47 : aicpusd_info("op name[%s], input[%d], base value[%lx]", opName_.c_str(), i, baseAddr);
358 47 : dataAddr = baseAddr;
359 47 : if (!skipAddressConversion_) {
360 42 : if (baseAddr == 0U) {
361 4 : aicpusd_info("op name[%s], input[%d] base addr is null", opName_.c_str(), i);
362 4 : return;
363 : }
364 38 : const int32_t addrType = inputsAddrType_.at(static_cast<size_t>(i));
365 38 : aicpusd_info("op name[%s], input[%d], Type[%u], data value[%lx]", opName_.c_str(), i, addrType, dataAddr);
366 : // baseAddr is a pointer point to data addr
367 38 : if (addrType != aicpu::dump::RAW_ADDR) {
368 29 : dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(baseAddr)));
369 29 : if (addrType == aicpu::dump::NOTILING_ADDR) {
370 11 : aicpusd_info("op name[%s], dump in notiling mode, input[%d]", opName_.c_str(), i);
371 11 : dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(dataAddr)));
372 : }
373 : }
374 : }
375 43 : aicpusd_info("op name[%s], input[%d], Type[%u], data value[%lx]", opName_.c_str(), i, inputsAddrType_.at(static_cast<size_t>(i)), dataAddr);
376 :
377 43 : return;
378 : }
379 38 : StatusCode OpDumpTask::ProcessInputDump(const ::toolkit::dumpdata::DumpData &dumpData,
380 : const std::string &path,
381 : IDE_SESSION &ideSession)
382 : {
383 38 : uint64_t dumpedSize = 0U;
384 79 : for (int64_t i = 0; i < dumpData.input_size(); ++i) {
385 43 : auto &input = dumpData.input(i);
386 43 : uint64_t len = input.size();
387 43 : if (len == 0U) {
388 3 : aicpusd_warn("op name[%s], input[%d] data size is zero", opName_.c_str(), i);
389 3 : continue;
390 : }
391 40 : uint64_t dataAddr = input.address();
392 40 : aicpusd_info("op name[%s], input[%d], size[%llu]", opName_.c_str(), i, len);
393 40 : if (dataAddr == 0U) {
394 8 : aicpusd_warn("op name[%s], input[%d] src is zero", opName_.c_str(), i);
395 8 : continue;
396 : }
397 32 : uint64_t innerOffset = 0U;
398 :
399 62 : while (innerOffset < len) {
400 32 : const uint64_t emptyBufferSize = buffSize_ - offset_;
401 32 : const uint64_t actSize = std::min(emptyBufferSize, len - innerOffset);
402 32 : const uint64_t srcAddr = dataAddr + innerOffset;
403 32 : aicpusd_info("op name[%s], begin to copy data from HBM to DDR for input[%d]," \
404 : " srcSize[%llu], innerOffset[%llu], offset[%llu], dstSize[%llu], dst value[%lx], src value[%lx]",
405 : opName_.c_str(), i, actSize, innerOffset, offset_, emptyBufferSize, buff_.get() + offset_, srcAddr);
406 32 : const errno_t eRet = memcpy_s(buff_.get() + offset_,
407 : emptyBufferSize,
408 32 : ValueToPtr(srcAddr),
409 : actSize);
410 32 : if (eRet != EOK) {
411 1 : aicpusd_err("op name[%s], input[%d] memcpy failed, dstSize[%llu], srcSize[%llu]",
412 : opName_.c_str(), i, emptyBufferSize, actSize);
413 2 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
414 : }
415 31 : aicpusd_info("op name[%s], end of copy data from HBM to DDR for input[%d], size[%llu]",
416 : opName_.c_str(), i, actSize);
417 31 : offset_ += actSize;
418 31 : innerOffset += actSize;
419 31 : dumpedSize += actSize;
420 81 : bool isLastSilce = (dumpedSize == inputTotalSize_) &&
421 19 : (outputTotalSize_ == 0U) &&
422 50 : (opBufferTotalSize_ == 0U) && (opWorkspaceTotalSize_ == 0U);
423 31 : if ((offset_ >= buffSize_) || isLastSilce) {
424 1 : const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
425 1 : if (ret != AICPU_SCHEDULE_OK) {
426 1 : aicpusd_err("op name[%s], dump input failed", opName_.c_str());
427 1 : return ret;
428 : }
429 0 : offset_ = 0U;
430 : }
431 : }
432 30 : aicpusd_info("op name[%s], process input[%d] data dump success.", opName_.c_str(), i);
433 : }
434 36 : return AICPU_SCHEDULE_OK;
435 : }
436 :
437 62 : void OpDumpTask::GetOutputDataAddr(uint64_t &dataAddr, const int32_t i)
438 : {
439 62 : const uint64_t baseAddr = outputsBaseAddr_.at(static_cast<size_t>(i));
440 62 : dataAddr = baseAddr;
441 62 : if (!skipAddressConversion_) {
442 58 : if (baseAddr == 0U) {
443 4 : aicpusd_info("op name[%s], output[%d] base addr is null.", opName_.c_str(), i);
444 4 : return;
445 : }
446 54 : const int32_t addrType = outputsAddrType_.at(static_cast<size_t>(i));
447 54 : aicpusd_info("op name[%s], output[%d], Type[%u]", opName_.c_str(), i, addrType);
448 : // baseAddr is a pointer point to data addr
449 54 : if (addrType != aicpu::dump::RAW_ADDR) {
450 41 : dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(baseAddr)));
451 41 : if (addrType == aicpu::dump::NOTILING_ADDR) {
452 11 : aicpusd_info("op name[%s], dump in notiling mode, output[%d]", opName_.c_str(), i);
453 11 : dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(dataAddr)));
454 : }
455 : }
456 : }
457 58 : aicpusd_info("op name[%s], output[%d], Type[%u]", opName_.c_str(), i, outputsAddrType_.at(static_cast<size_t>(i)));
458 58 : return;
459 : }
460 :
461 38 : StatusCode OpDumpTask::ProcessOutputDump(const ::toolkit::dumpdata::DumpData &dumpData,
462 : const std::string &path,
463 : IDE_SESSION &ideSession)
464 : {
465 38 : uint64_t dumpedSize = 0U;
466 93 : for (int64_t i = 0; i < dumpData.output_size(); ++i) {
467 58 : auto &output = dumpData.output(i);
468 58 : uint64_t len = output.size();
469 58 : if (len == 0U) {
470 2 : aicpusd_warn("op name[%s], output[%d] data size is zero", opName_.c_str(), i);
471 2 : continue;
472 : }
473 56 : uint64_t dataAddr = output.address();
474 56 : aicpusd_info("op name[%s], output[%d] size[%llu].", opName_.c_str(), i, len);
475 56 : if (dataAddr == 0U) {
476 8 : aicpusd_warn("op name[%s], output[%d] addr is null", opName_.c_str(), i);
477 8 : continue;
478 : }
479 48 : uint64_t innerOffset = 0U;
480 93 : while (innerOffset < len) {
481 48 : const uint64_t emptyBufferSize = buffSize_ - offset_;
482 48 : const uint64_t actSize = std::min(emptyBufferSize, len - innerOffset);
483 48 : const uint64_t srcAddr = dataAddr + innerOffset;
484 48 : aicpusd_info("op name[%s], begin to copy data from HBM to DDR for output[%d]," \
485 : " srcSize[%llu], innerOffset[%llu], offset[%llu], dstSize[%llu]",
486 : opName_.c_str(), i, actSize, innerOffset, offset_, emptyBufferSize);
487 48 : const errno_t eRet = memcpy_s(buff_.get() + offset_,
488 : emptyBufferSize,
489 48 : PtrToPtr<const void, const char_t>(ValueToPtr(srcAddr)),
490 : actSize);
491 48 : if (eRet != EOK) {
492 2 : aicpusd_err("op name[%s], output[%d] memcpy failed, dstSize[%llu], srcSize[%llu]",
493 : opName_.c_str(), i, emptyBufferSize, actSize);
494 3 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
495 : }
496 46 : aicpusd_info("op name[%s], end of copy data from HBM to DDR for output[%d],"
497 : " srcSize[%llu], dstSize[%llu]", opName_.c_str(), i, actSize, emptyBufferSize);
498 46 : offset_ += actSize;
499 46 : innerOffset += actSize;
500 46 : dumpedSize += actSize;
501 111 : bool isLastSilce = (dumpedSize == outputTotalSize_) &&
502 46 : (opBufferTotalSize_ == 0U) && (opWorkspaceTotalSize_ == 0U);
503 46 : if ((offset_ >= buffSize_) || isLastSilce) {
504 10 : const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
505 10 : if (ret != AICPU_SCHEDULE_OK) {
506 1 : aicpusd_err("op name[%s], dump output failed", opName_.c_str());
507 1 : return ret;
508 : }
509 9 : offset_ = 0U;
510 : }
511 : }
512 :
513 45 : aicpusd_info("op name[%s], process output[%d] data dump success.", opName_.c_str(), i);
514 : }
515 35 : return AICPU_SCHEDULE_OK;
516 : }
517 :
518 31 : StatusCode OpDumpTask::ProcessOpBufferDump(const ::toolkit::dumpdata::DumpData &dumpData,
519 : const std::string &path,
520 : IDE_SESSION &ideSession)
521 : {
522 31 : uint64_t dumpedSize = 0U;
523 48 : for (int64_t i = 0; i < dumpData.buffer_size(); ++i) {
524 17 : auto &buffer = dumpData.buffer(i);
525 17 : if (buffer.size() == 0U) {
526 0 : aicpusd_warn("op name[%s], op buffer[%d] data size is zero", opName_.c_str(), i);
527 0 : continue;
528 : }
529 17 : const size_t opBufferAddrIndex = static_cast<size_t>(i);
530 17 : if (opBufferAddr_[opBufferAddrIndex] == 0U) {
531 0 : aicpusd_warn("op name[%s], op buffer[%d] addr is null", opName_.c_str(), i);
532 0 : continue;
533 : }
534 17 : uint64_t innerOffset = 0U;
535 34 : while (innerOffset < buffer.size()) {
536 17 : const uint64_t emptyBufferSize = buffSize_ - offset_;
537 17 : const uint64_t actSize = std::min(emptyBufferSize, buffer.size() - innerOffset);
538 17 : const uint64_t srcAddr = opBufferAddr_[opBufferAddrIndex] + innerOffset;
539 17 : aicpusd_info("op name[%s], begin to copy data from HBM to DDR for op buffer[%d],"
540 : " srcSize[%llu], dstSize[%llu]", opName_.c_str(), i, actSize, emptyBufferSize);
541 17 : const errno_t eRet = memcpy_s(buff_.get() + offset_,
542 : emptyBufferSize,
543 17 : ValueToPtr(srcAddr),
544 : actSize);
545 17 : if (eRet != EOK) {
546 0 : aicpusd_err("op name[%s], op buffer[%d] memcpy failed, srcSize[%llu], dstSize[%llu]",
547 : opName_.c_str(), i, actSize, emptyBufferSize);
548 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
549 : }
550 17 : aicpusd_info("op name[%s], end of copy data from HBM to DDR for op buffer[%d],"
551 : " srcSize[%llu], dstSize[%llu]", opName_.c_str(), i, actSize, emptyBufferSize);
552 17 : offset_ += actSize;
553 17 : innerOffset += actSize;
554 17 : dumpedSize += actSize;
555 17 : const bool isLastSilce = (dumpedSize == opBufferTotalSize_) && (opWorkspaceTotalSize_ == 0U);
556 17 : if ((offset_ >= buffSize_) || isLastSilce) {
557 17 : const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
558 17 : if (ret != AICPU_SCHEDULE_OK) {
559 0 : aicpusd_err("op name[%s], dump op buffer failed", opName_.c_str());
560 0 : return ret;
561 : }
562 17 : offset_ = 0U;
563 : }
564 : }
565 17 : aicpusd_info("op name[%s], process op buffer[%d] data success.", opName_.c_str(), i);
566 : }
567 31 : return AICPU_SCHEDULE_OK;
568 : }
569 :
570 34 : StatusCode OpDumpTask::ProcessOpWorkspaceDump(const ::toolkit::dumpdata::DumpData &dumpData,
571 : const std::string &path,
572 : IDE_SESSION &ideSession)
573 : {
574 34 : uint64_t dumpedSize = 0U;
575 37 : for (int64_t i = 0; i < dumpData.space_size(); ++i) {
576 3 : auto &space = dumpData.space(i);
577 3 : if (space.size() == 0U) {
578 1 : aicpusd_err("op name[%s], op space[%d] data size is zero", opName_.c_str(), i);
579 1 : continue;
580 : }
581 2 : const size_t opWorkspaceAddrIndex = static_cast<size_t>(i);
582 2 : if (opWorkspaceAddr_[opWorkspaceAddrIndex] == 0U) {
583 1 : aicpusd_err("op name[%s], op space[%d] workspace is null", opName_.c_str(), i);
584 1 : continue;
585 : }
586 1 : uint64_t innerOffset = 0U;
587 2 : while (innerOffset < space.size()) {
588 1 : const uint64_t emptyWorkspaceSize = buffSize_ - offset_;
589 1 : const uint64_t actSize = std::min(emptyWorkspaceSize, space.size() - innerOffset);
590 1 : const uint64_t srcAddr = opWorkspaceAddr_[opWorkspaceAddrIndex] + innerOffset;
591 1 : aicpusd_info("op name[%s], begin to copy data from HBM to DDR for spaceIndex[%d]," \
592 : " srcSize[%llu], innerOffset[%llu], offset[%llu], dstSize[%llu]",
593 : opName_.c_str(), i, actSize, innerOffset, offset_, emptyWorkspaceSize);
594 1 : const errno_t eRet = memcpy_s(buff_.get() + offset_,
595 : emptyWorkspaceSize,
596 1 : PtrToPtr<void, char_t>(ValueToPtr(srcAddr)),
597 : actSize);
598 1 : if (eRet != EOK) {
599 0 : aicpusd_err("op name[%s], op spaceIndex[%d] memcpy failed, dstSize[%llu], srcSize[%llu]",
600 : opName_.c_str(), i, emptyWorkspaceSize, actSize);
601 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
602 : }
603 1 : aicpusd_info("op name[%s], op spaceIndex[%d] end copy, dstSize[%llu], srcSize[%llu]",
604 : opName_.c_str(), i, emptyWorkspaceSize, actSize);
605 1 : offset_ += actSize;
606 1 : innerOffset += actSize;
607 1 : dumpedSize += actSize;
608 1 : const bool isLastSilce = (dumpedSize == opWorkspaceTotalSize_);
609 1 : if ((offset_ >= buffSize_) || isLastSilce) {
610 1 : const StatusCode ret = Dump(path, buff_.get(), offset_, ideSession, isLastSilce);
611 1 : if (ret != AICPU_SCHEDULE_OK) {
612 0 : aicpusd_err("op name[%s], dump op space failed", opName_.c_str());
613 0 : return ret;
614 : }
615 1 : offset_ = 0U;
616 : }
617 : }
618 1 : aicpusd_info("op name[%s], process op space[%d] data success.", opName_.c_str(), i);
619 : }
620 34 : return AICPU_SCHEDULE_OK;
621 : }
622 :
623 51 : StatusCode OpDumpTask::Dump(const std::string &path,
624 : char_t * const data,
625 : const uint64_t len,
626 : IDE_SESSION &ideSession,
627 : const bool isLastSlice) const
628 : {
629 51 : if (ideSession != nullptr) {
630 50 : IdeDumpChunk ideDumpChunk = {};
631 50 : ideDumpChunk.fileName = const_cast<char_t *>(path.c_str());
632 50 : ideDumpChunk.dataBuf = reinterpret_cast<uint8_t *>(data);
633 50 : ideDumpChunk.bufLen = static_cast<uint32_t>(len);
634 50 : ideDumpChunk.isLastChunk = isLastSlice ? 1U : 0U;
635 50 : ideDumpChunk.offset = -1; // append
636 50 : ideDumpChunk.flag = IDE_DUMP_NONE_FLAG;
637 50 : auto startTime = std::chrono::steady_clock::now();
638 50 : aicpusd_info("op name[%s], start to call IdeDumpData, size[%u], isLastChunk[%u]",
639 : opName_.c_str(), len, ideDumpChunk.isLastChunk);
640 50 : IdeErrorT ideState = IdeDumpData(ideSession, &ideDumpChunk);
641 50 : if (ideState != IDE_DAEMON_NONE_ERROR) {
642 8 : aicpusd_run_info("Dump data not success, ret[%d].", ideState);
643 8 : ideSession = DumpSessionManager::GetInstance().ReacquireSession(hostPid_, deviceId_);
644 8 : if (ideSession == nullptr) {
645 2 : aicpusd_err("op name[%s], reacquire ide session failed.", opName_.c_str());
646 5 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
647 : }
648 6 : ideState = IdeDumpData(ideSession, &ideDumpChunk);
649 : }
650 48 : if (ideState != IDE_DAEMON_NONE_ERROR) {
651 3 : aicpusd_err("op name[%s], call IdeDumpData failed, size[%u], ret[%d]", opName_.c_str(), len, ideState);
652 3 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
653 : }
654 45 : auto endTime = std::chrono::steady_clock::now();
655 45 : const double drUs = std::chrono::duration<double, std::micro>(endTime - startTime).count();
656 45 : const double transmissionRate = ((len == 0LU) ? 0.0 : (drUs / static_cast<double>(len)));
657 45 : aicpusd_info("op name[%s], end of call IdeDumpData, size[%lu], cost time is [%.2lf]us,"
658 : " transmission rate is [%.2lf]byte/us", opName_.c_str(), len, drUs, transmissionRate);
659 : UNUSED(transmissionRate);
660 : } else {
661 1 : aicpusd_err("op name[%s], ide session is null, size[%u].", opName_.c_str(), len);
662 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
663 : }
664 45 : return AICPU_SCHEDULE_OK;
665 : }
666 :
667 44 : StatusCode OpDumpTask::ProcessngNoTiliInput()
668 : {
669 44 : if (skipAddressConversion_) {
670 4 : return AICPU_SCHEDULE_OK;
671 : }
672 :
673 80 : for (int64_t inputDim = 0; inputDim < baseDumpData_.input_size(); ++inputDim) {
674 40 : auto input = baseDumpData_.mutable_input(inputDim);
675 40 : const uint64_t baseAddr = inputsBaseAddr_.at(static_cast<size_t>(inputDim));
676 40 : if (baseAddr == 0U) {
677 2 : aicpusd_info("op name[%s], input[%d] base addr is null", opName_.c_str(), inputDim);
678 2 : continue;
679 : }
680 38 : aicpusd_info("op name[%s], input[%d]", opName_.c_str(), inputDim);
681 38 : const int32_t addrType = inputsAddrType_.at(static_cast<size_t>(inputDim));
682 38 : if (addrType == aicpu::dump::NOTILING_ADDR) {
683 : // baseAddr is a pointer point to data addr
684 16 : const uint64_t dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(baseAddr)));
685 16 : aicpusd_info("op name[%s], dump in notiling mode, input[%d]", opName_.c_str(), inputDim);
686 16 : const RuntimeTensorDesc *tensorDesc = PtrToPtr<void, RuntimeTensorDesc>(ValueToPtr(dataAddr));
687 16 : uint64_t dataNum = 1UL;
688 16 : const size_t dimSize = static_cast<size_t>(tensorDesc->shape[0]);
689 16 : if (dimSize > static_cast<size_t>(MAX_DIM_SIZE)) {
690 0 : aicpusd_err("op name[%s], tensor desc shape dim size[%zu] must be < %lld",
691 : opName_.c_str(), dimSize, MAX_DIM_SIZE);
692 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
693 : }
694 16 : std::vector<uint64_t> inputshape;
695 16 : std::vector<uint64_t> inputOriginShape;
696 16 : auto inputShape = input->mutable_shape();
697 48 : for (size_t i = 0UL; i < dimSize; ++i) {
698 32 : inputShape->add_dim(static_cast<uint64_t>(tensorDesc->shape[i + 1UL]));
699 32 : dataNum *= static_cast<uint64_t>(tensorDesc->shape[i + 1UL]);
700 32 : inputshape.push_back(static_cast<uint64_t>(tensorDesc->shape[i + 1UL]));
701 32 : aicpusd_info("op name[%s], dump input shape[%zu] value[%lld]",
702 : opName_.c_str(), i, tensorDesc->shape[i + 1UL]);
703 : }
704 16 : auto inputOriginalShape = input->mutable_original_shape();
705 16 : const size_t originalDimSize = static_cast<size_t>(tensorDesc->originalShape[0]);
706 48 : for (size_t i = 0UL; i < originalDimSize; ++i) {
707 32 : inputOriginalShape->add_dim(static_cast<uint64_t>(tensorDesc->originalShape[i + 1UL]));
708 32 : inputOriginShape.push_back(static_cast<uint64_t>(tensorDesc->originalShape[i + 1UL]));
709 : }
710 16 : const int32_t dataType = ge::GetSizeByDataType(static_cast<ge::DataType>(tensorDesc->dtype));
711 16 : if (dataType < 0) {
712 0 : aicpusd_err("op name[%s], tensor data dataType[%d] must be > 0", opName_.c_str(), dataType);
713 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
714 : }
715 16 : if (static_cast<uint64_t>(dataType) > (UINT64_MAX / dataNum)) {
716 0 : aicpusd_err("op name[%s], tensor data dataType[%d] * dataNum[%u] is overflow",
717 : opName_.c_str(), dataType, dataNum);
718 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
719 : }
720 16 : const uint64_t size = static_cast<uint64_t>(dataType) * dataNum;
721 16 : input->set_size(size);
722 16 : inputTotalSize_ += size;
723 16 : inputsShape_.push_back(inputshape);
724 16 : inputsOriginShape_.push_back(inputOriginShape);
725 16 : aicpusd_info("op name[%s], dump input size[%llu], type[%lld]", opName_.c_str(), size, tensorDesc->dtype);
726 16 : }
727 : }
728 40 : return AICPU_SCHEDULE_OK;
729 : }
730 :
731 44 : StatusCode OpDumpTask::ProcessngNoTiliOutput()
732 : {
733 44 : if (skipAddressConversion_) {
734 4 : return AICPU_SCHEDULE_OK;
735 : }
736 102 : for (int64_t outputDim = 0; outputDim < baseDumpData_.output_size(); ++outputDim) {
737 61 : auto output = baseDumpData_.mutable_output(outputDim);
738 62 : const uint64_t baseAddr = outputsBaseAddr_.at(static_cast<size_t>(outputDim));
739 62 : if (baseAddr == 0U) {
740 3 : aicpusd_info("op name[%s], output[%d] base addr is null.", opName_.c_str(), outputDim);
741 3 : continue;
742 : }
743 59 : aicpusd_info("op name[%s], output[%d] base is %llu.", opName_.c_str(), outputDim, baseAddr);
744 59 : const int32_t addrType = outputsAddrType_.at(static_cast<size_t>(outputDim));
745 59 : if (addrType == aicpu::dump::NOTILING_ADDR) {
746 : // baseAddr is a pointer point to data addr
747 16 : const uint64_t dataAddr = *(PtrToPtr<void, uint64_t>(ValueToPtr(baseAddr)));
748 16 : aicpusd_info("op name[%s], dump in notiling mode, output[%d]", opName_.c_str(), outputDim);
749 16 : const RuntimeTensorDesc *tensorDesc = PtrToPtr<void, RuntimeTensorDesc>(ValueToPtr(dataAddr));
750 16 : uint64_t dataNum = 1UL;
751 16 : const size_t dimSize = static_cast<size_t>(tensorDesc->shape[0]);
752 16 : if (dimSize > static_cast<size_t>(MAX_DIM_SIZE)) {
753 0 : aicpusd_err("op name[%s], tensor desc shape dim size[%zu] must be < %lld",
754 : opName_.c_str(), dimSize, MAX_DIM_SIZE);
755 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
756 : }
757 16 : auto outShape = output->mutable_shape();
758 16 : outShape->Clear();
759 16 : std::vector<uint64_t> outputShape;
760 16 : std::vector<uint64_t> outputOriginShape;
761 48 : for (size_t i = 0UL; i < dimSize; ++i) {
762 32 : outShape->add_dim(static_cast<uint64_t>(tensorDesc->shape[i + 1UL]));
763 32 : dataNum *= static_cast<uint64_t>(tensorDesc->shape[i + 1UL]);
764 32 : outputShape.push_back(static_cast<uint64_t>(tensorDesc->shape[i + 1UL]));
765 32 : aicpusd_info("op name[%s], dump output shape[%zu] value[%lld]",
766 : opName_.c_str(), i, tensorDesc->shape[i + 1UL]);
767 : }
768 16 : auto outOriginalShape = output->mutable_original_shape();
769 16 : outOriginalShape->Clear();
770 16 : const size_t originalDimSize = static_cast<size_t>(tensorDesc->originalShape[0]);
771 48 : for (size_t i = 0UL; i < originalDimSize; ++i) {
772 32 : outOriginalShape->add_dim(static_cast<uint64_t>(tensorDesc->originalShape[i + 1UL]));
773 32 : outputOriginShape.push_back(static_cast<uint64_t>(tensorDesc->originalShape[i + 1UL]));
774 : }
775 16 : const int32_t dataType = ge::GetSizeByDataType(static_cast<ge::DataType>(tensorDesc->dtype));
776 16 : if (dataType < 0) {
777 0 : aicpusd_err("op name[%s], tensor data type[%d] must be > 0", opName_.c_str(), dataType);
778 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
779 : }
780 16 : if (static_cast<uint64_t>(dataType) > (UINT64_MAX / dataNum)) {
781 0 : aicpusd_err("op name[%s], tensor data dataType[%d] * dataNum[%lu] is overflow",
782 : opName_.c_str(), dataType, dataNum);
783 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
784 : }
785 16 : const auto size = static_cast<uint64_t>(dataType) * dataNum;
786 16 : output->set_size(size);
787 16 : outputTotalSize_ += size;
788 16 : outputsShape_.push_back(outputShape);
789 16 : outputsOriginShape_.push_back(outputOriginShape);
790 16 : aicpusd_info("op name[%s], dump output size[%llu], type[%lld]", opName_.c_str(), size, tensorDesc->dtype);
791 16 : }
792 : }
793 40 : return AICPU_SCHEDULE_OK;
794 : }
795 :
796 1 : StatusCode OpDumpTask::DumpOpInfo(const uint32_t streamId, const uint32_t taskId)
797 : {
798 1 : TaskInfoExt dumpTaskInfo;
799 1 : dumpTaskInfo.streamId_ = INVALID_VAL;
800 1 : dumpTaskInfo.taskId_ = INVALID_VAL;
801 1 : dumpTaskInfo.contextId_ = INVALID_VAL;
802 1 : dumpTaskInfo.threadId_ = INVALID_VAL;
803 1 : DumpFileName dumpFileName(streamId, taskId);
804 2 : return DumpOpInfo(dumpTaskInfo, dumpFileName);
805 : }
806 :
807 33 : StatusCode OpDumpTask::ProcessDumpOpInfo(const TaskInfoExt &dumpTaskInfo, const std::string &dumpFilePath)
808 : {
809 33 : aicpusd_info("Begin to process op dump task. dumpMode=%d, threadId=%u", static_cast<int32_t>(dumpMode_), dumpTaskInfo.threadId_);
810 :
811 33 : auto dumpRet = AICPU_SCHEDULE_OK;
812 33 : switch (dumpMode_) {
813 30 : case DumpMode::TENSOR_DUMP_DATA:
814 30 : dumpRet = ProcessDumpTensor(dumpFilePath);
815 30 : break;
816 2 : case DumpMode::STATS_DUMP_DATA:
817 2 : dumpRet = ProcessDumpStatistic(dumpTaskInfo, dumpFilePath);
818 2 : break;
819 1 : default:
820 1 : aicpusd_err("Fail to dump for dump mode is unknown, DumpMode=%d", static_cast<int32_t>(dumpMode_));
821 1 : dumpRet = AICPU_SCHEDULE_ERROR_DUMP_FAILED;
822 1 : break;
823 : }
824 :
825 33 : if (dumpRet != AICPU_SCHEDULE_OK) {
826 1 : aicpusd_err("Dump failed. ret=%d, dumpMode=%d, threadId=%u, dumpFilePath=%s",
827 : static_cast<int32_t>(dumpRet), static_cast<int32_t>(dumpMode_), dumpTaskInfo.threadId_, dumpFilePath.c_str());
828 : }
829 :
830 33 : return dumpRet;
831 : }
832 :
833 44 : StatusCode OpDumpTask::DumpOpInfo(const TaskInfoExt &dumpTaskInfo, const DumpFileName &dumpFileName)
834 : {
835 44 : const std::lock_guard<std::mutex> queLock(dumpMtx_);
836 45 : uint64_t dumpNumber = 0U;
837 45 : if (GetDumpNumber(dumpNumber) != AICPU_SCHEDULE_OK) {
838 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
839 : }
840 :
841 44 : if (ProcessngNoTiliInput() != AICPU_SCHEDULE_OK) {
842 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
843 : }
844 :
845 44 : if (ProcessngNoTiliOutput() != AICPU_SCHEDULE_OK) {
846 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
847 : }
848 :
849 44 : if (!NeedDump(dumpNumber)) {
850 13 : return AICPU_SCHEDULE_OK;
851 : }
852 : // if need dump, set MODEL_TIMEOUT to false
853 31 : AicpuMonitor::GetInstance().DisableModelTimeout();
854 :
855 31 : const uint64_t nowTime = GetCurrentTime();
856 30 : baseDumpData_.set_dump_time(nowTime);
857 30 : UpdateDumpData();
858 :
859 30 : if ((baseDumpData_.ByteSizeLong() > static_cast<uint64_t>(INT_MAX)) || (baseDumpData_.ByteSizeLong() == 0U)) {
860 0 : aicpusd_err("op name[%s], dump data size[%zuB] should be in [1B, 2GB)].",
861 : opName_.c_str(), baseDumpData_.ByteSizeLong());
862 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
863 : }
864 30 : aicpusd_info("op name[%s], proto buffer total bytes[%llu]", opName_.c_str(), baseDumpData_.ByteSizeLong());
865 :
866 : // dump file path name
867 30 : const std::string dumpFilePath = DumpPath(nowTime, dumpNumber, dumpFileName);
868 :
869 31 : return ProcessDumpOpInfo(dumpTaskInfo, dumpFilePath);
870 45 : }
871 :
872 42 : void OpDumpTask::UpdateDumpData()
873 : {
874 83 : for (int64_t i = 0; i < baseDumpData_.input_size(); ++i) {
875 41 : uint64_t dataAddr = 0U;
876 41 : GetInputDataAddr(dataAddr, i);
877 41 : baseDumpData_.mutable_input(i)->set_address(dataAddr);
878 : }
879 98 : for (int64_t i = 0; i < baseDumpData_.output_size(); ++i) {
880 56 : uint64_t dataAddr = 0U;
881 56 : GetOutputDataAddr(dataAddr, i);
882 56 : baseDumpData_.mutable_output(i)->set_address(dataAddr);
883 : }
884 42 : }
885 :
886 31 : StatusCode OpDumpTask::ProcessDumpTensor(const std::string &dumpFilePath)
887 : {
888 31 : buffSize_ = baseDumpData_.ByteSizeLong() + sizeof(uint64_t) +
889 30 : inputTotalSize_ + outputTotalSize_ + opBufferTotalSize_ + opWorkspaceTotalSize_;
890 :
891 30 : buffSize_ = std::min(buffSize_, DUMP_SLICE_SIZE);
892 30 : buffSize_ = std::max(buffSize_, baseDumpData_.ByteSizeLong() + sizeof(uint64_t));
893 30 : buff_.reset(new (std::nothrow) char_t[buffSize_]);
894 31 : if (buff_ == nullptr) {
895 0 : aicpusd_err("op name[%s], malloc buffer for data dump failed, size[%llu]", opName_.c_str(), buffSize_);
896 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
897 : }
898 : // for memory statistic
899 31 : aicpusd_memory_log("op name[%s], MallocMemory, func=new, size=%llu, purpose=data dump buffer",
900 : opName_.c_str(), buffSize_);
901 31 : uint64_t * const sizePtr = PtrToPtr<char_t, uint64_t>(buff_.get());
902 31 : *sizePtr = baseDumpData_.ByteSizeLong();
903 31 : offset_ = sizeof(uint64_t);
904 30 : if (!baseDumpData_.SerializeToArray(buff_.get() + sizeof(uint64_t),
905 31 : static_cast<int32_t>(baseDumpData_.ByteSizeLong()))) {
906 0 : aicpusd_err("op name[%s], serialize dump data to string failed, data size[%zuB].",
907 : opName_.c_str(), baseDumpData_.ByteSizeLong());
908 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
909 : }
910 31 : offset_ += baseDumpData_.ByteSizeLong();
911 :
912 31 : return DoDumpTensor(dumpFilePath);
913 : }
914 :
915 32 : StatusCode OpDumpTask::DoDumpTensor(const std::string &dumpFilePath)
916 : {
917 : // the port is not used in ide module, just for privateInfo format check
918 32 : IDE_SESSION ideSession = DumpSessionManager::GetInstance().GetSession(hostPid_, deviceId_);
919 32 : if (ideSession == nullptr) {
920 1 : aicpusd_err("op name[%s], call IdeDumpStart failed, path[%s].", opName_.c_str(), dumpFilePath.c_str());
921 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
922 : }
923 31 : StatusCode ret = AICPU_SCHEDULE_OK;
924 31 : if (offset_ == buffSize_) {
925 0 : ret = Dump(dumpFilePath, buff_.get(), buffSize_, ideSession, false);
926 0 : if (ret != AICPU_SCHEDULE_OK) {
927 0 : aicpusd_err("op name[%s], dump proto failed, path[%s].", opName_.c_str(), dumpFilePath.c_str());
928 0 : return ret;
929 : }
930 0 : offset_ = 0U;
931 : }
932 31 : ret = ProcessInputDump(baseDumpData_, dumpFilePath, ideSession);
933 31 : if (ret != AICPU_SCHEDULE_OK) {
934 0 : return ret;
935 : }
936 31 : ret = ProcessOutputDump(baseDumpData_, dumpFilePath, ideSession);
937 31 : if (ret != AICPU_SCHEDULE_OK) {
938 0 : return ret;
939 : }
940 31 : ret = ProcessOpBufferDump(baseDumpData_, dumpFilePath, ideSession);
941 31 : if (ret != AICPU_SCHEDULE_OK) {
942 0 : return ret;
943 : }
944 31 : ret = ProcessOpWorkspaceDump(baseDumpData_, dumpFilePath, ideSession);
945 31 : if (ret != AICPU_SCHEDULE_OK) {
946 0 : return ret;
947 : }
948 : // in case of nothting has been dumped, we should dump dump_data's head
949 31 : if (offset_ != 0U) {
950 5 : const StatusCode ret = Dump(dumpFilePath, buff_.get(), offset_, ideSession, true);
951 5 : if (ret != AICPU_SCHEDULE_OK) {
952 0 : aicpusd_err("op name[%s], dump output failed", opName_.c_str());
953 0 : return ret;
954 : }
955 5 : offset_ = 0U;
956 : }
957 : // release buffer
958 31 : buff_.reset(nullptr);
959 :
960 31 : uint64_t fileSize = baseDumpData_.ByteSizeLong() + sizeof(uint64_t) +
961 31 : inputTotalSize_ + outputTotalSize_ + opBufferTotalSize_ + opWorkspaceTotalSize_;
962 31 : aicpusd_info("op name[%s], dump data success, path[%s], data size[%llu]",
963 : opName_.c_str(), dumpFilePath.c_str(), fileSize);
964 : UNUSED(fileSize);
965 31 : return AICPU_SCHEDULE_OK;
966 : }
967 :
968 3 : std::string OpDumpTask::GetDataFormatStr(::toolkit::dumpdata::OutputFormat dataFormat) const
969 : {
970 : static const std::map<::toolkit::dumpdata::OutputFormat, std::string> dataFormatMap = {
971 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NCHW, "NCHW"},
972 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NHWC, "NHWC"},
973 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_ND, "ND"},
974 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NC1HWC0, "NC1HWC0"},
975 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_Z, "FRACTAL_Z"},
976 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NC1C0HWPAD, "NC1C0HWPAD"},
977 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NHWC1C0, "NHWC1C0"},
978 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FSR_NCHW, "FSR_NCHW"},
979 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_DECONV, "FRACTAL_DECONV"},
980 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_C1HWNC0, "C1HWNC0"},
981 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_DECONV_TRANSPOSE, "FRACTAL_DECONV_TRANSPOSE"},
982 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_DECONV_SP_STRIDE_TRANS, "FRACTAL_DECONV_SP_STRIDE_TRANS"},
983 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NC1HWC0_C04, "NC1HWC0_C04"},
984 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_Z_C04, "FRACTAL_Z_C04"},
985 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_CHWN, "CHWN"},
986 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_DECONV_SP_STRIDE8_TRANS, "FRACTAL_DECONV_SP_STRIDE8_TRANS"},
987 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_HWCN, "HWCN"},
988 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NC1KHKWHWC0, "NC1KHKWHWC0"},
989 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_BN_WEIGHT, "BN_WEIGHT"},
990 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FILTER_HWCK, "FILTER_HWCK"},
991 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_HASHTABLE_LOOKUP_LOOKUPS, "HASHTABLE_LOOKUP_LOOKUPS"},
992 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_HASHTABLE_LOOKUP_KEYS, "HASHTABLE_LOOKUP_KEYS"},
993 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_HASHTABLE_LOOKUP_VALUE, "HASHTABLE_LOOKUP_VALUE"},
994 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_HASHTABLE_LOOKUP_OUTPUT, "HASHTABLE_LOOKUP_OUTPUT"},
995 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_HASHTABLE_LOOKUP_HITS, "HASHTABLE_LOOKUP_HITS"},
996 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_C1HWNCoC0, "C1HWNCoC0"},
997 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_MD, "MD"},
998 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NDHWC, "NDHWC"},
999 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_ZZ, "FRACTAL_ZZ"},
1000 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_NZ, "FRACTAL_NZ"},
1001 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NCDHW, "NCDHW"},
1002 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_DHWCN, "DHWCN"},
1003 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NDC1HWC0, "NDC1HWC0"},
1004 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_Z_3D, "FRACTAL_Z_3D"},
1005 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_CN, "CN"},
1006 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_NC, "NC"},
1007 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_DHWNC, "DHWNC"},
1008 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_Z_3D_TRANSPOSE, "FRACTAL_Z_3D_TRANSPOSE"},
1009 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_ZN_LSTM, "FRACTAL_ZN_LSTM"},
1010 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_FRACTAL_Z_G, "FRACTAL_Z_G"},
1011 0 : {::toolkit::dumpdata::OutputFormat::FORMAT_RESERVED, "RESERVED"}
1012 46 : };
1013 :
1014 3 : const auto iter = dataFormatMap.find(dataFormat);
1015 3 : if (iter == dataFormatMap.end()) {
1016 2 : return "-";
1017 : }
1018 :
1019 2 : return iter->second;
1020 1 : }
1021 :
1022 4 : std::string OpDumpTask::GetDataTypeStr(::toolkit::dumpdata::OutputDataType dataType) const
1023 : {
1024 : static const std::map<::toolkit::dumpdata::OutputDataType, std::string> dataTypeMap = {
1025 0 : {::toolkit::dumpdata::OutputDataType::DT_UNDEFINED, "DT_UNDEFINED"},
1026 0 : {::toolkit::dumpdata::OutputDataType::DT_FLOAT, "DT_FLOAT"},
1027 0 : {::toolkit::dumpdata::OutputDataType::DT_FLOAT16, "DT_FLOAT16"},
1028 0 : {::toolkit::dumpdata::OutputDataType::DT_INT8, "DT_INT8"},
1029 0 : {::toolkit::dumpdata::OutputDataType::DT_UINT8, "DT_UINT8"},
1030 0 : {::toolkit::dumpdata::OutputDataType::DT_INT16, "DT_INT16"},
1031 0 : {::toolkit::dumpdata::OutputDataType::DT_UINT16, "DT_UINT16"},
1032 0 : {::toolkit::dumpdata::OutputDataType::DT_INT32, "DT_INT32"},
1033 0 : {::toolkit::dumpdata::OutputDataType::DT_INT64, "DT_INT64"},
1034 0 : {::toolkit::dumpdata::OutputDataType::DT_UINT32, "DT_UINT32"},
1035 0 : {::toolkit::dumpdata::OutputDataType::DT_UINT64, "DT_UINT64"},
1036 0 : {::toolkit::dumpdata::OutputDataType::DT_BOOL, "DT_BOOL"},
1037 0 : {::toolkit::dumpdata::OutputDataType::DT_DOUBLE, "DT_DOUBLE"},
1038 0 : {::toolkit::dumpdata::OutputDataType::DT_STRING, "DT_STRING"},
1039 0 : {::toolkit::dumpdata::OutputDataType::DT_DUAL_SUB_INT8, "DT_DUAL_SUB_INT8"},
1040 0 : {::toolkit::dumpdata::OutputDataType::DT_DUAL_SUB_UINT8, "DT_DUAL_SUB_UINT8"},
1041 0 : {::toolkit::dumpdata::OutputDataType::DT_COMPLEX64, "DT_COMPLEX64"},
1042 0 : {::toolkit::dumpdata::OutputDataType::DT_COMPLEX128, "DT_COMPLEX128"},
1043 0 : {::toolkit::dumpdata::OutputDataType::DT_QINT8, "DT_QINT8"},
1044 0 : {::toolkit::dumpdata::OutputDataType::DT_QINT16, "DT_QINT16"},
1045 0 : {::toolkit::dumpdata::OutputDataType::DT_QINT32, "DT_QINT32"},
1046 0 : {::toolkit::dumpdata::OutputDataType::DT_QUINT8, "DT_QUINT8"},
1047 0 : {::toolkit::dumpdata::OutputDataType::DT_QUINT16, "DT_QUINT16"},
1048 0 : {::toolkit::dumpdata::OutputDataType::DT_RESOURCE, "DT_RESOURCE"},
1049 0 : {::toolkit::dumpdata::OutputDataType::DT_STRING_REF, "DT_STRING_REF"},
1050 0 : {::toolkit::dumpdata::OutputDataType::DT_DUAL, "DT_DUAL"}
1051 32 : };
1052 :
1053 4 : const auto iter = dataTypeMap.find(dataType);
1054 4 : if (iter == dataTypeMap.end()) {
1055 4 : return "-";
1056 : }
1057 :
1058 2 : return iter->second;
1059 1 : }
1060 :
1061 15 : std::string OpDumpTask::GenerateDataStatsInfo(uint64_t dataAddr, uint64_t dataSize,
1062 : ::toolkit::dumpdata::OutputDataType dataType) const
1063 : {
1064 15 : if (dataAddr == 0LU) {
1065 1 : aicpusd_warn("dataSize[%lu], dataAddr is zero", dataSize);
1066 2 : return ",,,,,,";
1067 : }
1068 14 : switch (dataType) {
1069 1 : case ::toolkit::dumpdata::OutputDataType::DT_FLOAT: {
1070 1 : NormalDataStats<float> dumpStats(dataAddr, dataSize);
1071 1 : return dumpStats.GetDataStatsStr();
1072 1 : }
1073 1 : case ::toolkit::dumpdata::OutputDataType::DT_FLOAT16: {
1074 1 : EigenDataStats dumpStats(dataAddr, dataSize);
1075 1 : return dumpStats.GetDataStatsStr();
1076 1 : }
1077 1 : case ::toolkit::dumpdata::OutputDataType::DT_UINT8: {
1078 1 : Uint8DataStats dumpStats(dataAddr, dataSize);
1079 1 : return dumpStats.GetDataStatsStr();
1080 1 : }
1081 1 : case ::toolkit::dumpdata::OutputDataType::DT_INT8: {
1082 1 : Int8DataStats dumpStats(dataAddr, dataSize);
1083 1 : return dumpStats.GetDataStatsStr();
1084 1 : }
1085 1 : case ::toolkit::dumpdata::OutputDataType::DT_INT16: {
1086 1 : NormalDataStats<int16_t> dumpStats(dataAddr, dataSize);
1087 1 : return dumpStats.GetDataStatsStr();
1088 1 : }
1089 1 : case ::toolkit::dumpdata::OutputDataType::DT_UINT16: {
1090 1 : NormalDataStats<uint16_t> dumpStats(dataAddr, dataSize);
1091 1 : return dumpStats.GetDataStatsStr();
1092 1 : }
1093 1 : case ::toolkit::dumpdata::OutputDataType::DT_INT32: {
1094 1 : NormalDataStats<int32_t> dumpStats(dataAddr, dataSize);
1095 1 : return dumpStats.GetDataStatsStr();
1096 1 : }
1097 1 : case ::toolkit::dumpdata::OutputDataType::DT_INT64: {
1098 1 : NormalDataStats<int64_t> dumpStats(dataAddr, dataSize);
1099 1 : return dumpStats.GetDataStatsStr();
1100 1 : }
1101 2 : case ::toolkit::dumpdata::OutputDataType::DT_UINT32: {
1102 2 : NormalDataStats<uint32_t> dumpStats(dataAddr, dataSize);
1103 2 : return dumpStats.GetDataStatsStr();
1104 2 : }
1105 1 : case ::toolkit::dumpdata::OutputDataType::DT_UINT64: {
1106 1 : NormalDataStats<uint64_t> dumpStats(dataAddr, dataSize);
1107 1 : return dumpStats.GetDataStatsStr();
1108 1 : }
1109 1 : case ::toolkit::dumpdata::OutputDataType::DT_BOOL: {
1110 1 : NormalDataStats<bool> dumpStats(dataAddr, dataSize);
1111 1 : return dumpStats.GetDataStatsStr();
1112 1 : }
1113 1 : case ::toolkit::dumpdata::OutputDataType::DT_DOUBLE: {
1114 1 : NormalDataStats<double> dumpStats(dataAddr, dataSize);
1115 1 : return dumpStats.GetDataStatsStr();
1116 1 : }
1117 1 : default: {
1118 1 : aicpusd_warn("Try to dump unsupported data type. dataType=%s[%d]", GetDataTypeStr(dataType).c_str(),
1119 : static_cast<int32_t>(dataType));
1120 1 : break;
1121 : }
1122 : }
1123 :
1124 : // If the data type is unsupported type, set all stats val to none
1125 2 : return ",,,,,,";
1126 : }
1127 :
1128 3 : std::string OpDumpTask::GenerateDataDimInfo(::toolkit::dumpdata::Shape dataShape) const
1129 : {
1130 3 : const int32_t dimSize = dataShape.dim_size();
1131 3 : if (dimSize <= 0) {
1132 2 : return "-";
1133 : }
1134 :
1135 2 : std::ostringstream oss;
1136 2 : for (int32_t i = 0; i < dimSize - 1; ++i) {
1137 0 : oss << dataShape.dim(i) << "x";
1138 : }
1139 2 : oss << dataShape.dim(dimSize - 1);
1140 :
1141 2 : return oss.str();
1142 2 : }
1143 :
1144 8 : std::string OpDumpTask::ShapeDebugString(std::vector<uint64_t> shapeInfo) const
1145 : {
1146 8 : const int32_t dimSize = shapeInfo.size();
1147 8 : if (dimSize <= 0) {
1148 0 : return "-";
1149 : }
1150 :
1151 8 : std::ostringstream oss;
1152 20 : for (int32_t i = 0; i < dimSize - 1; ++i) {
1153 12 : oss << shapeInfo[i] << "x";
1154 : }
1155 8 : oss << shapeInfo[dimSize - 1];
1156 8 : return oss.str();
1157 8 : }
1158 :
1159 8 : bool OpDumpTask::CheckAndGetKfcDumpStatsAPI()
1160 : {
1161 : // 假设当前该符号so已经打开,需要确认该符号已经打开
1162 8 : if (kfcDumpFunc_ != nullptr) {
1163 1 : return true;
1164 : }
1165 0 : const char *kfcDumpKernelName = (&AdumpStatsOpInitStatus != nullptr && AdumpStatsOpInitStatus())
1166 : ? "AdumpStatsOpSrvLaunch"
1167 7 : : "AicpuKfcDumpSrvLaunch";
1168 :
1169 7 : kfcDumpFunc_ = PtrToFunctionPtr<void, AicpuKfcDumpFuncPtr>(dlsym(RTLD_DEFAULT, kfcDumpKernelName));
1170 7 : if (kfcDumpFunc_ == nullptr) {
1171 2 : aicpusd_info("Kfc dump API[%s] not get.", kfcDumpKernelName);
1172 2 : return false;
1173 : }
1174 5 : aicpusd_info("Kfc dump API[%s] has get, no need get again.", kfcDumpKernelName);
1175 5 : return true;
1176 : }
1177 :
1178 56 : bool OpDumpTask::IsSupportKfcDump()
1179 : {
1180 56 : if (dumpMode_ != DumpMode::STATS_DUMP_DATA) {
1181 47 : return false;
1182 : }
1183 9 : if (taskType_ == aicpu::dump::Task::FFTSPLUS) {
1184 1 : aicpusd_info("Task is ffts plus and does not support kfc statistical dump.");
1185 1 : return false;
1186 : }
1187 8 : bool isHasKfcDumpFun = CheckAndGetKfcDumpStatsAPI();
1188 8 : if (!isHasKfcDumpFun) {
1189 2 : aicpusd_info("Not find kfc statistical dump api [%s] from kfc op.", KFC_DUMP_KERNEL_NAME.c_str());
1190 2 : return false;
1191 : }
1192 6 : aicpusd_info("Get kfc dump statistical api.");
1193 6 : return true;
1194 : }
1195 :
1196 4 : StatusCode OpDumpTask::ProcessKfcDumpStats(KfcDumpTask &taskInfo, const std::string &dumpFilePath)
1197 : {
1198 4 : dumpPath_ = dumpFilePath;
1199 4 : if (kfcDumpFunc_ == nullptr) {
1200 0 : aicpusd_err("Not get kfc statistical dump api [%s].", KFC_DUMP_KERNEL_NAME.c_str());
1201 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
1202 : }
1203 4 : void *param = PtrToPtr<KfcDumpTask, void>(&taskInfo);
1204 : static std::mutex mutexForKfcDumpFunc;
1205 4 : const std::lock_guard<std::mutex> lk(mutexForKfcDumpFunc);
1206 4 : int32_t ret = kfcDumpFunc_(param);
1207 4 : if (ret != 0) {
1208 0 : aicpusd_err("Kfc statistical dump [%s] ret = %d.", KFC_DUMP_KERNEL_NAME.c_str(), ret);
1209 : }
1210 4 : return ret;
1211 4 : }
1212 :
1213 5 : StatusCode OpDumpTask::ProcessDumpStatistic(const TaskInfoExt &dumpTaskInfo, const std::string &dumpFilePath)
1214 : {
1215 5 : if (!IsSupportKfcDump()) {
1216 1 : return ProcessDumpStats(dumpFilePath);
1217 : }
1218 4 : KfcDumpTask taskInfo(dumpTaskInfo.streamId_, dumpTaskInfo.taskId_, dumpTaskInfo.indexId_);
1219 4 : return ProcessKfcDumpStats(taskInfo, dumpFilePath);
1220 : }
1221 :
1222 1 : StatusCode OpDumpTask::ProcessDumpStats(const std::string &dumpFilePath)
1223 : {
1224 1 : std::ostringstream oss;
1225 : oss << "Input/Output,Index,Data Size,Data Type,Format,Shape,Max Value,Min Value,"
1226 1 : << "Avg Value,Count,Nan Count,Negative Inf Count,Positive Inf Count\n";
1227 :
1228 2 : for (int64_t i = 0; i < baseDumpData_.input_size(); ++i) {
1229 1 : const auto input = baseDumpData_.input(i);
1230 1 : aicpusd_info("Input[%u], data_type[%llu], size[%llu]", i, input.data_type(), input.size());
1231 2 : oss << "Input," << i << "," << input.size() << ","<< GetDataTypeStr(input.data_type()) << ","
1232 3 : << GetDataFormatStr(input.format()) << "," << GenerateDataDimInfo(input.shape())
1233 4 : << "," << GenerateDataStatsInfo(input.address(), input.size(), input.data_type()) << "\n";
1234 1 : }
1235 :
1236 2 : for (int64_t i = 0; i < baseDumpData_.output_size(); ++i) {
1237 1 : const auto output = baseDumpData_.output(i);
1238 1 : aicpusd_info("output[%u], data_type[%llu], size[%llu]", i, output.data_type(), output.size());
1239 2 : oss << "Output," << i << "," << output.size() << "," << GetDataTypeStr(output.data_type()) << ","
1240 3 : << GetDataFormatStr(output.format()) << "," << GenerateDataDimInfo(output.shape())
1241 4 : << "," << GenerateDataStatsInfo(output.address(), output.size(), output.data_type()) << "\n";
1242 1 : }
1243 :
1244 1 : const std::string statsFilePath = dumpFilePath + ".csv";
1245 2 : return DoDumpStats(statsFilePath, oss.str());
1246 1 : }
1247 :
1248 4 : StatusCode OpDumpTask::DoDumpStats(const std::string &dumpFilePath, const std::string &content)
1249 : {
1250 4 : IDE_SESSION ideSession = DumpSessionManager::GetInstance().GetSession(hostPid_, deviceId_);
1251 4 : if (ideSession == nullptr) {
1252 1 : aicpusd_err("op name[%s], call IdeDumpStart failed, path[%s].", opName_.c_str(), dumpFilePath.c_str());
1253 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
1254 : }
1255 :
1256 3 : return Dump(dumpFilePath, const_cast<char_t *>(content.c_str()), content.size(), ideSession, true);
1257 : }
1258 :
1259 10 : void OpDumpTask::UpdateDumpNum()
1260 : {
1261 10 : const std::lock_guard<std::mutex> queLock(dumpMtx_);
1262 10 : taskDumpNum_++;
1263 10 : aicpusd_info("op name[%s], dump number is updated, dump number[%llu].", opName_.c_str(), taskDumpNum_);
1264 10 : }
1265 :
1266 32 : bool OpDumpTask::IsEndGraph() const
1267 : {
1268 32 : return endGraph_;
1269 : }
1270 :
1271 3 : bool OpDumpTask::GetModelId(uint32_t &modelId) const
1272 : {
1273 3 : if (optionalParam_.hasModelId) {
1274 3 : modelId = optionalParam_.modelId;
1275 3 : return true;
1276 : }
1277 0 : return false;
1278 : }
1279 :
1280 0 : std::string OpDumpTask::GetOpName() const
1281 : {
1282 0 : return opName_;
1283 : }
1284 :
1285 45 : bool OpDumpTask::NeedDump(const uint64_t step) const
1286 : {
1287 45 : if (endGraph_) {
1288 2 : aicpusd_run_info("op name[%s], end graph dump task.", opName_.c_str());
1289 2 : return false;
1290 : }
1291 43 : if ((!optionalParam_.hasStepId) && (!dumpStep_.singleStep.empty() || !dumpStep_.intervalStep.empty())) {
1292 1 : aicpusd_run_info("op name[%s], the stepid needs to be filtered, but no stepid addr.", opName_.c_str());
1293 1 : return false;
1294 : }
1295 41 : bool stepNeedDump = false;
1296 41 : if (dumpStep_.singleStep.empty() && dumpStep_.intervalStep.empty()) {
1297 37 : stepNeedDump = true;
1298 : }
1299 41 : if (dumpStep_.singleStep.find(step) != dumpStep_.singleStep.end()) {
1300 0 : stepNeedDump = true;
1301 : }
1302 45 : for (const auto item : dumpStep_.intervalStep) {
1303 4 : if ((step >= item.start) && (step <= item.end)) {
1304 0 : stepNeedDump = true;
1305 0 : break;
1306 : }
1307 : }
1308 42 : if (!stepNeedDump) {
1309 4 : aicpusd_run_info("op name[%s], the step[%llu] is not in dump list %s.",
1310 : opName_.c_str(), step, dumpStep_.DebugString().c_str());
1311 4 : return false;
1312 : }
1313 :
1314 38 : if ((inputTotalSize_ == 0U) &&
1315 7 : (outputTotalSize_ == 0U) &&
1316 7 : (opBufferTotalSize_ == 0U) && (opWorkspaceTotalSize_ == 0U)) {
1317 7 : aicpusd_run_info("op name[%s], no data need to dump.", opName_.c_str());
1318 7 : return false;
1319 : }
1320 :
1321 31 : return true;
1322 : }
1323 :
1324 32 : std::string OpDumpTask::DumpPath(const uint64_t nowTime, const uint64_t dumpNumber,
1325 : const DumpFileName &dumpFileName,
1326 : const bool debugFlag)
1327 : {
1328 32 : const uint32_t streamId = dumpFileName.streamId_;
1329 32 : const uint32_t taskId = dumpFileName.taskId_;
1330 32 : const uint32_t contextId = dumpFileName.contextId_;
1331 32 : const uint32_t threadId = dumpFileName.threadId_;
1332 32 : std::ostringstream oss;
1333 33 : const uint32_t deviceId = deviceId_;
1334 33 : oss << baseDumpPath_;
1335 33 : if (optionalParam_.hasModelName) {
1336 24 : oss << "/" << optionalParam_.modelName;
1337 : }
1338 33 : if (optionalParam_.hasModelId) {
1339 25 : oss << "/" << optionalParam_.modelId;
1340 : }
1341 : // single op dump
1342 33 : if (optionalParam_.hasStepId) {
1343 20 : oss << "/" << dumpNumber;
1344 : }
1345 :
1346 33 : std::string opName = opName_;
1347 33 : std::string opType = opType_;
1348 33 : ReplaceStringElem(opName);
1349 33 : ReplaceStringElem(opType);
1350 33 : if (debugFlag) {
1351 1 : opName += "Debug";
1352 : }
1353 33 : oss << "/" << opType << "." << opName << "." << taskId << "." << streamId << "." << nowTime;
1354 33 : if ((contextId != INVALID_VAL) && (threadId != INVALID_VAL)) {
1355 7 : oss << "." << aicpu::dump::Task::FFTSPLUS << "." << contextId << "." << threadId << "." << deviceId;
1356 : }
1357 :
1358 66 : return oss.str();
1359 33 : }
1360 :
1361 24 : void OpDumpTask::ClearBaseDumpData()
1362 : {
1363 24 : baseDumpData_.Clear();
1364 24 : return;
1365 : }
1366 :
1367 4 : std::string DumpStep::DebugString() const
1368 : {
1369 4 : std::ostringstream oss;
1370 8 : for (const auto step : singleStep) {
1371 4 : oss << "[" << step << "] ";
1372 : }
1373 8 : for (const auto step : intervalStep) {
1374 4 : oss << "[" << step.start << ", " << step.end << "] ";
1375 : }
1376 :
1377 8 : return oss.str();
1378 4 : }
1379 :
1380 : template <typename T>
1381 119 : DataStats<T>::~DataStats() {}
1382 :
1383 : template <typename T>
1384 119 : void DataStats<T>::Stats()
1385 : {
1386 119 : ResetStats();
1387 119 : maxValue_ = minValue_ = data_[0];
1388 5349 : for (uint64_t i = 0UL; i < count_; ++i) {
1389 5230 : T ele = data_[i];
1390 5230 : if (IsNan(ele)) {
1391 1 : ++nanCount_;
1392 : }
1393 :
1394 5230 : if (ele > maxValue_) {
1395 368 : maxValue_ = ele;
1396 : }
1397 5230 : if (ele < minValue_) {
1398 343 : minValue_ = ele;
1399 : }
1400 :
1401 5230 : if (IsInf(ele)) {
1402 1 : if (ele > static_cast<T>(0)) {
1403 1 : ++posInfCount_;
1404 : } else {
1405 0 : ++negInfCount_;
1406 : }
1407 : }
1408 :
1409 5230 : UpdateAvgValue(ele, i);
1410 : }
1411 119 : AdjustAvgValue();
1412 :
1413 119 : return;
1414 : }
1415 : /*
1416 : * 组装kfc需要的dump信息
1417 : */
1418 6 : void OpDumpTask::GetKfcDumpInfo(std::shared_ptr<KfcDumpInfo> dumpInfo)
1419 : {
1420 : // dumpInfo指针为空校验在调用者保证
1421 6 : dumpInfo->opName = opName_;
1422 6 : dumpInfo->opType = opType_;
1423 6 : aicpusd_info("Dump op info for kfc op : opName[%s], opType[%s].", dumpInfo->opName.c_str(), dumpInfo->opType.c_str());
1424 7 : for (size_t i = 0; i < opWorkspaceAddr_.size(); i++) {
1425 1 : dumpInfo->workspace.push_back({LOG, opWorkspaceAddr_[i], opWorkspaceSize_[i]});
1426 1 : aicpusd_info("Dump op info for kfc op: opWorkspaceAddr[%lu] size[%lu].", dumpInfo->workspace[i].data_addr, dumpInfo->workspace[i].size);
1427 : }
1428 8 : for (size_t i = 0; i < inputsBaseAddr_.size(); i++) {
1429 2 : InputOutputKfcDumpInfo inputKfcDumpInfo;
1430 2 : inputKfcDumpInfo.index = i;
1431 2 : inputKfcDumpInfo.data_type = inputsDataType_[i];
1432 2 : inputKfcDumpInfo.format = inputsFormat_[i];
1433 2 : inputKfcDumpInfo.address = baseDumpData_.mutable_input(i)->address();
1434 2 : inputKfcDumpInfo.size = inputsSize_[i];
1435 2 : inputKfcDumpInfo.shape = inputsShape_[i];
1436 2 : inputKfcDumpInfo.origin_shape = inputsOriginShape_[i];
1437 2 : dumpInfo->inputDumpInfo.push_back(inputKfcDumpInfo);
1438 2 : aicpusd_info("Dump input info for kfc op: index[%d], data_type[%d], format[%d], address[%ld], size[%ld], shape[%s], origin_shape[%s]",
1439 : dumpInfo->inputDumpInfo[i].index,
1440 : dumpInfo->inputDumpInfo[i].data_type,
1441 : dumpInfo->inputDumpInfo[i].format,
1442 : dumpInfo->inputDumpInfo[i].address,
1443 : dumpInfo->inputDumpInfo[i].size,
1444 : ShapeDebugString(dumpInfo->inputDumpInfo[i].shape).c_str(), ShapeDebugString(dumpInfo->inputDumpInfo[i].origin_shape).c_str());
1445 2 : }
1446 8 : for (size_t i = 0; i < outputsBaseAddr_.size(); i++) {
1447 2 : InputOutputKfcDumpInfo outputKfcDumpInfo;
1448 2 : outputKfcDumpInfo.index = i;
1449 2 : outputKfcDumpInfo.data_type = outputsDataType_[i];
1450 2 : outputKfcDumpInfo.format = outputsFormat_[i];
1451 2 : outputKfcDumpInfo.address = baseDumpData_.mutable_output(i)->address();
1452 2 : outputKfcDumpInfo.size = outputSize_[i];
1453 2 : outputKfcDumpInfo.shape = outputsShape_[i];
1454 2 : outputKfcDumpInfo.origin_shape = outputsOriginShape_[i];
1455 2 : dumpInfo->outputDumpInfo.push_back(outputKfcDumpInfo);
1456 2 : aicpusd_info("Dump output info for kfc op: index[%d], data_type[%d], format[%d], address[%ld], size[%ld], shape[%s], origin_shape[%s].",
1457 : dumpInfo->outputDumpInfo[i].index,
1458 : dumpInfo->outputDumpInfo[i].data_type,
1459 : dumpInfo->outputDumpInfo[i].format,
1460 : dumpInfo->outputDumpInfo[i].address,
1461 : dumpInfo->outputDumpInfo[i].size,
1462 : ShapeDebugString(dumpInfo->outputDumpInfo[i].shape).c_str(), ShapeDebugString(dumpInfo->outputDumpInfo[i].origin_shape).c_str());
1463 2 : }
1464 6 : return;
1465 : }
1466 3 : void OpDumpTask::UpdateUdfDumpDataTotalSize()
1467 : {
1468 6 : for (int64_t i = 0; i < baseDumpData_.input_size(); ++i) {
1469 3 : auto &input = baseDumpData_.input(i);
1470 3 : uint64_t len = input.size();
1471 3 : if (len == 0U) {
1472 0 : aicpusd_warn("input[%ld] data size is zero", i);
1473 0 : continue;
1474 : }
1475 3 : inputTotalSize_ += len;
1476 : }
1477 6 : for (int64_t i = 0; i < baseDumpData_.output_size(); ++i) {
1478 3 : auto &output = baseDumpData_.output(i);
1479 3 : uint64_t len = output.size();
1480 3 : if (len == 0U) {
1481 0 : aicpusd_warn("output[%ld] data size is zero", i);
1482 0 : continue;
1483 : }
1484 3 : outputTotalSize_ += len;
1485 : }
1486 3 : return;
1487 : }
1488 6 : StatusCode OpDumpTask::PreProcessUdfOpMappingInfo(uint8_t *dumpInfo, uint64_t length)
1489 : {
1490 6 : if (dumpInfo == nullptr || length == 0) {
1491 2 : aicpusd_err("dump info is nullptr or length is [%lu]", length);
1492 2 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
1493 : }
1494 4 : aicpusd_info("PreProcessUdfOpMappingInfo begin length is %lu", length);
1495 4 : char_t *addr = PtrToPtr<void, char_t>(ValueToPtr(PtrToValue(dumpInfo) + sizeof(uint64_t *)));
1496 4 : uint64_t addrLength = *(PtrToPtr<uint8_t, uint64_t>(dumpInfo));
1497 4 : char_t *path = PtrToPtr<void, char_t>(ValueToPtr(PtrToValue(addr) + addrLength + sizeof(uint64_t *)));
1498 4 : uint64_t pathLength = *(PtrToPtr<char_t, uint64_t>(addr + addrLength));
1499 4 : if ((addrLength + pathLength) > length) {
1500 1 : aicpusd_err("addrLength[%lu] + pathLength[%lu] > length[%lu]", addrLength, pathLength, length);
1501 1 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
1502 : }
1503 3 : const bool parseRet = baseDumpData_.ParseFromArray(addr, addrLength);
1504 3 : if (!parseRet) {
1505 0 : aicpusd_err("parse op udf info failed, addrLength[%lu]", addrLength);
1506 0 : return AICPU_SCHEDULE_ERROR_DUMP_FAILED;
1507 : }
1508 3 : aicpusd_info("dump info is %s", baseDumpData_.DebugString().c_str());
1509 3 : opName_ = baseDumpData_.op_name();
1510 3 : UpdateUdfDumpDataTotalSize();
1511 3 : std::string pathStr(path, pathLength);
1512 3 : aicpusd_info("pathStr is %s", pathStr.c_str());
1513 3 : auto dumpRet = ProcessDumpTensor(pathStr);
1514 3 : if (dumpRet != AICPU_SCHEDULE_OK) {
1515 2 : aicpusd_err("Dump failed. ret=%d, pathStr=%s, dump info is %s",
1516 : static_cast<int32_t>(dumpRet), pathStr.c_str(), baseDumpData_.DebugString().c_str());
1517 2 : return dumpRet;
1518 : }
1519 1 : return AICPU_SCHEDULE_OK;
1520 3 : }
1521 :
1522 121 : DumpSessionManager &DumpSessionManager::GetInstance()
1523 : {
1524 121 : static DumpSessionManager instance;
1525 121 : return instance;
1526 : }
1527 :
1528 63 : IDE_SESSION DumpSessionManager::GetSession(int32_t hostPid, uint32_t deviceId)
1529 : {
1530 63 : std::lock_guard<std::mutex> lock(mutex_);
1531 63 : const uint64_t threadId = GetTid();
1532 63 : if (sessionsMap_.find(threadId) == sessionsMap_.end()) {
1533 35 : auto startTime = std::chrono::steady_clock::now();
1534 35 : sessionsMap_[threadId] = CreateIdeDumpSession(hostPid, deviceId);
1535 35 : auto endTime = std::chrono::steady_clock::now();
1536 35 : const double drUs = std::chrono::duration<double, std::micro>(endTime - startTime).count();
1537 35 : aicpusd_run_info("thread[%lu] create ide dump session success, cost time is [%.2lf]us.",threadId, drUs);
1538 : }
1539 126 : return sessionsMap_[threadId];
1540 63 : }
1541 :
1542 15 : IDE_SESSION DumpSessionManager::ReacquireSession(int32_t hostPid, uint32_t deviceId)
1543 : {
1544 15 : std::lock_guard<std::mutex> lock(mutex_);
1545 15 : const uint64_t threadId = GetTid();
1546 15 : if (sessionsMap_.find(threadId) == sessionsMap_.end()) {
1547 9 : auto startTime = std::chrono::steady_clock::now();
1548 9 : sessionsMap_[threadId] = CreateIdeDumpSession(hostPid, deviceId);
1549 9 : auto endTime = std::chrono::steady_clock::now();
1550 9 : const double drUs = std::chrono::duration<double, std::micro>(endTime - startTime).count();
1551 9 : aicpusd_run_info("thread[%lu] create ide dump session success, cost time is [%.2lf]us.",threadId, drUs);
1552 : } else {
1553 6 : auto startTime = std::chrono::steady_clock::now();
1554 6 : (void)IdeDumpEnd(sessionsMap_[threadId]);
1555 6 : sessionsMap_[threadId] = CreateIdeDumpSession(hostPid, deviceId);
1556 6 : auto endTime = std::chrono::steady_clock::now();
1557 6 : const double drUs = std::chrono::duration<double, std::micro>(endTime - startTime).count();
1558 6 : aicpusd_run_info("thread[%lu] reacquire ide dump session success, cost time is [%.2lf]us.",threadId, drUs);
1559 : }
1560 30 : return sessionsMap_[threadId];
1561 15 : }
1562 :
1563 82 : void DumpSessionManager::CloseAllSessions()
1564 : {
1565 82 : std::lock_guard<std::mutex> lock(mutex_);
1566 124 : for (auto& pair : sessionsMap_) {
1567 42 : if (pair.second != nullptr) {
1568 30 : auto startTime = std::chrono::steady_clock::now();
1569 30 : (void)IdeDumpEnd(pair.second);
1570 30 : auto endTime = std::chrono::steady_clock::now();
1571 30 : const double drUs = std::chrono::duration<double, std::micro>(endTime - startTime).count();
1572 30 : aicpusd_run_info("thread[%lu] reacquire ide dump session success, cost time is [%.2lf]us.",pair.first, drUs);
1573 : }
1574 : }
1575 82 : sessionsMap_.clear();
1576 82 : }
1577 :
1578 52 : IDE_SESSION DumpSessionManager::CreateIdeDumpSession(int32_t hostPid, uint32_t deviceId) const
1579 : {
1580 52 : const std::string privateInfo = "127.0.0.1:22118;" + std::to_string(deviceId) + ";" + std::to_string(hostPid);
1581 52 : aicpusd_info("ide dump start private info[%s]", privateInfo.c_str());
1582 52 : IDE_SESSION ideSession = IdeDumpStart(privateInfo.c_str());
1583 52 : if (ideSession == nullptr) {
1584 13 : aicpusd_err("call IdeDumpStart failed, private info[%s], hostPid[%d], deviceId[%u]", privateInfo.c_str(), hostPid, deviceId);
1585 13 : return nullptr;
1586 : }
1587 39 : return ideSession;
1588 52 : }
1589 : } // namespace aicpu
|