Skip to content
16 changes: 12 additions & 4 deletions sycl/plugins/level_zero/pi_level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3852,10 +3852,6 @@ pi_result piProgramBuild(pi_program Program, pi_uint32 NumDevices,
// RT calls piProgramRelease().
Program->State = _pi_program::Invalid;
Result = mapError(ZeResult);
if (Program->ZeBuildLog) {
ZE_CALL_NOCHECK(zeModuleBuildLogDestroy, (Program->ZeBuildLog));
Program->ZeBuildLog = nullptr;
}
if (ZeModule) {
ZE_CALL_NOCHECK(zeModuleDestroy, (ZeModule));
ZeModule = nullptr;
Expand Down Expand Up @@ -3923,6 +3919,18 @@ pi_result piProgramGetBuildInfo(pi_program Program, pi_device Device,
if (ParamValueSizeRet) {
*ParamValueSizeRet = LogSize;
}
if (ParamValue) {
// When the program build fails in piProgramBuild(), we delayed cleaning
// up the build log because RT later calls this routine to get the
// failed build log.
// To avoid memory leaks, we should clean up the failed build log here
// because RT does not create sycl::program when piProgramBuild() fails,
// thus it won't call piProgramRelease() to clean up the build log.
if (Program->State == _pi_program::Invalid) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the Program is a valid PI object (although in "invalid" state) and SYCL RT knows that since it calls this piProgramGetBuildInfo for it. That said, I think the correct fix would be for SYCL RT to call piProgramRelease after it is done with the program build-log retrieval.

ZE_CALL_NOCHECK(zeModuleBuildLogDestroy, (Program->ZeBuildLog));
Program->ZeBuildLog = nullptr;
}
}
return PI_SUCCESS;
}

Expand Down