Skip to content

Commit 638b71b

Browse files
authored
[SYCL] Fix build log for L0 plugin (#2479)
The build log was not preserved for failed compile and link operations in the L0 plugin, and this prevented the build log information from being included in the SYCL "compile_program_error" exception. Fix this and add a test.
1 parent 6832d83 commit 638b71b

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

sycl/plugins/level_zero/pi_level_zero.cpp

+14-10
Original file line numberDiff line numberDiff line change
@@ -2231,16 +2231,22 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices,
22312231
ZeHandles.push_back(Input->ZeModule);
22322232
}
22332233

2234-
// Link all the modules together. If this fails (or if we catch an
2235-
// exception below), we need to release the reference counts on the input
2236-
// modules, delete any copies, etc.
2234+
// Link all the modules together.
22372235
ze_module_build_log_handle_t ZeBuildLog;
2238-
ZE_CALL(zeModuleDynamicLinkMock(ZeHandles.size(), ZeHandles.data(),
2239-
&ZeBuildLog));
2236+
ze_result_t ZeResult = ZE_CALL_NOCHECK(zeModuleDynamicLinkMock(
2237+
ZeHandles.size(), ZeHandles.data(), &ZeBuildLog));
22402238

22412239
// Construct a new program object to represent the linked executable. This
2242-
// new object holds a reference to all the input programs.
2243-
*RetProgram = new _pi_program(Context, std::move(Inputs), ZeBuildLog);
2240+
// new object holds a reference to all the input programs. Note that we
2241+
// create this program object even if the link fails with "link failure"
2242+
// because we need the new program object to hold the buid log (which has
2243+
// the description of the failure).
2244+
if (ZeResult == ZE_RESULT_SUCCESS ||
2245+
ZeResult == ZE_RESULT_ERROR_MODULE_LINK_FAILURE) {
2246+
*RetProgram = new _pi_program(Context, std::move(Inputs), ZeBuildLog);
2247+
}
2248+
if (ZeResult != ZE_RESULT_SUCCESS)
2249+
return mapError(ZeResult);
22442250
} catch (const std::bad_alloc &) {
22452251
return PI_OUT_OF_HOST_MEMORY;
22462252
} catch (...) {
@@ -2356,9 +2362,8 @@ static pi_result compileOrBuild(pi_program Program, pi_uint32 NumDevices,
23562362
ze_device_handle_t ZeDevice = DeviceList[0]->ZeDevice;
23572363
ze_context_handle_t ZeContext = Program->Context->ZeContext;
23582364
ze_module_handle_t ZeModule;
2359-
ze_module_build_log_handle_t ZeBuildLog;
23602365
ZE_CALL(zeModuleCreate(ZeContext, ZeDevice, &ZeModuleDesc, &ZeModule,
2361-
&ZeBuildLog));
2366+
&Program->ZeBuildLog));
23622367

23632368
// Check if this module imports any symbols, which we need to know if we
23642369
// end up linking this module later. See comments in piProgramLink() for
@@ -2371,7 +2376,6 @@ static pi_result compileOrBuild(pi_program Program, pi_uint32 NumDevices,
23712376
// The caller must set the State to Object or Exe as appropriate.
23722377
Program->Code.reset();
23732378
Program->ZeModule = ZeModule;
2374-
Program->ZeBuildLog = ZeBuildLog;
23752379
return PI_SUCCESS;
23762380
}
23772381

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// XFAIL: cuda
2+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
3+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
4+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
5+
// RUN: %ACC_RUN_PLACEHOLDER %t.out
6+
7+
//==--- build-log.cpp - Test log message from faild build ----------==//
8+
//
9+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10+
// See https://llvm.org/LICENSE.txt for license information.
11+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12+
//
13+
//===--------------------------------------------------------------===//
14+
15+
#include <CL/sycl.hpp>
16+
17+
SYCL_EXTERNAL
18+
void symbol_that_does_not_exist();
19+
20+
void test() {
21+
cl::sycl::queue Queue;
22+
23+
// Submitting this kernel should result in a compile_program_error exception
24+
// with a message indicating that "symbol_that_does_not_exist" is undefined.
25+
auto Kernel = []() {
26+
#ifdef __SYCL_DEVICE_ONLY__
27+
symbol_that_does_not_exist();
28+
#endif
29+
};
30+
31+
std::string Msg;
32+
int Result;
33+
34+
try {
35+
Queue.submit([&](cl::sycl::handler &CGH) {
36+
CGH.single_task<class SingleTask>(Kernel);
37+
});
38+
assert(false && "There must be compilation error");
39+
} catch (const cl::sycl::compile_program_error &e) {
40+
std::string Msg(e.what());
41+
assert(Msg.find("symbol_that_does_not_exist") != std::string::npos);
42+
} catch (...) {
43+
assert(false && "There must be cl::sycl::compile_program_error");
44+
}
45+
}
46+
47+
int main() {
48+
test();
49+
50+
return 0;
51+
}

0 commit comments

Comments
 (0)