Skip to content

Commit

Permalink
[VitisAI] Add profiler interface for vitisai (#23032)
Browse files Browse the repository at this point in the history
### Description
<!-- Describe your changes. -->
Add common interfaces for vitis ep profiler.


### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
Vitis ep can collect and record api and kernel timestamps in file when
onnxruntime '-p' is enabled.
  • Loading branch information
tianfang-fafafa authored Dec 16, 2024
1 parent 2ff66b8 commit a4eb8f2
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 0 deletions.
12 changes: 12 additions & 0 deletions onnxruntime/core/providers/vitisai/imp/global_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ struct OrtVitisAIEpAPI {
const std::vector<std::unique_ptr<vaip_core::ExecutionProvider>>& eps,
const char* const* keys,
const char* const* values, size_t kv_len) = nullptr;
void (*profiler_collect)(
std::vector<EventInfo>& api_events,
std::vector<EventInfo>& kernel_events);
void Ensure() {
if (handle_)
return;
Expand All @@ -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));
Expand All @@ -97,6 +101,14 @@ static vaip_core::OrtApiForVaip the_global_api;
std::shared_ptr<KernelRegistry> get_kernel_registry_vitisaiep() { return s_kernel_registry_vitisaiep; }
const std::vector<OrtCustomOpDomain*>& get_domains_vitisaiep() { return s_domains_vitisaiep; }

void profiler_collect(
std::vector<EventInfo>& api_events,
std::vector<EventInfo>& kernel_events) {
if (s_library_vitisaiep.profiler_collect) {
s_library_vitisaiep.profiler_collect(api_events, kernel_events);
}
}

vaip_core::DllSafe<std::vector<std::unique_ptr<vaip_core::ExecutionProvider>>> compile_onnx_model(
const onnxruntime::GraphViewer& graph_viewer, const logging::Logger& logger, const ProviderOptions& options) {
auto model_path = graph_viewer.ModelPath().string();
Expand Down
15 changes: 15 additions & 0 deletions onnxruntime/core/providers/vitisai/include/vaip/global_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ int vitisai_ep_set_ep_dynamic_options(
const std::vector<std::unique_ptr<vaip_core::ExecutionProvider>>& eps,
const char* const* keys,
const char* const* values, size_t kv_len);
/**
* Replace EventRecord with std::tuple<std::string, int ,int, long long, long long>,
* 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<EventInfo>& api_events,
std::vector<EventInfo>& kernel_events);
Original file line number Diff line number Diff line change
@@ -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 <cassert>
Expand Down Expand Up @@ -135,4 +136,8 @@ common::Status VitisAIExecutionProvider::SetEpDynamicOptions(gsl::span<const cha
}
return Status::OK();
}

std::unique_ptr<profiling::EpProfiler> VitisAIExecutionProvider::GetProfiler() {
return std::make_unique<profiling::VitisaiProfiler>();
}
} // namespace onnxruntime
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class VitisAIExecutionProvider : public IExecutionProvider {
std::vector<NodeComputeInfo>& node_compute_funcs) override;
std::shared_ptr<KernelRegistry> GetKernelRegistry() const override;

std::unique_ptr<profiling::EpProfiler> 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<const Node*> GetEpContextNodes() const override;
Expand Down
49 changes: 49 additions & 0 deletions onnxruntime/core/providers/vitisai/vitisai_profiler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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<std::chrono::microseconds>(tp.time_since_epoch()).count();

std::vector<EventInfo> api_events;
std::vector<EventInfo> kernel_events;
profiler_collect(api_events, kernel_events);

std::unordered_map<std::string, std::string> 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
23 changes: 23 additions & 0 deletions onnxruntime/core/providers/vitisai/vitisai_profiler.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit a4eb8f2

Please sign in to comment.