1 /**
2 * Copyright 2021-2024 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "include/backend/debug/data_dump/tensor_stat_dump.h"
18 #include <map>
19 #include "debug/debug_services.h"
20 #include "debug/utils.h"
21 #include "include/backend/debug/common/csv_writer.h"
22 #include "include/backend/debug/debugger/debugger.h"
23 #include "include/common/debug/common.h"
24 namespace {
25 constexpr auto kInput = "input";
26 constexpr auto kOutput = "output";
27 constexpr auto kCsvFileName = "statistic.csv";
28 } // namespace
29
30 namespace mindspore {
TensorStatDump(const std::string & op_type,const std::string & op_name,uint32_t task_id,uint32_t stream_id,uint64_t timestamp,bool input,size_t slot,size_t tensor_loader_slot)31 TensorStatDump::TensorStatDump(const std::string &op_type, const std::string &op_name, uint32_t task_id,
32 uint32_t stream_id, uint64_t timestamp, bool input, size_t slot,
33 size_t tensor_loader_slot)
34 : op_type_{op_type},
35 op_name_{op_name},
36 task_id_{std::to_string(task_id)},
37 stream_id_{std::to_string(stream_id)},
38 timestamp_{std::to_string(timestamp)},
39 slot_{slot},
40 tensor_loader_slot_{tensor_loader_slot} {
41 if (input) {
42 io_ = kInput;
43 } else {
44 io_ = kOutput;
45 }
46 }
47
TensorStatDump(const std::string & op_type,const std::string & op_name,const std::string & task_id,const std::string & stream_id,const std::string & timestamp,const std::string & io,size_t slot,size_t tensor_loader_slot,const mindspore::TypeId data_type)48 TensorStatDump::TensorStatDump(const std::string &op_type, const std::string &op_name, const std::string &task_id,
49 const std::string &stream_id, const std::string ×tamp, const std::string &io,
50 size_t slot, size_t tensor_loader_slot, const mindspore::TypeId data_type)
51 : op_type_{op_type},
52 op_name_{op_name},
53 task_id_{task_id},
54 stream_id_{stream_id},
55 timestamp_{timestamp},
56 io_{io},
57 slot_{slot},
58 tensor_loader_slot_{tensor_loader_slot},
59 data_type_{data_type} {
60 if (io_ != kInput && io_ != kOutput) {
61 MS_LOG(EXCEPTION) << "Cannot instantiate TensorStatDump, io needs to be either " << kInput << " or " << kOutput;
62 }
63 }
64
OpenStatisticsFile(const std::string & dump_path)65 bool TensorStatDump::OpenStatisticsFile(const std::string &dump_path) {
66 std::string filename = dump_path + "/" + kCsvFileName;
67 // try to open file
68 CsvWriter &csv = CsvWriter::GetInstance();
69 const string csv_header = CsvHeaderUtil::GetInstance().GetStatCsvHeader();
70 int retry = 2;
71 while (retry > 0) {
72 if (csv.OpenFile(filename, csv_header)) {
73 break;
74 }
75 retry--;
76 }
77 if (retry == 0) {
78 MS_LOG(WARNING) << "Open statistic dump file failed, skipping current statistics";
79 return false;
80 }
81 return true;
82 }
83
DumpTensorStatsToFile(const std::string & original_kernel_name,const std::string & dump_path,const Debugger * debugger)84 bool TensorStatDump::DumpTensorStatsToFile(const std::string &original_kernel_name, const std::string &dump_path,
85 const Debugger *debugger) {
86 // get tensor data using debugger
87 std::string tensor_loader_name = original_kernel_name + ":" + std::to_string(tensor_loader_slot_);
88 std::shared_ptr<TensorData> data = debugger->GetTensor(tensor_loader_name);
89 if (data == nullptr) {
90 MS_LOG(INFO) << "Failed to find " << tensor_loader_name << " in tensor loader, skipping current statistics";
91 return false;
92 }
93 return DumpTensorStatsToFile(dump_path, data);
94 }
95
DumpTensorStatsToFile(const std::string & dump_path,const std::shared_ptr<TensorData> data)96 bool TensorStatDump::DumpTensorStatsToFile(const std::string &dump_path, const std::shared_ptr<TensorData> data) {
97 if (data == nullptr) {
98 MS_LOG(INFO) << "Tensor data is empty, skipping current statistics";
99 return false;
100 }
101 std::string type = data->GetTypeString();
102 if (type.empty()) {
103 type = "unsupported(" + std::to_string(data->GetType()) + ")";
104 MS_LOG(INFO) << "Unsupported tensor data_type " << type << " for tensor " << data->GetName();
105 }
106 std::string filename = dump_path + "/" + kCsvFileName;
107 // try to open file
108 CsvWriter csv;
109 const auto csv_header = CsvHeaderUtil::GetInstance().GetStatCsvHeader();
110 if (!csv.OpenFile(filename, csv_header)) {
111 MS_LOG(WARNING) << "Open statistic dump file failed, skipping current statistics";
112 return false;
113 }
114 DebugServices::TensorStat stat = DebugServices::GetTensorStatistics(data);
115 // write tensor statistics to csv file
116 std::ostringstream shape;
117 shape << "\"(";
118 for (size_t i = 0; i < stat.shape.size(); i++) {
119 shape << (i > 0 ? "," : "") << stat.shape[i];
120 }
121 shape << ")\"";
122
123 csv.WriteToCsv(op_type_);
124 csv.WriteToCsv(op_name_);
125 csv.WriteToCsv(task_id_);
126 csv.WriteToCsv(stream_id_);
127 csv.WriteToCsv(timestamp_);
128 csv.WriteToCsv(io_);
129 csv.WriteToCsv(slot_);
130 csv.WriteToCsv(stat.data_size);
131 if (data_type_ != mindspore::TypeId::kTypeUnknown) {
132 csv.WriteToCsv(TypeIdToString(data_type_, true));
133 } else {
134 csv.WriteToCsv(type);
135 }
136 csv.WriteToCsv(shape.str());
137 stat.UpdateHeaderItemMap();
138 auto &dump_json_parser = DumpJsonParser::GetInstance();
139 auto statistic_category = dump_json_parser.statistic_category();
140 // first several item write to file without endline;
141 for (auto &header : statistic_category) {
142 auto &item = stat.header_item_map[header];
143 csv.WriteToCsv(item);
144 MS_LOG(INFO) << "Write the :" << header << " into file, value is: " << item;
145 }
146 csv.WriteToCsv("", true);
147 csv.CloseFile();
148 return true;
149 }
150 } // namespace mindspore
151