Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/runtime_src/core/common/api/kernel_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,14 @@ get_kernel_from_impl(const xrt::kernel_impl* kernel_impl);
xrt::run
get_run_from_impl(const xrt::run_impl*);

// Fill XDP kernel data from a run_impl pointer for profiling hooks
// Fill XDP kernel data from a run_impl pointer for profiling hooks.
// include_state controls whether run_impl->state() is queried; that polls the
// command and is only valid after submission, so callers that run before the
// command is submitted (run_constructor/run_start hooks) must leave it false.
XRT_CORE_COMMON_EXPORT
void
get_xdp_kernel_data(const xrt::run_impl* run_impl, xrt_core::xdp::xrt_kernel_data* data);
get_xdp_kernel_data(const xrt::run_impl* run_impl, xrt_core::xdp::xrt_kernel_data* data,
bool include_state = false);

// Set dtrace control file on a run_impl handle
// This is used by XDP profiling to set the CT file without requiring xrt::run
Expand Down
10 changes: 8 additions & 2 deletions src/runtime_src/core/common/api/xrt_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4580,14 +4580,20 @@ get_run_from_impl(const xrt::run_impl* run_impl)
}

void
get_xdp_kernel_data(const xrt::run_impl* run_impl, xrt_core::xdp::xrt_kernel_data* data)
get_xdp_kernel_data(const xrt::run_impl* run_impl, xrt_core::xdp::xrt_kernel_data* data,
bool include_state)
{
auto kernel = run_impl->get_kernel();
data->uid = run_impl->get_uid();
data->name = kernel->get_name();
data->hwctx = kernel->get_hw_context();
data->mod = kernel->get_module();
data->ert_state = static_cast<int>(run_impl->state());
// run_impl->state() polls the command's ERT packet. That is only valid once
// the command has been submitted; calling it earlier (e.g. from the
// run_constructor / run_start hooks, which fire before submission) throws
// "Cannot poll a command that has not been submitted". Only the run_wait
// hook actually consumes ert_state, so query it only when explicitly asked.
data->ert_state = include_state ? static_cast<int>(run_impl->state()) : 0;
}

void
Expand Down
99 changes: 75 additions & 24 deletions src/runtime_src/core/common/xdp/profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,11 @@
#include "core/common/dlfcn.h"
#include "core/common/module_loader.h"
#include "core/common/message.h"
#include "core/common/utils.h"
#include "core/include/xrt/xrt_kernel.h"

#include <cstring>
#include <functional>
#include <sstream>
#include <cstdlib>

#ifdef _WIN32
#pragma warning( disable : 4996 ) /* Disable warning for getenv */
#endif

// An anonymous namespace to hold a common set of blank functions
// for all modules that don't require specialization and the common
Expand Down Expand Up @@ -64,8 +59,7 @@ namespace {
#if !defined(XDP_CLIENT_BUILD) && !defined(XDP_VE2_BUILD)
static bool is_hw_emulation()
{
static auto xem = std::getenv("XCL_EMULATION_MODE");
static bool hwem = xem ? (std::strcmp(xem, "hw_emu") == 0) : false;
static bool hwem = (xrt_core::utils::getenv("XCL_EMULATION_MODE") == "hw_emu");
return hwem;
}
#endif
Expand All @@ -79,7 +73,7 @@ namespace xrt_core::xdp::core {
void
load_core()
{
if (std::getenv("AMD_XDP_NPU3")) {
if (xrt_core::utils::is_env("AMD_XDP_NPU3")) {
static xrt_core::sdk_loader
xdp_core_loader("xdp_core_npu3",
register_callbacks_empty,
Expand Down Expand Up @@ -114,12 +108,12 @@ load()
{
#if defined(XDP_CLIENT_BUILD) && defined(_WIN32)
static xrt_core::sdk_loader
xdp_aie_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_profile_plugin_npu3" : "xdp_aie_profile_plugin",
xdp_aie_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_profile_plugin_npu3" : "xdp_aie_profile_plugin",
register_callbacks,
warning_callbacks_empty);
#else
static xrt_core::module_loader
xdp_aie_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_profile_plugin_npu3" : "xdp_aie_profile_plugin",
xdp_aie_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_profile_plugin_npu3" : "xdp_aie_profile_plugin",
register_callbacks,
warning_callbacks_empty);
#endif
Expand Down Expand Up @@ -185,7 +179,17 @@ load_xdna()
void
load()
{
load_xdna();
#if defined(XDP_CLIENT_BUILD) && defined(_WIN32)
static xrt_core::sdk_loader
xdp_aie_dtrace_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_dtrace_plugin_npu3" : "xdp_aie_dtrace_plugin",
register_callbacks,
warning_callbacks_empty);
#else
static xrt_core::module_loader
xdp_aie_dtrace_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_dtrace_plugin_npu3" : "xdp_aie_dtrace_plugin",
register_callbacks,
warning_callbacks_empty);
#endif
}

void
Expand All @@ -205,7 +209,14 @@ end_poll(void* handle)
void
run_constructor(xrt::run_impl* run_impl)
{
if (run_constructor_cb) {
if (!run_constructor_cb)
return;

// The dtrace run hooks are best-effort profiling instrumentation. They must
// never affect the run lifecycle: an exception escaping here would propagate
// out of the run_impl constructor and corrupt the caller's run object (e.g.
// leaving FlexMLRT polling a command that was never submitted).
try {
xrt_kernel_data data{};
xrt_core::kernel_int::get_xdp_kernel_data(run_impl, &data);
auto elf_hdl = data.mod ? xrt_core::module_int::get_elf_handle(data.mod) : nullptr;
Expand All @@ -215,31 +226,63 @@ run_constructor(xrt::run_impl* run_impl)
data.name.c_str(),
elf_hdl.get());
}
catch (const std::exception& e) {
xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT",
std::string{"AIE dtrace run_constructor hook failed (ignored): "} + e.what());
}
catch (...) {
xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT",
"AIE dtrace run_constructor hook failed (ignored): unknown exception");
}
}

void
run_start(const xrt::run_impl* run_impl)
{
if (run_start_cb) {
if (!run_start_cb)
return;

try {
xrt_kernel_data data{};
xrt_core::kernel_int::get_xdp_kernel_data(run_impl, &data);
run_start_cb(nullptr, data.hwctx.get_handle().get(),
data.uid,
data.name.c_str());
}
catch (const std::exception& e) {
xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT",
std::string{"AIE dtrace run_start hook failed (ignored): "} + e.what());
}
catch (...) {
xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT",
"AIE dtrace run_start hook failed (ignored): unknown exception");
}
}

void
run_wait(const xrt::run_impl* run_impl)
{
if (run_wait_cb) {
if (!run_wait_cb)
return;

try {
xrt_kernel_data data{};
xrt_core::kernel_int::get_xdp_kernel_data(run_impl, &data);
// run_wait fires after the command has completed, so polling state() here
// is valid and ert_state is the value this hook needs.
xrt_core::kernel_int::get_xdp_kernel_data(run_impl, &data, true);
run_wait_cb(nullptr, data.hwctx.get_handle().get(),
data.uid,
data.name.c_str(),
data.ert_state);
}
catch (const std::exception& e) {
xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT",
std::string{"AIE dtrace run_wait hook failed (ignored): "} + e.what());
}
catch (...) {
xrt_core::message::send(xrt_core::message::severity_level::debug, "XRT",
"AIE dtrace run_wait hook failed (ignored): unknown exception");
}
}

} // end namespace xrt_core::xdp::aie::dtrace
Expand Down Expand Up @@ -267,7 +310,7 @@ void
load()
{
static xrt_core::module_loader
xdp_aie_debug_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_debug_plugin_npu3" : "xdp_aie_debug_plugin",
xdp_aie_debug_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_debug_plugin_npu3" : "xdp_aie_debug_plugin",
register_callbacks,
warning_callbacks_empty);
}
Expand Down Expand Up @@ -355,7 +398,7 @@ void
load()
{
static xrt_core::module_loader
xdp_ml_timeline_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_ml_timeline_plugin_npu3" : "xdp_ml_timeline_plugin",
xdp_ml_timeline_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_ml_timeline_plugin_npu3" : "xdp_ml_timeline_plugin",
register_callbacks,
warning_callbacks_empty);
}
Expand Down Expand Up @@ -443,12 +486,12 @@ load()
{
#if defined(XDP_CLIENT_BUILD) && defined(_WIN32)
static xrt_core::sdk_loader
xdp_aie_trace_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_trace_plugin_npu3" : "xdp_aie_trace_plugin",
xdp_aie_trace_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_trace_plugin_npu3" : "xdp_aie_trace_plugin",
register_callbacks,
warning_callbacks_empty);
#else
static xrt_core::module_loader
xdp_aie_trace_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_trace_plugin_npu3" : "xdp_aie_trace_plugin",
xdp_aie_trace_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_trace_plugin_npu3" : "xdp_aie_trace_plugin",
register_callbacks,
warning_callbacks_empty);
#endif
Expand Down Expand Up @@ -502,12 +545,12 @@ load()
{
#if defined(XDP_CLIENT_BUILD) && defined(_WIN32)
static xrt_core::sdk_loader
xdp_aie_halt_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_halt_plugin_npu3" : "xdp_aie_halt_plugin",
xdp_aie_halt_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_halt_plugin_npu3" : "xdp_aie_halt_plugin",
register_callbacks,
warning_callbacks_empty);
#else
static xrt_core::module_loader
xdp_aie_halt_loader(std::getenv("AMD_XDP_NPU3") ? "xdp_aie_halt_plugin_npu3" : "xdp_aie_halt_plugin",
xdp_aie_halt_loader(xrt_core::utils::is_env("AMD_XDP_NPU3") ? "xdp_aie_halt_plugin_npu3" : "xdp_aie_halt_plugin",
register_callbacks,
warning_callbacks_empty);
#endif
Expand Down Expand Up @@ -687,6 +730,14 @@ update_device(void* handle, bool hw_context_flow)
"Failed to setup for AIE Debug. Caught exception ",
handle);

load_once_and_update(xrt_core::config::get_aie_dtrace,
xrt_core::xdp::aie::dtrace::load,
xrt_core::xdp::aie::dtrace::update_device,
"Failed to load AIE dtrace library. Caught exception ",
"Failed to setup for AIE dtrace. Caught exception ",
handle,
hw_context_flow);

#elif defined(XDP_VE2_BUILD)

load_once_and_update(xrt_core::config::get_ml_timeline,
Expand Down Expand Up @@ -773,7 +824,7 @@ update_device(void* handle, bool hw_context_flow)
load_once_and_update(
[]() {
return xrt_core::config::get_pl_deadlock_detection() &&
nullptr == std::getenv("XCL_EMULATION_MODE");
!xrt_core::utils::is_env("XCL_EMULATION_MODE");
},
xrt_core::xdp::pl_deadlock::load,
xrt_core::xdp::pl_deadlock::update_device,
Expand Down Expand Up @@ -875,7 +926,7 @@ finish_flush_device(void* handle)
#else

if (xrt_core::config::get_pl_deadlock_detection()
&& nullptr == std::getenv("XCL_EMULATION_MODE")) {
&& !xrt_core::utils::is_env("XCL_EMULATION_MODE")) {
xrt_core::xdp::pl_deadlock::finish_flush_device(handle);
}
if (xrt_core::config::get_aie_trace())
Expand Down
Loading