Skip to content

[SYCL] Emit program build logs for warning levels >= 2 #5319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 4, 2022
Merged
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 sycl/source/detail/config.def
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ CONFIG(SYCL_CACHE_MAX_DEVICE_IMAGE_SIZE, 16, __SYCL_CACHE_MAX_DEVICE_IMAGE_SIZE)
CONFIG(INTEL_ENABLE_OFFLOAD_ANNOTATIONS, 1, __SYCL_INTEL_ENABLE_OFFLOAD_ANNOTATIONS)
CONFIG(SYCL_ENABLE_DEFAULT_CONTEXTS, 1, __SYCL_ENABLE_DEFAULT_CONTEXTS)
CONFIG(SYCL_QUEUE_THREAD_POOL_SIZE, 4, __SYCL_QUEUE_THREAD_POOL_SIZE)
CONFIG(SYCL_RT_WARNING_LEVEL, 4, __SYCL_RT_WARNING_LEVEL)
24 changes: 24 additions & 0 deletions sycl/source/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,30 @@ template <> class SYCLConfig<SYCL_PI_TRACE> {
}
};

template <> class SYCLConfig<SYCL_RT_WARNING_LEVEL> {
using BaseT = SYCLConfigBase<SYCL_RT_WARNING_LEVEL>;

public:
static unsigned int get() { return getCachedValue(); }

static void reset() { (void)getCachedValue(true); }

private:
static unsigned int getCachedValue(bool ResetCache = false) {
const auto Parser = []() {
const char *ValStr = BaseT::getRawValue();
int SignedLevel = ValStr ? std::atoi(ValStr) : 0;
return SignedLevel >= 0 ? SignedLevel : 0;
};

static unsigned int Level = Parser();
if (ResetCache)
Level = Parser();

return Level;
}
};

template <> class SYCLConfig<SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE> {
using BaseT = SYCLConfigBase<SYCL_PARALLEL_FOR_RANGE_ROUNDING_TRACE>;

Expand Down
9 changes: 9 additions & 0 deletions sycl/source/detail/kernel_program_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ class KernelProgramCache {
MKernelFastCache.emplace(CacheKey, CacheVal);
}

/// Clears cache state.
///
/// This member function should only be used in unit tests.
void reset() {
MCachedPrograms = ProgramCacheT{};
MKernelsPerProgramCache = KernelCacheT{};
MKernelFastCache = KernelFastCacheT{};
}

private:
std::mutex MProgramCacheMutex;
std::mutex MKernelsPerProgramCacheMutex;
Expand Down
15 changes: 15 additions & 0 deletions sycl/source/detail/program_manager/program_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,17 @@ std::pair<RT::PiProgram, bool> ProgramManager::getOrCreatePIProgram(
return {NativePrg, BinProg.size()};
}

/// Emits information about built programs if the appropriate contitions are
/// met, namely when SYCL_RT_WARNING_LEVEL is greater than or equal to 2.
static void emitBuiltProgramInfo(const pi_program &Prog,
const ContextImplPtr &Context) {
if (SYCLConfig<SYCL_RT_WARNING_LEVEL>::get() >= 2) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: 2 got to have a name here. Suggest add naming in separate patch when we're to add some behaviour for another value e.g. 1.

std::string ProgramBuildLog =
ProgramManager::getProgramBuildLog(Prog, Context);
std::clog << ProgramBuildLog << std::endl;
}
}

RT::PiProgram ProgramManager::getBuiltPIProgram(
OSModuleHandle M, const ContextImplPtr &ContextImpl,
const DeviceImplPtr &DeviceImpl, const std::string &KernelName,
Expand Down Expand Up @@ -511,6 +522,8 @@ RT::PiProgram ProgramManager::getBuiltPIProgram(
getRawSyclObjImpl(Device)->getHandleRef(),
ContextImpl->getCachedLibPrograms(), DeviceLibReqMask);

emitBuiltProgramInfo(BuiltProgram.get(), ContextImpl);

{
std::lock_guard<std::mutex> Lock(MNativeProgramsMutex);
NativePrograms[BuiltProgram.get()] = &Img;
Expand Down Expand Up @@ -1785,6 +1798,8 @@ device_image_plain ProgramManager::build(const device_image_plain &DeviceImage,
getRawSyclObjImpl(Devs[0])->getHandleRef(),
ContextImpl->getCachedLibPrograms(), DeviceLibReqMask);

emitBuiltProgramInfo(BuiltProgram.get(), ContextImpl);

{
std::lock_guard<std::mutex> Lock(MNativeProgramsMutex);
NativePrograms[BuiltProgram.get()] = &Img;
Expand Down
24 changes: 18 additions & 6 deletions sycl/unittests/helpers/CommonRedefinitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,31 @@ inline pi_result redefinedProgramGetInfoCommon(pi_program program,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret) {
if (param_value_size_ret) {
*param_value_size_ret = sizeof(size_t);
}
if (param_name == PI_PROGRAM_INFO_NUM_DEVICES) {
auto value = reinterpret_cast<unsigned int *>(param_value);
*value = 1;
if (param_value) {
auto value = reinterpret_cast<unsigned int *>(param_value);
*value = 1;
}
}

if (param_name == PI_PROGRAM_INFO_BINARY_SIZES) {
auto value = reinterpret_cast<size_t *>(param_value);
value[0] = 1;
if (param_value) {
auto value = reinterpret_cast<size_t *>(param_value);
value[0] = 1;
}
}

if (param_name == PI_PROGRAM_INFO_BINARIES) {
auto value = reinterpret_cast<unsigned char *>(param_value);
value[0] = 1;
if (param_value_size_ret) {
*param_value_size_ret = sizeof(unsigned char);
}
if (param_value) {
auto value = reinterpret_cast<unsigned char *>(param_value);
value[0] = 1;
}
}

return PI_SUCCESS;
Expand Down
3 changes: 3 additions & 0 deletions sycl/unittests/helpers/ScopedEnvVar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

#pragma once

#include <CL/sycl/detail/common.hpp>

#include <cstdlib>
#include <functional>
#include <stdlib.h>

Expand Down
150 changes: 150 additions & 0 deletions sycl/unittests/program_manager/BuildLog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//==----------------- BuildLog.cpp --- Build log tests ---------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "gtest/internal/gtest-internal.h"
#define SYCL2020_DISABLE_DEPRECATION_WARNINGS

#include <CL/sycl.hpp>
#include <detail/config.hpp>
#include <detail/context_impl.hpp>
#include <detail/program_manager/program_manager.hpp>
#include <helpers/CommonRedefinitions.hpp>
#include <helpers/PiImage.hpp>
#include <helpers/PiMock.hpp>
#include <helpers/ScopedEnvVar.hpp>

#include <gtest/gtest.h>

#include <cstring>
#include <stdlib.h>

#include <helpers/TestKernel.hpp>

// Same as defined in config.def
static constexpr auto WarningLevelEnvVar = "SYCL_RT_WARNING_LEVEL";

static bool LogRequested = false;

static pi_result redefinedProgramGetBuildInfo(
pi_program program, pi_device device, cl_program_build_info param_name,
size_t param_value_size, void *param_value, size_t *param_value_size_ret) {

if (param_value_size_ret) {
*param_value_size_ret = 1;
}
if (param_value) {
*static_cast<char *>(param_value) = '1';
}

if (param_name == PI_PROGRAM_BUILD_INFO_LOG) {
LogRequested = true;
}

return PI_SUCCESS;
}

static pi_result redefinedDeviceGetInfo(pi_device device,
pi_device_info param_name,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret) {
if (param_name == PI_DEVICE_INFO_NAME) {
const std::string name = "Test Device";
if (param_value_size_ret) {
*param_value_size_ret = name.size();
}
if (param_value) {
auto *val = static_cast<char *>(param_value);
strcpy(val, name.data());
}
}
if (param_name == PI_DEVICE_INFO_COMPILER_AVAILABLE) {
if (param_value_size_ret) {
*param_value_size_ret = sizeof(cl_bool);
}
if (param_value) {
auto *val = static_cast<cl_bool *>(param_value);
*val = 1;
}
}
return PI_SUCCESS;
}

static void setupCommonTestAPIs(sycl::unittest::PiMock &Mock) {
using namespace sycl::detail;
Mock.redefine<PiApiKind::piProgramGetBuildInfo>(redefinedProgramGetBuildInfo);
Mock.redefine<PiApiKind::piDeviceGetInfo>(redefinedDeviceGetInfo);
}

TEST(BuildLog, OutputNothingOnLevel1) {
using namespace sycl::detail;
using namespace sycl::unittest;
ScopedEnvVar var(WarningLevelEnvVar, "1",
SYCLConfig<SYCL_RT_WARNING_LEVEL>::reset);

sycl::platform Plt{sycl::default_selector()};
// TODO make sure unsupported platform is never selected
if (Plt.is_host() || Plt.get_backend() == sycl::backend::ext_oneapi_cuda ||
Plt.get_backend() == sycl::backend::ext_oneapi_hip) {
GTEST_SKIP_("Test is not supported on this platform");
}

sycl::unittest::PiMock Mock{Plt};
setupDefaultMockAPIs(Mock);
setupCommonTestAPIs(Mock);

const sycl::device Dev = Plt.get_devices()[0];

sycl::queue Queue{Dev};

sycl::context Ctx = Queue.get_context();
auto ContextImpl = getSyclObjImpl(Ctx);
// Make sure no kernels are cached
ContextImpl->getKernelProgramCache().reset();

LogRequested = false;
sycl::kernel_bundle KernelBundle =
sycl::get_kernel_bundle<sycl::bundle_state::input>(Ctx, {Dev});
(void)sycl::build(KernelBundle);

EXPECT_EQ(LogRequested, false);
}

TEST(BuildLog, OutputLogOnLevel2) {
using namespace sycl::detail;
using namespace sycl::unittest;
ScopedEnvVar var(WarningLevelEnvVar, "2",
SYCLConfig<SYCL_RT_WARNING_LEVEL>::reset);

sycl::platform Plt{sycl::default_selector()};
// TODO make sure unsupported platform is never selected
if (Plt.is_host() || Plt.get_backend() == sycl::backend::ext_oneapi_cuda ||
Plt.get_backend() == sycl::backend::ext_oneapi_hip) {
GTEST_SKIP_("Test is not supported on this platform");
}

sycl::unittest::PiMock Mock{Plt};
setupDefaultMockAPIs(Mock);
setupCommonTestAPIs(Mock);

const sycl::device Dev = Plt.get_devices()[0];

sycl::queue Queue{Dev};

const sycl::context Ctx = Queue.get_context();
auto ContextImpl = getSyclObjImpl(Ctx);
// Make sure no kernels are cached
ContextImpl->getKernelProgramCache().reset();

LogRequested = false;
sycl::kernel_bundle KernelBundle =
sycl::get_kernel_bundle<sycl::bundle_state::input>(Ctx, {Dev});
(void)sycl::build(KernelBundle);

EXPECT_EQ(LogRequested, true);
}
1 change: 1 addition & 0 deletions sycl/unittests/program_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(CMAKE_CXX_EXTENSIONS OFF)

add_sycl_unittest(ProgramManagerTests OBJECT
BuildLog.cpp
EliminatedArgMask.cpp
itt_annotations.cpp
)
Expand Down