• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2019-2020 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 "utils/info.h"
18 #include <utility>
19 #include <fstream>
20 #include <sstream>
21 #include <climits>
22 #include "ir/anf.h"
23 #include "utils/convert_utils_base.h"
24 
25 namespace mindspore {
HighLightLine(const std::string & line,int col_begin,int col_end,SourceLineTip tip)26 std::string HighLightLine(const std::string &line, int col_begin, int col_end, SourceLineTip tip) {
27   std::string temp_line = line;
28   if (col_begin < col_end && col_begin != -1 && col_end <= SizeToLong(temp_line.length()) &&
29       tip != kSourceLineTipDiscard) {
30     std::string start = temp_line.substr(0, LongToSize(col_begin));
31     std::string trimmed = temp_line.substr(LongToSize(col_begin), LongToSize(col_end - col_begin));
32     std::string end = temp_line.substr(LongToSize(col_end), LongToSize(SizeToLong(temp_line.length()) - col_end));
33     std::stringstream oss;
34     std::stringstream tip_ss;
35     std::string start_spaces(start.length(), ' ');
36     if (tip == kSourceLineTipInLine) {
37       temp_line = start + "<" + trimmed + ">" + end;
38     } else if (tip == kSourceLineTipNextLine) {
39       tip_ss << start_spaces << "^";
40     }
41     oss << temp_line << "\n" << tip_ss.str();
42     return oss.str();
43   }
44   return temp_line;
45 }
46 // Generate debug information for the location node .
47 // print the file name, line no and column no, and part of the content
ToString(SourceLineTip tip) const48 std::string Location::ToString(SourceLineTip tip) const {
49   std::stringstream debug_info_ss;
50   debug_info_ss << "In file " << file_name_ << "(" << line_ << ")" << std::endl;
51   if (line_ <= 0) {
52     return debug_info_ss.str();
53   }
54 
55   char path[PATH_MAX] = {0x00};
56 #if defined(_WIN32) || defined(_WIN64)
57   if (file_name_.size() >= PATH_MAX || _fullpath(path, file_name_.c_str(), PATH_MAX) == nullptr) {
58     return debug_info_ss.str();
59   }
60 #else
61   if (file_name_.size() >= PATH_MAX || realpath(file_name_.c_str(), path) == nullptr) {
62     return debug_info_ss.str();
63   }
64 #endif
65   auto src_path = std::string(path);
66   std::ifstream file(src_path);
67   if (!file.is_open()) {
68     return debug_info_ss.str();
69   }
70 
71   int line_num = 0;
72   std::string line;
73   (void)getline(file, line);
74   while (line_num != line_ - 1) {
75     (void)getline(file, line);
76     line_num++;
77   }
78   file.close();
79 
80   debug_info_ss << HighLightLine(line, column_, column_end_, tip) << std::endl;
81   return debug_info_ss.str();
82 }
83 
ProcessAttributeFromContext()84 void TraceContext::ProcessAttributeFromContext() {
85   trace_info_ = nullptr;
86   location_ = nullptr;
87   func_name_ = "";
88   // if there is trace context, get info from previous context
89   if (!TraceManager::trace_context_stack_.empty()) {
90     TraceContextPtr top = TraceManager::trace_context_stack_.top();
91     trace_info_ = top->trace_info();
92     location_ = top->location();
93     func_name_ = top->func_name();
94   }
95 }
96 
DebugInfo()97 DebugInfo::DebugInfo() {
98   InitValueFromContext();
99   unique_id_ = gen_unique_id();
100   debug_id_ = -1;
101   name_ = "";
102 }
103 
DebugInfo(const std::string & name)104 DebugInfo::DebugInfo(const std::string &name) {
105   InitValueFromContext();
106   unique_id_ = gen_unique_id();
107   debug_id_ = -1;
108   name_ = name;
109 }
110 
DebugInfo(const LocationPtr & loc)111 DebugInfo::DebugInfo(const LocationPtr &loc) {
112   InitValueFromContext();
113   unique_id_ = gen_unique_id();
114   debug_id_ = -1;
115   location_ = loc;
116 }
117 
debug_id()118 int64_t DebugInfo::debug_id() {
119   // cppcheck-suppress variableScope
120   static int64_t cur_debug_id = 0;
121   if (debug_id_ == -1) {
122     debug_id_ = cur_debug_id;
123     cur_debug_id++;
124   }
125   return debug_id_;
126 }
127 
unique_id_through_copy() const128 int64_t DebugInfo::unique_id_through_copy() const {
129   auto info = trace_info();
130   if (info != nullptr) {
131     if (info->isa<TraceCopy>() && info->debug_info() != nullptr) {
132       return info->debug_info()->unique_id_through_copy();
133     }
134   }
135   return unique_id();
136 }
137 
debug_name()138 std::string DebugInfo::debug_name() {
139   if (!name_.empty()) {
140     return name_;
141   }
142   std::string debug_name = std::to_string(debug_id());
143   name_ = debug_name;
144   return debug_name;
145 }
146 
debug_name()147 std::string NodeDebugInfo::debug_name() {
148   if (!name_.empty()) {
149     return name_;
150   }
151   std::string prefix = "";
152   if (node_.lock() != nullptr) {
153     std::ostringstream oss;
154     oss << "[" << node_.lock()->type_name() << "]";
155     prefix = oss.str();
156   }
157   name_ = prefix + DebugInfo::debug_name();
158   return name_;
159 }
160 
debug_name()161 std::string GraphDebugInfo::debug_name() {
162   std::string prefix = "";
163   return prefix + DebugInfo::debug_name();
164 }
165 
location()166 LocationPtr GraphDebugInfo::location() {
167   // function may have decorator which is included in its location
168   if (deco_loc_ != nullptr && DebugInfo::location() != nullptr) {
169     LocationPtr loc = std::make_shared<Location>(*DebugInfo::location());
170     loc->set_line(loc->line() + (deco_loc_->line_end() - deco_loc_->line() + 1));
171     return loc;
172   }
173   return DebugInfo::location();
174 }
set_deco_location(const LocationPtr & deco_list_loc)175 void GraphDebugInfo::set_deco_location(const LocationPtr &deco_list_loc) { deco_loc_ = deco_list_loc; }
176 
CurrentContextInfo()177 TraceContextPtr TraceManager::CurrentContextInfo() {
178   if (!TraceManager::trace_context_stack_.empty()) {
179     return TraceManager::trace_context_stack_.top();
180   }
181   return nullptr;
182 }
183 
DebugTrace(const std::string & func_name,const LocationPtr & location)184 void TraceManager::DebugTrace(const std::string &func_name, const LocationPtr &location) {
185   if (location == nullptr) {
186     MS_LOG(EXCEPTION) << "DebugTrace wrong location is null";
187   }
188   TraceContextPtr context = std::make_shared<TraceContext>(location);
189   context->set_func_name(func_name);
190   TraceManager::trace_context_stack_.push(context);
191 }
192 
DebugTrace(const LocationPtr & location)193 void TraceManager::DebugTrace(const LocationPtr &location) {
194   if (location == nullptr) {
195     MS_LOG(EXCEPTION) << "DebugTrace wrong location is null";
196   }
197   TraceContextPtr context = std::make_shared<TraceContext>(location);
198   TraceManager::trace_context_stack_.push(context);
199   TraceManager::parse_or_resolve_debug_info_ = std::make_shared<DebugInfo>(location);
200 }
201 
DebugTrace(const TraceInfoPtr & trace_info)202 void TraceManager::DebugTrace(const TraceInfoPtr &trace_info) {
203   if (trace_info == nullptr) {
204     MS_LOG(EXCEPTION) << "DebugTrace wrong traced info is null";
205   }
206   TraceContextPtr context = std::make_shared<TraceContext>(trace_info);
207   if (trace_info->debug_info() == nullptr) {
208     MS_LOG(EXCEPTION) << "Trace debug info is null";
209   }
210   TraceManager::trace_context_stack_.push(context);
211   TraceManager::parse_or_resolve_debug_info_ = trace_info->debug_info();
212 }
213 
DebugTrace(const DebugInfoPtr & debug_info,const TraceInfoPtr & trace_info)214 void TraceManager::DebugTrace(const DebugInfoPtr &debug_info, const TraceInfoPtr &trace_info) {
215   if (trace_info == nullptr) {
216     MS_LOG(EXCEPTION) << "DebugTrace wrong traced info is null";
217   }
218   auto cloned_info = trace_info->clone();
219   cloned_info->set_debug_info(debug_info);
220   if (cloned_info->debug_info() == nullptr) {
221     MS_LOG(EXCEPTION) << "Trace debug info is null with cloned trace";
222   }
223   TraceContextPtr context = std::make_shared<TraceContext>(cloned_info);
224   TraceManager::trace_context_stack_.push(context);
225 }
226 
EndTrace()227 void TraceManager::EndTrace() { TraceManager::trace_context_stack_.pop(); }
228 
GetParseOrResolveDebugInfo()229 DebugInfoPtr TraceManager::GetParseOrResolveDebugInfo() { return TraceManager::parse_or_resolve_debug_info_; }
230 
ClearParseOrResolveDebugInfo()231 void TraceManager::ClearParseOrResolveDebugInfo() { TraceManager::parse_or_resolve_debug_info_ = nullptr; }
232 
233 thread_local std::stack<TraceContextPtr> TraceManager::trace_context_stack_;
234 
235 thread_local DebugInfoPtr TraceManager::parse_or_resolve_debug_info_ = nullptr;
236 }  // namespace mindspore
237