Skip to content

Commit a4eb8f2

Browse files
[VitisAI] Add profiler interface for vitisai (#23032)
### 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.
1 parent 2ff66b8 commit a4eb8f2

File tree

6 files changed

+106
-0
lines changed

6 files changed

+106
-0
lines changed

onnxruntime/core/providers/vitisai/imp/global_api.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ struct OrtVitisAIEpAPI {
5858
const std::vector<std::unique_ptr<vaip_core::ExecutionProvider>>& eps,
5959
const char* const* keys,
6060
const char* const* values, size_t kv_len) = nullptr;
61+
void (*profiler_collect)(
62+
std::vector<EventInfo>& api_events,
63+
std::vector<EventInfo>& kernel_events);
6164
void Ensure() {
6265
if (handle_)
6366
return;
@@ -81,6 +84,7 @@ struct OrtVitisAIEpAPI {
8184
}
8285
std::ignore = env.GetSymbolFromLibrary(handle_, "vaip_get_version",
8386
(void**)&vaip_get_version);
87+
std::ignore = env.GetSymbolFromLibrary(handle_, "profiler_collect", (void**)&profiler_collect);
8488
ORT_THROW_IF_ERROR(env.GetSymbolFromLibrary(handle_, "create_ep_context_nodes", (void**)&create_ep_context_nodes));
8589
ORT_THROW_IF_ERROR(env.GetSymbolFromLibrary(handle_, "vitisai_ep_on_run_start", (void**)&vitisai_ep_on_run_start));
8690
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;
97101
std::shared_ptr<KernelRegistry> get_kernel_registry_vitisaiep() { return s_kernel_registry_vitisaiep; }
98102
const std::vector<OrtCustomOpDomain*>& get_domains_vitisaiep() { return s_domains_vitisaiep; }
99103

104+
void profiler_collect(
105+
std::vector<EventInfo>& api_events,
106+
std::vector<EventInfo>& kernel_events) {
107+
if (s_library_vitisaiep.profiler_collect) {
108+
s_library_vitisaiep.profiler_collect(api_events, kernel_events);
109+
}
110+
}
111+
100112
vaip_core::DllSafe<std::vector<std::unique_ptr<vaip_core::ExecutionProvider>>> compile_onnx_model(
101113
const onnxruntime::GraphViewer& graph_viewer, const logging::Logger& logger, const ProviderOptions& options) {
102114
auto model_path = graph_viewer.ModelPath().string();

onnxruntime/core/providers/vitisai/include/vaip/global_api.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,18 @@ int vitisai_ep_set_ep_dynamic_options(
2424
const std::vector<std::unique_ptr<vaip_core::ExecutionProvider>>& eps,
2525
const char* const* keys,
2626
const char* const* values, size_t kv_len);
27+
/**
28+
* Replace EventRecord with std::tuple<std::string, int ,int, long long, long long>,
29+
* because EventRecord is defined in profiler_common.h which is used inside onnxruntime.
30+
* However, profiler_collect function will call vitis ep which can't include profiler_common.h.
31+
*/
32+
using EventInfo = std::tuple<
33+
std::string, // name
34+
int, // pid
35+
int, // tid
36+
long long, // timestamp
37+
long long // duration
38+
>;
39+
void profiler_collect(
40+
std::vector<EventInfo>& api_events,
41+
std::vector<EventInfo>& kernel_events);

onnxruntime/core/providers/vitisai/vitisai_execution_provider.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
22
// Licensed under the MIT License.
33
#include "vitisai_execution_provider.h"
4+
#include "vitisai_profiler.h"
45

56
// Standard headers/libs.
67
#include <cassert>
@@ -135,4 +136,8 @@ common::Status VitisAIExecutionProvider::SetEpDynamicOptions(gsl::span<const cha
135136
}
136137
return Status::OK();
137138
}
139+
140+
std::unique_ptr<profiling::EpProfiler> VitisAIExecutionProvider::GetProfiler() {
141+
return std::make_unique<profiling::VitisaiProfiler>();
142+
}
138143
} // namespace onnxruntime

onnxruntime/core/providers/vitisai/vitisai_execution_provider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class VitisAIExecutionProvider : public IExecutionProvider {
3636
std::vector<NodeComputeInfo>& node_compute_funcs) override;
3737
std::shared_ptr<KernelRegistry> GetKernelRegistry() const override;
3838

39+
std::unique_ptr<profiling::EpProfiler> GetProfiler() override;
40+
3941
// This method is called after both `GetComputeCapabilityOps()` and `Compile()`.
4042
// This timing is required to work with both compliation-based EPs and non-compilation-based EPs.
4143
const InlinedVector<const Node*> GetEpContextNodes() const override;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "vitisai_profiler.h"
5+
6+
namespace onnxruntime {
7+
namespace profiling {
8+
9+
#if defined(USE_VITISAI)
10+
11+
bool VitisaiProfiler::StartProfiling(TimePoint tp) {
12+
return true;
13+
}
14+
15+
void VitisaiProfiler::EndProfiling(TimePoint tp, Events& events) {
16+
auto time_point =
17+
std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch()).count();
18+
19+
std::vector<EventInfo> api_events;
20+
std::vector<EventInfo> kernel_events;
21+
profiler_collect(api_events, kernel_events);
22+
23+
std::unordered_map<std::string, std::string> event_args;
24+
25+
for (auto& a : api_events) {
26+
events.emplace_back(EventCategory::API_EVENT,
27+
std::get<1>(a), // pid
28+
std::get<2>(a), // tid
29+
std::get<0>(a), // name
30+
std::get<3>(a) - time_point, // timestamp
31+
std::get<4>(a), // duration
32+
event_args);
33+
}
34+
35+
for (auto& k : kernel_events) {
36+
events.emplace_back(EventCategory::KERNEL_EVENT,
37+
std::get<1>(k),
38+
std::get<2>(k),
39+
std::get<0>(k),
40+
std::get<3>(k) - time_point,
41+
std::get<4>(k),
42+
event_args);
43+
}
44+
}
45+
46+
#endif
47+
48+
} // namespace profiling
49+
} // namespace onnxruntime
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "core/providers/vitisai/include/vaip/global_api.h"
5+
6+
namespace onnxruntime {
7+
namespace profiling {
8+
9+
#if defined(USE_VITISAI)
10+
class VitisaiProfiler final : public EpProfiler {
11+
public:
12+
VitisaiProfiler() = default;
13+
ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(VitisaiProfiler);
14+
~VitisaiProfiler() {}
15+
bool StartProfiling(TimePoint) override;
16+
void EndProfiling(TimePoint, Events&) override;
17+
void Start(uint64_t) override{};
18+
void Stop(uint64_t) override{};
19+
};
20+
#endif
21+
22+
} // namespace profiling
23+
} // namespace onnxruntime

0 commit comments

Comments
 (0)