Skip to content

[SYCL] Diagnose error in L0 for linker options #5268

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 2 commits into from
Jan 14, 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
43 changes: 32 additions & 11 deletions sycl/plugins/level_zero/pi_level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3785,15 +3785,26 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices,
const pi_program *InputPrograms,
void (*PFnNotify)(pi_program Program, void *UserData),
void *UserData, pi_program *RetProgram) {
(void)Options;

// We only support one device with Level Zero currently.
pi_device Device = Context->Devices[0];
if (NumDevices != 1) {
zePrint("piProgramLink: level_zero supports only one device.");
return PI_INVALID_VALUE;
}

// We do not support any link flags at this time because the Level Zero API
// does not have any way to pass flags that are specific to linking.
if (Options && *Options != '\0') {
std::string ErrorMessage(
"Level Zero does not support kernel link flags: \"");
ErrorMessage.append(Options);
ErrorMessage.push_back('\"');
pi_program Program =
new _pi_program(_pi_program::Invalid, Context, ErrorMessage);
*RetProgram = Program;
return PI_LINK_PROGRAM_FAILURE;
}

// Validate input parameters.
PI_ASSERT(DeviceList && DeviceList[0] == Device, PI_INVALID_DEVICE);
PI_ASSERT(!PFnNotify && !UserData, PI_INVALID_VALUE);
Expand Down Expand Up @@ -4051,16 +4062,26 @@ pi_result piProgramGetBuildInfo(pi_program Program, pi_device Device,
// with piProgramRegister?
return ReturnValue("");
} else if (ParamName == CL_PROGRAM_BUILD_LOG) {
// The OpenCL spec says an empty string is returned if there was no
// previous Compile, Build, or Link.
if (!Program->ZeBuildLog)
return ReturnValue("");
size_t LogSize = ParamValueSize;
ZE_CALL(zeModuleBuildLogGetString,
(Program->ZeBuildLog, &LogSize, pi_cast<char *>(ParamValue)));
if (ParamValueSizeRet) {
*ParamValueSizeRet = LogSize;
// Check first to see if the plugin code recorded an error message.
if (!Program->ErrorMessage.empty()) {
return ReturnValue(Program->ErrorMessage.c_str());
}

// Next check if there is a Level Zero build log.
if (Program->ZeBuildLog) {
size_t LogSize = ParamValueSize;
ZE_CALL(zeModuleBuildLogGetString,
(Program->ZeBuildLog, &LogSize, pi_cast<char *>(ParamValue)));
if (ParamValueSizeRet) {
*ParamValueSizeRet = LogSize;
}
return PI_SUCCESS;
}

// Otherwise, there is no error. The OpenCL spec says to return an empty
// string if there ws no previous attempt to compile, build, or link the
// program.
return ReturnValue("");
} else {
zePrint("piProgramGetBuildInfo: unsupported ParamName\n");
return PI_INVALID_VALUE;
Expand Down
9 changes: 9 additions & 0 deletions sycl/plugins/level_zero/pi_level_zero.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,11 @@ struct _pi_program : _pi_object {
: Context{Context}, OwnZeModule{OwnZeModule}, State{St},
ZeModule{ZeModule}, ZeBuildLog{nullptr} {}

// Construct a program in Invalid state with a custom error message.
_pi_program(state St, pi_context Context, const std::string &ErrorMessage)
: Context{Context}, OwnZeModule{true}, ErrorMessage{ErrorMessage},
State{St}, ZeModule{nullptr}, ZeBuildLog{nullptr} {}

~_pi_program();

const pi_context Context; // Context of the program.
Expand All @@ -1083,6 +1088,10 @@ struct _pi_program : _pi_object {
// asked to not transfer the ownership to SYCL RT.
const bool OwnZeModule;

// This error message is used only in Invalid state to hold a custom error
// message from a call to piProgramLink.
const std::string ErrorMessage;

// Protects accesses to all the non-const member variables. Exclusive access
// is required to modify any of these members.
std::shared_mutex Mutex;
Expand Down