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