From 97e6d2de79187d8170514c3ca583a7c793a32848 Mon Sep 17 00:00:00 2001 From: Greg Lueck Date: Fri, 14 Jan 2022 17:29:25 -0500 Subject: [PATCH] [SYCL] Diagnose error in L0 for linker options (#5268) 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. --- sycl/plugins/level_zero/pi_level_zero.cpp | 43 +++++++++++++++++------ sycl/plugins/level_zero/pi_level_zero.hpp | 9 +++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/sycl/plugins/level_zero/pi_level_zero.cpp b/sycl/plugins/level_zero/pi_level_zero.cpp index 6a1ed55462ddd..55977aba18318 100644 --- a/sycl/plugins/level_zero/pi_level_zero.cpp +++ b/sycl/plugins/level_zero/pi_level_zero.cpp @@ -3785,8 +3785,6 @@ 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) { @@ -3794,6 +3792,19 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices, 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); @@ -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(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(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; diff --git a/sycl/plugins/level_zero/pi_level_zero.hpp b/sycl/plugins/level_zero/pi_level_zero.hpp index a40ae9b46fcae..ec5f4c3fdafdb 100644 --- a/sycl/plugins/level_zero/pi_level_zero.hpp +++ b/sycl/plugins/level_zero/pi_level_zero.hpp @@ -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. @@ -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;