Skip to content

Commit

Permalink
[SYCL] Diagnose error in L0 for linker options (#5268)
Browse files Browse the repository at this point in the history
The Level Zero driver does not support any way to pass options that
are specific to the online linker, so diagnose an error if the
application attempts to pass any.  Previously, any such options were
silently ignored.

Note that the Level Zero driver does support online _compiler_
options, and the plugin correctly handles these.
  • Loading branch information
gmlueck authored Jan 14, 2022
1 parent bd1ed6a commit 97e6d2d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
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

0 comments on commit 97e6d2d

Please sign in to comment.