diff --git a/onnxruntime/core/providers/vitisai/imp/global_api.cc b/onnxruntime/core/providers/vitisai/imp/global_api.cc index 3e802e5a77203..fbfd1c1af8fa5 100644 --- a/onnxruntime/core/providers/vitisai/imp/global_api.cc +++ b/onnxruntime/core/providers/vitisai/imp/global_api.cc @@ -58,6 +58,9 @@ struct OrtVitisAIEpAPI { const std::vector>& eps, const char* const* keys, const char* const* values, size_t kv_len) = nullptr; + void (*profiler_collect)( + std::vector& api_events, + std::vector& kernel_events); void Ensure() { if (handle_) return; @@ -81,6 +84,7 @@ struct OrtVitisAIEpAPI { } std::ignore = env.GetSymbolFromLibrary(handle_, "vaip_get_version", (void**)&vaip_get_version); + std::ignore = env.GetSymbolFromLibrary(handle_, "profiler_collect", (void**)&profiler_collect); ORT_THROW_IF_ERROR(env.GetSymbolFromLibrary(handle_, "create_ep_context_nodes", (void**)&create_ep_context_nodes)); ORT_THROW_IF_ERROR(env.GetSymbolFromLibrary(handle_, "vitisai_ep_on_run_start", (void**)&vitisai_ep_on_run_start)); ORT_THROW_IF_ERROR(env.GetSymbolFromLibrary(handle_, "vitisai_ep_set_ep_dynamic_options", (void**)&vitisai_ep_set_ep_dynamic_options)); @@ -97,6 +101,14 @@ static vaip_core::OrtApiForVaip the_global_api; std::shared_ptr get_kernel_registry_vitisaiep() { return s_kernel_registry_vitisaiep; } const std::vector& get_domains_vitisaiep() { return s_domains_vitisaiep; } +void profiler_collect( + std::vector& api_events, + std::vector& kernel_events) { + if (s_library_vitisaiep.profiler_collect) { + s_library_vitisaiep.profiler_collect(api_events, kernel_events); + } +} + vaip_core::DllSafe>> compile_onnx_model( const onnxruntime::GraphViewer& graph_viewer, const logging::Logger& logger, const ProviderOptions& options) { auto model_path = graph_viewer.ModelPath().string(); diff --git a/onnxruntime/core/providers/vitisai/include/vaip/global_api.h b/onnxruntime/core/providers/vitisai/include/vaip/global_api.h index b0353bd6adae9..c85284bff4639 100644 --- a/onnxruntime/core/providers/vitisai/include/vaip/global_api.h +++ b/onnxruntime/core/providers/vitisai/include/vaip/global_api.h @@ -24,3 +24,18 @@ int vitisai_ep_set_ep_dynamic_options( const std::vector>& eps, const char* const* keys, const char* const* values, size_t kv_len); +/** + * Replace EventRecord with std::tuple, + * because EventRecord is defined in profiler_common.h which is used inside onnxruntime. + * However, profiler_collect function will call vitis ep which can't include profiler_common.h. + */ +using EventInfo = std::tuple< + std::string, //name + int, //pid + int, //tid + long long, //timestamp + long long //duration +>; +void profiler_collect( + std::vector& api_events, + std::vector& kernel_events); diff --git a/onnxruntime/core/providers/vitisai/vitisai_execution_provider.cc b/onnxruntime/core/providers/vitisai/vitisai_execution_provider.cc index 023a954c83d70..3a99f56bb732a 100644 --- a/onnxruntime/core/providers/vitisai/vitisai_execution_provider.cc +++ b/onnxruntime/core/providers/vitisai/vitisai_execution_provider.cc @@ -1,6 +1,7 @@ // Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. // Licensed under the MIT License. #include "vitisai_execution_provider.h" +#include "vitisai_profiler.h" // Standard headers/libs. #include @@ -135,4 +136,8 @@ common::Status VitisAIExecutionProvider::SetEpDynamicOptions(gsl::span VitisAIExecutionProvider::GetProfiler() { + return std::make_unique(); +} } // namespace onnxruntime diff --git a/onnxruntime/core/providers/vitisai/vitisai_execution_provider.h b/onnxruntime/core/providers/vitisai/vitisai_execution_provider.h index 9864a40bd1d3b..dff49f7828adc 100644 --- a/onnxruntime/core/providers/vitisai/vitisai_execution_provider.h +++ b/onnxruntime/core/providers/vitisai/vitisai_execution_provider.h @@ -36,6 +36,8 @@ class VitisAIExecutionProvider : public IExecutionProvider { std::vector& node_compute_funcs) override; std::shared_ptr GetKernelRegistry() const override; + std::unique_ptr GetProfiler() override; + // This method is called after both `GetComputeCapabilityOps()` and `Compile()`. // This timing is required to work with both compliation-based EPs and non-compilation-based EPs. const InlinedVector GetEpContextNodes() const override; diff --git a/onnxruntime/core/providers/vitisai/vitisai_profiler.cc b/onnxruntime/core/providers/vitisai/vitisai_profiler.cc new file mode 100644 index 0000000000000..253c20da8a351 --- /dev/null +++ b/onnxruntime/core/providers/vitisai/vitisai_profiler.cc @@ -0,0 +1,50 @@ +// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Licensed under the MIT License. + +#include "vitisai_profiler.h" + +namespace onnxruntime { +namespace profiling { + +#if defined(USE_VITISAI) + +bool VitisaiProfiler::StartProfiling(TimePoint tp) { + return true; +} + +void VitisaiProfiler::EndProfiling(TimePoint tp, Events& events) { + + auto time_point = \ + std::chrono::duration_cast(tp.time_since_epoch()).count(); + + std::vector api_events; + std::vector kernel_events; + profiler_collect(api_events, kernel_events); + + std::unordered_map event_args; + + for (auto& a : api_events) { + events.emplace_back(EventCategory::API_EVENT, + std::get<1>(a), //pid + std::get<2>(a), //tid + std::get<0>(a), //name + std::get<3>(a) - time_point, //timestamp + std::get<4>(a), //duration + event_args); + } + + for (auto& k : kernel_events) { + events.emplace_back(EventCategory::KERNEL_EVENT, + std::get<1>(k), + std::get<2>(k), + std::get<0>(k), + std::get<3>(k) - time_point, + std::get<4>(k), + event_args); + } +} + +#endif + +} // namespace profiling +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/vitisai/vitisai_profiler.h b/onnxruntime/core/providers/vitisai/vitisai_profiler.h new file mode 100644 index 0000000000000..059e1a7d86e9a --- /dev/null +++ b/onnxruntime/core/providers/vitisai/vitisai_profiler.h @@ -0,0 +1,23 @@ +// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Licensed under the MIT License. + +#include "core/providers/vitisai/include/vaip/global_api.h" + +namespace onnxruntime { +namespace profiling { + +#if defined(USE_VITISAI) +class VitisaiProfiler final: public EpProfiler { + public: + VitisaiProfiler() = default; + ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(VitisaiProfiler); + ~VitisaiProfiler() {} + bool StartProfiling(TimePoint) override; + void EndProfiling(TimePoint, Events&) override; + void Start(uint64_t) override{}; + void Stop(uint64_t) override{}; +}; +#endif + +} // namespace profiling +} // namespace onnxruntime