1 /** 2 * Copyright 2023 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 #ifndef MINDSPORE_PI_JIT_COMMON_H 17 #define MINDSPORE_PI_JIT_COMMON_H 18 19 #define PY_SSIZE_T_CLEAN 20 #include <functional> 21 #include <list> 22 #include <map> 23 #include <memory> 24 #include <string> 25 #include <tuple> 26 #include <unordered_map> 27 #include <utility> 28 #include <vector> 29 #include "pybind11/pybind11.h" 30 #include "pipeline/jit/pi/pydef.h" 31 #include "pipeline/jit/pi/graph_guard/cache.h" 32 #include "pipeline/jit/pi/pi_jit_config.h" 33 #include "pipeline/jit/pi/utils/utils.h" 34 #include "utils/convert_utils_base.h" 35 36 namespace mindspore { 37 namespace pijit { 38 namespace py = pybind11; 39 using NativeFunc = std::function<PyObject *(PyObject *, PyObject *)>; 40 using InlineInfoKey = std::tuple<std::string, std::string, int>; 41 using InlineInfoChain = std::pair<std::string, std::string>; 42 43 // record the inline and stop trace reason and other information for each graph 44 class Tracebackes { 45 public: 46 struct Tracebacke { 47 std::string func_name_; 48 std::string changed_func_; 49 int code_size_; 50 bool is_graph_mode_; 51 }; 52 53 struct InlineInfo { 54 std::string func_name_; 55 std::string inline_name_; 56 std::string root_name_; 57 InlineReason res = InlineReason::kInlineUnknown; 58 int code_size_; 59 int depth; 60 int line; 61 }; 62 Tracebackes() = default; Tracebackes(const std::string & raw_func_name,const std::string & raw_func_info_name,int raw_code_size)63 Tracebackes(const std::string &raw_func_name, const std::string &raw_func_info_name, int raw_code_size) 64 : raw_func_name_(raw_func_name), raw_func_info_name_(raw_func_info_name), raw_code_size_(raw_code_size) {} ~Tracebackes()65 ~Tracebackes() { Clear(); } Clear()66 void Clear() { 67 tbs_.clear(); 68 stop_trace_res_.clear(); 69 inline_infos_.clear(); 70 } 71 raw_func_name()72 std::string raw_func_name() const { return raw_func_name_; } PushTbs(const Tracebacke & tb)73 void PushTbs(const Tracebacke &tb) { tbs_.push_back(tb); } PushStopTraceRes(const std::string & func_name,StopTraceReason res)74 void PushStopTraceRes(const std::string &func_name, StopTraceReason res) { stop_trace_res_.emplace(func_name, res); } 75 void PushInlineInfo(InlineInfo info); 76 void DumpInlineInfo(std::stringstream &os, const std::string &func_name) const; 77 int FindMaxNameLength(const std::list<Tracebacke> &tbs) const; 78 std::string Dump(bool is_all = false) const; 79 std::string DumpSummary() const; GetStopTrace()80 std::string GetStopTrace() { 81 std::string res; 82 for (auto item : stop_trace_res_) { 83 std::string item_str; 84 if (res.size() == 0) { 85 res += std::string("\"") + item.first + "\":" + std::to_string(SizeToInt(item.second)); 86 } else { 87 res += std::string("\"") + item.first + "\":" + std::to_string(SizeToInt(item.second)); 88 } 89 } 90 res = std::string("{") + res + std::string("}"); 91 return res; 92 } 93 94 private: 95 std::string raw_func_name_; 96 std::string raw_func_info_name_; 97 int raw_code_size_; 98 std::list<Tracebacke> tbs_; 99 // <func_name, stop_trace_reason> 100 std::unordered_map<std::string, StopTraceReason> stop_trace_res_; 101 // <root_func_name, InlineInfo> 102 std::map<std::string, std::list<InlineInfo>> inline_infos_; 103 }; 104 105 // shouldn't save this object, must get it by 'getJitCompileResults' 106 // python call free function of this struct while the onwer (pyobject) is freed 107 typedef struct CodeExtra { 108 // sub-graph trees 109 CodeExtra *parent_; 110 111 std::vector<CodeExtra *> children_; 112 113 PyFrameObject *origin_frame_; // frame object 114 115 enum State { 116 NEVER_COMPILE = 0, 117 GRAPH_CANDIDATE, 118 GRAPH_CAPTURED, 119 GRAPH_BUILDING, 120 GRAPH_CALLABLE, 121 } stat; 122 123 // compiler output 124 OptCodePtr code; 125 126 // code cache 127 mindspore::pijit::OptCodeHubPtr codehub; 128 129 std::shared_ptr<Tracebackes> tbs; 130 131 std::shared_ptr<GraphJitConfig> conf; 132 IncCodeCountCodeExtra133 int IncCodeCount() { return compile_count_++; } 134 int compile_count_; 135 int break_count_; 136 PyObject *signature_; 137 } JitCompileResults; 138 139 JitCompileResults *getJitCompileResults(PyObject *code, bool alloc = true); 140 std::vector<py::object> PackArgs(const PyFrameObject *frame); 141 } // namespace pijit 142 } // namespace mindspore 143 144 #endif // MINDSPORE_PI_JIT_COMMON_H 145