Skip to content

[UR][L0] Fix UR_PROGRAM_INFO_BINARIES query #19415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: sycl
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 19 additions & 40 deletions unified-runtime/source/adapters/level_zero/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,62 +746,41 @@ ur_result_t urProgramGetInfo(
return ReturnValue(binarySizes.data(), binarySizes.size());
}
case UR_PROGRAM_INFO_BINARIES: {
// The caller sets "ParamValue" to an array of pointers, one for each
// device.
uint8_t **PBinary = nullptr;
if (ProgramInfo) {
PBinary = ur_cast<uint8_t **>(ProgramInfo);
if (!PBinary[0]) {
break;
}
}
std::shared_lock<ur_shared_mutex> Guard(Program->Mutex);
uint8_t *NativeBinaryPtr = nullptr;
if (PBinary) {
NativeBinaryPtr = PBinary[0];
size_t NumDevices = Program->AssociatedDevices.size();
if (PropSizeRet) {
// Return the size of the array of pointers to binaries (for each device).
*PropSizeRet = NumDevices * sizeof(uint8_t *);
}

size_t SzBinary = 0;
// If the caller did not provide an array of pointers to copy binaries into, return early.
if (!ProgramInfo)
break;

// If the caller provided an array of pointers, copy the binaries.
uint8_t **DestBinPtrs = ur_cast<uint8_t **>(ProgramInfo);
for (uint32_t deviceIndex = 0;
deviceIndex < Program->AssociatedDevices.size(); deviceIndex++) {
deviceIndex < NumDevices; deviceIndex++) {
uint8_t *DestBinPtr = DestBinPtrs[deviceIndex];
if (!DestBinPtr)
continue;

auto ZeDevice = Program->AssociatedDevices[deviceIndex]->ZeDevice;
auto State = Program->getState(ZeDevice);
if (State == ur_program_handle_t_::Native) {
// If Program was created from Native code then return that code.
if (PBinary) {
std::memcpy(PBinary[deviceIndex], Program->getCode(ZeDevice),
// If Program was created from Native code then return that code.
std::memcpy(DestBinPtr, Program->getCode(ZeDevice),
Program->getCodeSize(ZeDevice));
}
SzBinary += Program->getCodeSize(ZeDevice);
continue;
}
if (State == ur_program_handle_t_::IL ||
State == ur_program_handle_t_::Object) {
// We don't have a binary for this device, so don't update the output
// pointer to the binary, only set return size to 0.
if (PropSizeRet)
*PropSizeRet = 0;
} else if (State == ur_program_handle_t_::Exe) {
auto ZeModule = Program->getZeModuleHandle(ZeDevice);
if (!ZeModule) {
return UR_RESULT_ERROR_INVALID_PROGRAM;
}
size_t binarySize = 0;
if (PBinary) {
NativeBinaryPtr = PBinary[deviceIndex];
}
// If the caller is using a Program which is a built binary, then
// the program returned will either be a single module if this is a
// native binary or the native binary for each device will be returned.
size_t DummySize;
ZE2UR_CALL(zeModuleGetNativeBinary,
(ZeModule, &binarySize, NativeBinaryPtr));
SzBinary += binarySize;
} else {
return UR_RESULT_ERROR_INVALID_PROGRAM;
(ZeModule, &DummySize, DestBinPtr));
}
}
if (PropSizeRet)
*PropSizeRet = SzBinary;
break;
}
case UR_PROGRAM_INFO_NUM_KERNELS: {
Expand Down
Loading