Skip to content

Commit 5bd42eb

Browse files
authored
[SYCL] Set compiled program for hostpipe (#9060)
HostPipe implementation should pass the compiled program to backend when invoke the read / write operation. There are two scenarios for HostPipe read / write: * Invoke device kernel before HostPipe read / write * Invoke HostPipe read / write before device kernel. For the 1st scenario, the program should be compiled before HostPipe read / write. We get the program from Cache for HostPipe entry. For the 2nd scenario, the program should NOT be compiled. We need to compile the program first for HostPipe entry. The compiled program will be cached for future device kernel.
1 parent 4c52506 commit 5bd42eb

File tree

4 files changed

+57
-11
lines changed

4 files changed

+57
-11
lines changed

sycl/source/detail/context_impl.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,26 +394,29 @@ void context_impl::DeviceGlobalInitializer::ClearEvents(const plugin &Plugin) {
394394
MDeviceGlobalInitEvents.clear();
395395
}
396396

397-
std::optional<RT::PiProgram> context_impl::getProgramForDeviceGlobal(
398-
const device &Device, DeviceGlobalMapEntry *DeviceGlobalEntry) {
397+
std::optional<RT::PiProgram> context_impl::getProgramForDevImgs(
398+
const device &Device, const std::set<std::uintptr_t> &ImgIdentifiers,
399+
const std::string &ObjectTypeName) {
400+
399401
KernelProgramCache::ProgramWithBuildStateT *BuildRes = nullptr;
400402
{
401403
auto LockedCache = MKernelProgramCache.acquireCachedPrograms();
402404
auto &KeyMap = LockedCache.get().KeyMap;
403405
auto &Cache = LockedCache.get().Cache;
404406
RT::PiDevice &DevHandle = getSyclObjImpl(Device)->getHandleRef();
405-
for (std::uintptr_t ImageIDs : DeviceGlobalEntry->MImageIdentifiers) {
407+
for (std::uintptr_t ImageIDs : ImgIdentifiers) {
406408
auto OuterKey = std::make_pair(ImageIDs, DevHandle);
407409
size_t NProgs = KeyMap.count(OuterKey);
408410
if (NProgs == 0)
409411
continue;
410412
// If the cache has multiple programs for the identifiers or if we have
411-
// already found a program in the cache with the device_global, we cannot
412-
// proceed.
413+
// already found a program in the cache with the device_global or host
414+
// pipe we cannot proceed.
413415
if (NProgs > 1 || (BuildRes && NProgs == 1))
414-
throw sycl::exception(
415-
make_error_code(errc::invalid),
416-
"More than one image exists with the device_global.");
416+
throw sycl::exception(make_error_code(errc::invalid),
417+
"More than one image exists with the " +
418+
ObjectTypeName + ".");
419+
417420
auto KeyMappingsIt = KeyMap.find(OuterKey);
418421
assert(KeyMappingsIt != KeyMap.end());
419422
auto CachedProgIt = Cache.find(KeyMappingsIt->second);
@@ -426,6 +429,21 @@ std::optional<RT::PiProgram> context_impl::getProgramForDeviceGlobal(
426429
return *MKernelProgramCache.waitUntilBuilt<compile_program_error>(BuildRes);
427430
}
428431

432+
std::optional<RT::PiProgram> context_impl::getProgramForDeviceGlobal(
433+
const device &Device, DeviceGlobalMapEntry *DeviceGlobalEntry) {
434+
return getProgramForDevImgs(Device, DeviceGlobalEntry->MImageIdentifiers,
435+
"device_global");
436+
}
437+
/// Gets a program associated with a HostPipe Entry from the cache.
438+
std::optional<RT::PiProgram>
439+
context_impl::getProgramForHostPipe(const device &Device,
440+
HostPipeMapEntry *HostPipeEntry) {
441+
// One HostPipe entry belongs to one Img
442+
std::set<std::uintptr_t> ImgIdentifiers;
443+
ImgIdentifiers.insert(HostPipeEntry->getDevBinImage()->getImageID());
444+
return getProgramForDevImgs(Device, ImgIdentifiers, "host_pipe");
445+
}
446+
429447
} // namespace detail
430448
} // __SYCL_INLINE_VER_NAMESPACE(_V1)
431449
} // namespace sycl

sycl/source/detail/context_impl.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,15 @@ class context_impl {
215215
std::optional<RT::PiProgram>
216216
getProgramForDeviceGlobal(const device &Device,
217217
DeviceGlobalMapEntry *DeviceGlobalEntry);
218+
/// Gets a program associated with a HostPipe Entry from the cache.
219+
std::optional<RT::PiProgram>
220+
getProgramForHostPipe(const device &Device, HostPipeMapEntry *HostPipeEntry);
221+
222+
/// Gets a program associated with Dev / Images pairs.
223+
std::optional<RT::PiProgram>
224+
getProgramForDevImgs(const device &Device,
225+
const std::set<std::uintptr_t> &ImgIdentifiers,
226+
const std::string &ObjectTypeName);
218227

219228
enum PropertySupport { NotSupported = 0, Supported = 1, NotChecked = 2 };
220229

sycl/source/detail/host_pipe_map_entry.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ struct HostPipeMapEntry {
5050
void initialize(const RTDeviceBinaryImage *DeviceImage) {
5151
mDeviceImage = DeviceImage;
5252
}
53+
54+
RTDeviceBinaryImage *getDevBinImage() {
55+
return const_cast<RTDeviceBinaryImage *>(mDeviceImage);
56+
}
5357
};
5458

5559
} // namespace detail

sycl/source/detail/scheduler/commands.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,9 +2343,24 @@ pi_int32 enqueueReadWriteHostPipe(const QueueImplPtr &Queue,
23432343
detail::HostPipeMapEntry *hostPipeEntry =
23442344
ProgramManager::getInstance().getHostPipeEntry(PipeName);
23452345

2346-
RT::PiProgram Program = ProgramManager::getInstance().createPIProgram(
2347-
*(hostPipeEntry->mDeviceImage), Queue->get_context(),
2348-
Queue->get_device());
2346+
RT::PiProgram Program = nullptr;
2347+
device Device = Queue->get_device();
2348+
ContextImplPtr ContextImpl = Queue->getContextImplPtr();
2349+
std::optional<RT::PiProgram> CachedProgram =
2350+
ContextImpl->getProgramForHostPipe(Device, hostPipeEntry);
2351+
if (CachedProgram)
2352+
Program = *CachedProgram;
2353+
else {
2354+
// If there was no cached program, build one.
2355+
device_image_plain devImgPlain =
2356+
ProgramManager::getInstance().getDeviceImageFromBinaryImage(
2357+
hostPipeEntry->getDevBinImage(), Queue->get_context(),
2358+
Queue->get_device());
2359+
device_image_plain BuiltImage =
2360+
ProgramManager::getInstance().build(devImgPlain, {Device}, {});
2361+
Program = getSyclObjImpl(BuiltImage)->get_program_ref();
2362+
}
2363+
assert(Program && "Program for this hostpipe is not compiled.");
23492364

23502365
// Get plugin for calling opencl functions
23512366
const detail::plugin &Plugin = Queue->getPlugin();

0 commit comments

Comments
 (0)