#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace py = pybind11; namespace torch::profiler::impl { namespace { enum CallType { PyCall = 0, PyModuleCall, PyCCall, PyOptimizerCall }; static constexpr size_t CallTypeSize = 4; using no_ephemeral_t = std::tuple<>; static constexpr uint64_t NoTID = std::numeric_limits::max(); // ============================================================================ // == Miscellaneous structs and utils ========================================= // ============================================================================ struct CodeLocation { CodeLocation() = default; explicit CodeLocation(PyFrameObject* frame) : line_number_{PyFrame_GetLineNumber(frame)} { auto code = THPCodeObjectPtr(PyFrame_GetCode(frame)); filename_ = THPUtils_unpackStringView(code->co_filename).data(); name_ = THPUtils_unpackStringView(code->co_name).data(); } bool operator==(const CodeLocation& other) const { return filename_ == other.filename_ && name_ == other.name_ && line_number_ == other.line_number_; } const char* filename_{nullptr}; const char* name_{nullptr}; int line_number_{0}; }; template PyCodeObject* getCode(); template <> PyCodeObject* getCode() { static auto module_call_code = []() { pybind11::gil_scoped_acquire gil; auto res = py::module::import("torch.nn") .attr("Module") .attr("__call__") .attr("__code__") .ptr(); TORCH_INTERNAL_ASSERT(PyCode_Check(res)); return (PyCodeObject*)res; }(); return module_call_code; } template <> PyCodeObject* getCode() { static auto optimizer_step_code = []() { pybind11::gil_scoped_acquire gil; auto res = py::module::import("torch.optim") .attr("Optimizer") .attr("_optimizer_step_code") .attr("__code__") .ptr(); TORCH_INTERNAL_ASSERT(PyCode_Check(res)); return (PyCodeObject*)res; }(); return optimizer_step_code; } } // namespace } // namespace torch::profiler::impl template <> struct std::hash { size_t operator()(const torch::profiler::impl::CodeLocation& x) { return c10::get_hash(x.filename_, x.name_, x.line_number_); } }; namespace torch::profiler::impl { namespace { // ============================================================================ // == CallTypeHelper: Tools for generic programming on specializations. ======= // ============================================================================ template