Skip to content
Closed
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
1 change: 1 addition & 0 deletions libkineto/libkineto_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def get_libkineto_xpupti_srcs(with_api = True):
"src/plugin/xpupti/XpuptiActivityApi.cpp",
"src/plugin/xpupti/XpuptiActivityProfiler.cpp",
"src/plugin/xpupti/XpuptiActivityHandlers.cpp",
"src/plugin/xpupti/XpuptiScopeProfilerConfig.cpp",
] + (get_libkineto_cpu_only_srcs(with_api))

def get_libkineto_aiupti_srcs(with_api = True):
Expand Down
3 changes: 3 additions & 0 deletions libkineto/src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#ifdef HAS_XPUPTI
#include "plugin/xpupti/XpuptiActivityApi.h"
#include "plugin/xpupti/XpuptiActivityProfiler.h"
#include "plugin/xpupti/XpuptiScopeProfilerConfig.h"
#endif
#ifdef HAS_AIUPTI
#include "plugin/aiupti/AiuptiActivityApi.h"
Expand Down Expand Up @@ -193,6 +194,8 @@ void libkineto_init(bool cpuOnly, bool logOnError) {
throw std::runtime_error(errPrefixMsg);
#endif
}

XpuptiScopeProfilerConfig::registerFactory();
return std::make_unique<XPUActivityProfiler>();
});
#endif // HAS_XPUPTI
Expand Down
69 changes: 69 additions & 0 deletions libkineto/src/plugin/xpupti/XpuptiScopeProfilerConfig.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "XpuptiScopeProfilerConfig.h"

#include <Logger.h>

#include <fmt/core.h>
#include <fmt/ostream.h>
#include <fmt/ranges.h>

namespace KINETO_NAMESPACE {

// number of scopes affect the size of counter data binary used by
// the XPUPTI Profiler. these defaults can be tuned
constexpr int KMaxAutoScopes = 1500; // supports 1500 kernels
constexpr int KMaxUserScopes = 10; // enable upto 10 sub regions marked by user

bool XpuptiScopeProfilerConfig::handleOption(
const std::string& name,
std::string& val) {
VLOG(0) << " handling : " << name << " = " << val;
// Xpupti Scope based Profiler configuration
using namespace std::literals::string_view_literals;
if (name == "XPUPTI_PROFILER_METRICS"sv) {
activitiesXpuptiMetrics_ = splitAndTrim(val, ',');
} else if (name == "XPUPTI_PROFILER_ENABLE_PER_KERNEL"sv) {
xpuptiProfilerPerKernel_ = toBool(val);
} else if (name == "XPUPTI_PROFILER_MAX_SCOPES"sv) {
Comment thread
moksiuc marked this conversation as resolved.
xpuptiProfilerMaxScopes_ = toInt64(val);
} else {
return false;
}
return true;
}

void XpuptiScopeProfilerConfig::setDefaults() {
if (activitiesXpuptiMetrics_.size() > 0 && xpuptiProfilerMaxScopes_ == 0) {
xpuptiProfilerMaxScopes_ =
xpuptiProfilerPerKernel_ ? KMaxAutoScopes : KMaxUserScopes;
}
}

void XpuptiScopeProfilerConfig::printActivityProfilerConfig(
std::ostream& s) const {
if (activitiesXpuptiMetrics_.size() > 0) {
fmt::print(
s,
"Xpupti Profiler metrics : {}\n"
"Xpupti Profiler measure per kernel : {}\n"
"Xpupti Profiler max scopes : {}\n",
fmt::join(activitiesXpuptiMetrics_, ", "),
xpuptiProfilerPerKernel_,
xpuptiProfilerMaxScopes_);
}
}

void XpuptiScopeProfilerConfig::registerFactory() {
Config::addConfigFactory(kXpuptiProfilerConfigName, [](Config& cfg) {
return new XpuptiScopeProfilerConfig(cfg);
});
}

} // namespace KINETO_NAMESPACE
91 changes: 91 additions & 0 deletions libkineto/src/plugin/xpupti/XpuptiScopeProfilerConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include "Config.h"

#include <chrono>
#include <vector>

namespace KINETO_NAMESPACE {

constexpr char kXpuptiProfilerConfigName[] = "xpupti_scope_profiler";

class XpuptiScopeProfilerConfig : public AbstractConfig {
public:
bool handleOption(const std::string& name, std::string& val) override;

void validate(
const std::chrono::time_point<std::chrono::system_clock>&
fallbackProfileStartTime) override {}

static XpuptiScopeProfilerConfig& get(const Config& cfg) {
return dynamic_cast<XpuptiScopeProfilerConfig&>(
cfg.feature(kXpuptiProfilerConfigName));
}

Config& parent() const {
return *parent_;
}

std::vector<std::string> activitiesXpuptiMetrics() const {
return activitiesXpuptiMetrics_;
}

bool xpuptiProfilerPerKernel() const {
return xpuptiProfilerPerKernel_;
}

int64_t xpuptiProfilerMaxScopes() const {
return xpuptiProfilerMaxScopes_;
}

void setSignalDefaults() override {
setDefaults();
}

void setClientDefaults() override {
setDefaults();
}

void printActivityProfilerConfig(std::ostream& s) const override;
void setActivityDependentConfig() override {}
static void registerFactory();

protected:
AbstractConfig* cloneDerived(AbstractConfig& parent) const override {
XpuptiScopeProfilerConfig* clone = new XpuptiScopeProfilerConfig(*this);
clone->parent_ = dynamic_cast<Config*>(&parent);
return clone;
}

private:
XpuptiScopeProfilerConfig() = delete;
explicit XpuptiScopeProfilerConfig(Config& parent) : parent_(&parent) {}
explicit XpuptiScopeProfilerConfig(const XpuptiScopeProfilerConfig& other) =
default;

// some defaults will depend on other configuration
void setDefaults();

// Associated Config object
Config* parent_;

// Counter metrics exposed via XPUPTI Profiler API
std::vector<std::string> activitiesXpuptiMetrics_;

// Collect profiler metrics per kernel - autoscope made
bool xpuptiProfilerPerKernel_{false};

// max number of scopes to configure the profiler for.
// this has to be set before hand to reserve space for the output
int64_t xpuptiProfilerMaxScopes_ = 0;
};

} // namespace KINETO_NAMESPACE
1 change: 1 addition & 0 deletions libkineto/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ endif()

if(DEFINED LIBKINETO_NOXPUPTI AND NOT LIBKINETO_NOXPUPTI)
set(XPU_XPUPTI_LIBRARY ${PTI_LIBRARY} ${SYCL_LIBRARY})
add_subdirectory(xpupti)
else()
set(XPU_XPUPTI_LIBRARY "")
endif()
Expand Down
20 changes: 20 additions & 0 deletions libkineto/test/xpupti/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

set(CMAKE_CXX_STANDARD 17)

set(LINK_LIBRARIES
gtest_main
kineto_base
kineto_api
$<BUILD_INTERFACE:fmt::fmt-header-only>
${SYCL_LIBRARY}
${PTI_LIBRARY}
)

add_executable(XpuptiScopeProfilerConfigTest XpuptiScopeProfilerConfigTest.cpp)
target_link_libraries(XpuptiScopeProfilerConfigTest PRIVATE ${LINK_LIBRARIES})
gtest_discover_tests(XpuptiScopeProfilerConfigTest)
71 changes: 71 additions & 0 deletions libkineto/test/xpupti/XpuptiScopeProfilerConfigTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "src/plugin/xpupti/XpuptiScopeProfilerConfig.h"
#include "include/Config.h"

#include <fmt/core.h>
#include <fmt/ranges.h>

#include <gtest/gtest.h>

namespace KN = KINETO_NAMESPACE;

class XpuptiScopeProfilerConfigTest : public ::testing::Test {
protected:
void SetUp() override {
KN::XpuptiScopeProfilerConfig::registerFactory();
}
};

TEST_F(XpuptiScopeProfilerConfigTest, ConfigureProfiler) {
KN::Config cfg;
std::vector<std::string> metrics = {
"metric1",
"metric2",
"metric3",
};
auto metricsConfigStr =
fmt::format("XPUPTI_PROFILER_METRICS = {}", fmt::join(metrics, ","));

EXPECT_TRUE(cfg.parse(metricsConfigStr));
EXPECT_TRUE(cfg.parse("XPUPTI_PROFILER_ENABLE_PER_KERNEL = true"));
EXPECT_TRUE(cfg.parse("XPUPTI_PROFILER_MAX_SCOPES = 314159"));

const KN::XpuptiScopeProfilerConfig& xpupti_cfg =
KN::XpuptiScopeProfilerConfig::get(cfg);

EXPECT_EQ(xpupti_cfg.activitiesXpuptiMetrics(), metrics);
EXPECT_EQ(xpupti_cfg.xpuptiProfilerPerKernel(), true);
EXPECT_EQ(xpupti_cfg.xpuptiProfilerMaxScopes(), 314159);
}

TEST_F(XpuptiScopeProfilerConfigTest, ScopesDefaults) {
KN::Config cfg, cfg_auto;

// do not set max scopes in config, check defaults are sane
EXPECT_TRUE(cfg.parse("XPUPTI_PROFILER_METRICS = metric1"));
EXPECT_TRUE(cfg.parse("XPUPTI_PROFILER_ENABLE_PER_KERNEL = false"));

cfg.setSignalDefaults();

EXPECT_TRUE(cfg_auto.parse("XPUPTI_PROFILER_METRICS = metric2"));
EXPECT_TRUE(cfg_auto.parse("XPUPTI_PROFILER_ENABLE_PER_KERNEL = true"));

cfg_auto.setClientDefaults();

int user_scopes, auto_scopes;

user_scopes =
KN::XpuptiScopeProfilerConfig::get(cfg).xpuptiProfilerMaxScopes();
auto_scopes =
KN::XpuptiScopeProfilerConfig::get(cfg_auto).xpuptiProfilerMaxScopes();

EXPECT_EQ(user_scopes, 10);
EXPECT_EQ(auto_scopes, 1500);
}