Skip to content

Commit dddac4a

Browse files
[SYCL] Support build log and options in the L0 plugin (#1981)
- Defer L0 module creation/build until piProgramBuild/piProgramCompile. - Support build log extraction. - Support build options. Author: Sergey V Maslov <[email protected]> Signed-off-by: Artur Gainullin <[email protected]> Co-authored-by: Sergey V Maslov <[email protected]>
1 parent b1b8510 commit dddac4a

File tree

2 files changed

+61
-49
lines changed

2 files changed

+61
-49
lines changed

sycl/plugins/level_zero/pi_level0.cpp

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ static pi_result mapError(ze_result_t ZeResult) {
259259
{ZE_RESULT_ERROR_INVALID_NATIVE_BINARY, PI_INVALID_BINARY},
260260
{ZE_RESULT_ERROR_INVALID_KERNEL_NAME, PI_INVALID_KERNEL_NAME},
261261
{ZE_RESULT_ERROR_INVALID_FUNCTION_NAME, PI_BUILD_PROGRAM_FAILURE},
262-
{ZE_RESULT_ERROR_OVERLAPPING_REGIONS, PI_INVALID_OPERATION}};
262+
{ZE_RESULT_ERROR_OVERLAPPING_REGIONS, PI_INVALID_OPERATION},
263+
{ZE_RESULT_ERROR_MODULE_BUILD_FAILURE, PI_BUILD_PROGRAM_FAILURE}};
263264
auto It = ErrorMapping.find(ZeResult);
264265
if (It == ErrorMapping.end()) {
265266
return PI_ERROR_UNKNOWN;
@@ -1634,22 +1635,20 @@ pi_result piProgramCreate(pi_context Context, const void *IL, size_t Length,
16341635

16351636
assert(Context);
16361637
assert(Program);
1637-
ze_device_handle_t ZeDevice = Context->Device->ZeDevice;
16381638

1639+
// NOTE: the L0 module creation is also building the program, so we are
1640+
// deferring it until the program is ready to be built in piProgramBuild
1641+
// and piProgramCompile. Also it is only then we know the build options.
1642+
//
16391643
ze_module_desc_t ZeModuleDesc = {};
16401644
ZeModuleDesc.version = ZE_MODULE_DESC_VERSION_CURRENT;
16411645
ZeModuleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
16421646
ZeModuleDesc.inputSize = Length;
1643-
ZeModuleDesc.pInputModule = pi_cast<const uint8_t *>(IL);
1644-
ZeModuleDesc.pBuildFlags = nullptr;
1645-
1646-
ze_module_handle_t ZeModule;
1647-
ZE_CALL(zeModuleCreate(ZeDevice, &ZeModuleDesc, &ZeModule,
1648-
0)); // TODO: handle build log
1647+
ZeModuleDesc.pInputModule = new uint8_t[Length];
1648+
memcpy(const_cast<uint8_t *>(ZeModuleDesc.pInputModule), IL, Length);
16491649

16501650
try {
1651-
auto ZePiProgram = new _pi_program(ZeModule, Context);
1652-
*Program = pi_cast<pi_program>(ZePiProgram);
1651+
*Program = new _pi_program(nullptr, ZeModuleDesc, Context);
16531652
} catch (const std::bad_alloc &) {
16541653
return PI_OUT_OF_HOST_MEMORY;
16551654
} catch (...) {
@@ -1670,7 +1669,6 @@ pi_result piProgramCreateWithBinary(pi_context Context, pi_uint32 NumDevices,
16701669
assert(Context);
16711670
assert(RetProgram);
16721671
assert(DeviceList && DeviceList[0] == Context->Device);
1673-
ze_device_handle_t ZeDevice = Context->Device->ZeDevice;
16741672

16751673
// Check the binary too.
16761674
assert(Lengths && Lengths[0] != 0);
@@ -1682,15 +1680,11 @@ pi_result piProgramCreateWithBinary(pi_context Context, pi_uint32 NumDevices,
16821680
ZeModuleDesc.version = ZE_MODULE_DESC_VERSION_CURRENT;
16831681
ZeModuleDesc.format = ZE_MODULE_FORMAT_NATIVE;
16841682
ZeModuleDesc.inputSize = Length;
1685-
ZeModuleDesc.pInputModule = Binary;
1686-
ZeModuleDesc.pBuildFlags = nullptr;
1687-
1688-
ze_module_handle_t ZeModule;
1689-
ZE_CALL(zeModuleCreate(ZeDevice, &ZeModuleDesc, &ZeModule, 0));
1683+
ZeModuleDesc.pInputModule = new uint8_t[Length];
1684+
memcpy(const_cast<uint8_t *>(ZeModuleDesc.pInputModule), Binary, Length);
16901685

16911686
try {
1692-
auto ZePiProgram = new _pi_program(ZeModule, Context);
1693-
*RetProgram = pi_cast<pi_program>(ZePiProgram);
1687+
*RetProgram = new _pi_program(nullptr, ZeModuleDesc, Context);
16941688
} catch (const std::bad_alloc &) {
16951689
return PI_OUT_OF_HOST_MEMORY;
16961690
} catch (...) {
@@ -1777,14 +1771,7 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices,
17771771
const pi_program *InputPrograms,
17781772
void (*PFnNotify)(pi_program Program, void *UserData),
17791773
void *UserData, pi_program *RetProgram) {
1780-
die("piProgramLink: Program Linking is not supported yet in Level0");
1781-
1782-
// TODO: L0 builds the program at the time of piProgramCreate.
1783-
// But build options are not available at that time, so we must
1784-
// stop building it there, but move it here. The problem though
1785-
// is that this would mean moving zeModuleCreate here entirely,
1786-
// and so L0 module creation would be deferred until
1787-
// piProgramCompile/piProgramLink/piProgramBuild.
1774+
// TODO: L0 does not [yet] support linking so dummy implementation here.
17881775
assert(NumInputPrograms == 1 && InputPrograms);
17891776
assert(RetProgram);
17901777
*RetProgram = InputPrograms[0];
@@ -1797,32 +1784,36 @@ pi_result piProgramCompile(
17971784
const pi_program *InputHeaders, const char **HeaderIncludeNames,
17981785
void (*PFnNotify)(pi_program Program, void *UserData), void *UserData) {
17991786

1800-
// TODO: L0 builds the program at the time of piProgramCreate.
1801-
// But build options are not available at that time, so we must
1802-
// stop building it there, but move it here. The problem though
1803-
// is that this would mean moving zeModuleCreate here entirely,
1804-
// and so L0 module creation would be deferred until
1805-
// piProgramCompile/piProgramLink/piProgramBuild.
1806-
//
1807-
// It is expected that program was successfully built during piProgramCreate
1808-
assert(Program && Program->ZeModule);
1809-
return PI_SUCCESS;
1787+
// Assert on unsupported arguments.
1788+
assert(NumInputHeaders == 0);
1789+
assert(!InputHeaders);
1790+
1791+
// There is no support foe linking yet in L0 so "compile" actually
1792+
// does the "build".
1793+
return piProgramBuild(Program, NumDevices, DeviceList, Options, PFnNotify,
1794+
UserData);
18101795
}
18111796

18121797
pi_result piProgramBuild(pi_program Program, pi_uint32 NumDevices,
18131798
const pi_device *DeviceList, const char *Options,
18141799
void (*PFnNotify)(pi_program Program, void *UserData),
18151800
void *UserData) {
1801+
assert(Program);
1802+
assert(NumDevices == 1);
1803+
assert(DeviceList && DeviceList[0] == Program->Context->Device);
1804+
assert(!PFnNotify);
1805+
assert(!UserData);
18161806

1817-
// TODO: L0 builds the program at the time of piProgramCreate.
1818-
// But build options are not available at that time, so we must
1819-
// stop building it there, but move it here. The problem though
1820-
// is that this would mean moving zeModuleCreate here entirely,
1821-
// and so L0 module creation would be deferred until
1822-
// piProgramCompile/piProgramLink/piProgramBuild.
1823-
//
1824-
// It is expected that program was successfully built during piProgramCreate
1825-
assert(Program && Program->ZeModule);
1807+
// Check that the program wasn't already built.
1808+
assert(!Program->ZeModule);
1809+
1810+
Program->ZeModuleDesc.pBuildFlags = Options;
1811+
// TODO: set specialization constants here.
1812+
Program->ZeModuleDesc.pConstants = nullptr;
1813+
1814+
ze_device_handle_t ZeDevice = Program->Context->Device->ZeDevice;
1815+
ZE_CALL(zeModuleCreate(ZeDevice, &Program->ZeModuleDesc, &Program->ZeModule,
1816+
&Program->ZeBuildLog));
18261817
return PI_SUCCESS;
18271818
}
18281819

@@ -1846,9 +1837,19 @@ pi_result piProgramGetBuildInfo(pi_program Program, pi_device Device,
18461837
// return for programs that were built outside and registered
18471838
// with piProgramRegister?
18481839
return ReturnValue("");
1840+
} else if (ParamName == CL_PROGRAM_BUILD_LOG) {
1841+
assert(Program->ZeBuildLog);
1842+
size_t LogSize = ParamValueSize;
1843+
ZE_CALL(zeModuleBuildLogGetString(Program->ZeBuildLog, &LogSize,
1844+
pi_cast<char *>(ParamValue)));
1845+
if (ParamValueSizeRet) {
1846+
*ParamValueSizeRet = LogSize;
1847+
}
1848+
} else {
1849+
zePrint("piProgramGetBuildInfo: unsupported ParamName\n");
1850+
return PI_INVALID_VALUE;
18491851
}
1850-
zePrint("piProgramGetBuildInfo: unsupported ParamName\n");
1851-
return PI_INVALID_VALUE;
1852+
return PI_SUCCESS;
18521853
}
18531854

18541855
pi_result piProgramRetain(pi_program Program) {
@@ -1861,6 +1862,9 @@ pi_result piProgramRelease(pi_program Program) {
18611862
assert(Program);
18621863
assert((Program->RefCount > 0) && "Program is already released.");
18631864
if (--(Program->RefCount) == 0) {
1865+
delete[] Program->ZeModuleDesc.pInputModule;
1866+
if (Program->ZeBuildLog)
1867+
zeModuleBuildLogDestroy(Program->ZeBuildLog);
18641868
// TODO: call zeModuleDestroy for non-interop L0 modules
18651869
delete Program;
18661870
}

sycl/plugins/level_zero/pi_level0.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,20 @@ struct _pi_event : _pi_object {
306306
};
307307

308308
struct _pi_program : _pi_object {
309-
_pi_program(ze_module_handle_t Module, pi_context Context)
310-
: ZeModule{Module}, Context{Context} {}
309+
_pi_program(ze_module_handle_t Module, ze_module_desc_t ModuleDesc,
310+
pi_context Context)
311+
: ZeModuleDesc(ModuleDesc), ZeModule{Module},
312+
ZeBuildLog{nullptr}, Context{Context} {}
313+
314+
// L0 module descriptor.
315+
ze_module_desc_t ZeModuleDesc;
311316

312317
// L0 module handle.
313318
ze_module_handle_t ZeModule;
314319

320+
// L0 build log.
321+
ze_module_build_log_handle_t ZeBuildLog;
322+
315323
// Keep the context of the program.
316324
pi_context Context;
317325
};

0 commit comments

Comments
 (0)