diff --git a/llvm/include/llvm/Support/PropertySetIO.h b/llvm/include/llvm/Support/PropertySetIO.h index 310afd5f4cfa3..0a8852357cd36 100644 --- a/llvm/include/llvm/Support/PropertySetIO.h +++ b/llvm/include/llvm/Support/PropertySetIO.h @@ -193,6 +193,7 @@ class PropertySetRegistry { static constexpr char SYCL_ASSERT_USED[] = "SYCL/assert used"; static constexpr char SYCL_EXPORTED_SYMBOLS[] = "SYCL/exported symbols"; static constexpr char SYCL_DEVICE_GLOBALS[] = "SYCL/device globals"; + static constexpr char SYCL_HOST_PIPES[] = "SYCL/host pipes"; // Function for bulk addition of an entire property set under given category // (property set name). diff --git a/llvm/lib/Support/PropertySetIO.cpp b/llvm/lib/Support/PropertySetIO.cpp index 3541c11a8d7d2..4dc6a048e137c 100644 --- a/llvm/lib/Support/PropertySetIO.cpp +++ b/llvm/lib/Support/PropertySetIO.cpp @@ -202,6 +202,7 @@ constexpr char PropertySetRegistry::SYCL_MISC_PROP[]; constexpr char PropertySetRegistry::SYCL_ASSERT_USED[]; constexpr char PropertySetRegistry::SYCL_EXPORTED_SYMBOLS[]; constexpr char PropertySetRegistry::SYCL_DEVICE_GLOBALS[]; +constexpr char PropertySetRegistry::SYCL_HOST_PIPES[]; } // namespace util } // namespace llvm diff --git a/sycl/include/CL/sycl/detail/host_pipe_map.hpp b/sycl/include/CL/sycl/detail/host_pipe_map.hpp new file mode 100755 index 0000000000000..9c82f11bf0a76 --- /dev/null +++ b/sycl/include/CL/sycl/detail/host_pipe_map.hpp @@ -0,0 +1,21 @@ +//==-------------------- host_pipe_map.hpp -----------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace detail { +namespace host_pipe_map { + +__SYCL_EXPORT void add(const void *HostPipePtr, const char *UniqueId); + +} // namespace host_pipe_map +} // namespace detail +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/include/CL/sycl/detail/pi.h b/sycl/include/CL/sycl/detail/pi.h index 16482c07e1fa5..9bdb4b067da15 100644 --- a/sycl/include/CL/sycl/detail/pi.h +++ b/sycl/include/CL/sycl/detail/pi.h @@ -777,6 +777,8 @@ static const uint8_t PI_DEVICE_BINARY_OFFLOAD_KIND_SYCL = 4; #define __SYCL_PI_PROPERTY_SET_SYCL_EXPORTED_SYMBOLS "SYCL/exported symbols" /// PropertySetRegistry::SYCL_DEVICE_GLOBALS defined in PropertySetIO.h #define __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_GLOBALS "SYCL/device globals" +/// PropertySetRegistry::SYCL_HOST_PIPES defined in PropertySetIO.h +#define __SYCL_PI_PROPERTY_SET_SYCL_HOST_PIPES "SYCL/host pipes" /// Program metadata tags recognized by the PI backends. For kernels the tag /// must appear after the kernel name. diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index dbb7adabd2c26..c2e7a96eaf946 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -383,6 +383,13 @@ class DeviceBinaryImage { DeviceGlobals.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_DEVICE_GLOBALS); return DeviceGlobals; } + const PropertyRange getHostPipes() const { + // We can't have this variable as a class member, since it would break + // the ABI backwards compatibility. + DeviceBinaryImage::PropertyRange HostPipes; + HostPipes.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_HOST_PIPES); + return HostPipes; + } virtual ~DeviceBinaryImage() {} protected: diff --git a/sycl/source/CMakeLists.txt b/sycl/source/CMakeLists.txt index b89835c5f4864..60988bb02ca43 100644 --- a/sycl/source/CMakeLists.txt +++ b/sycl/source/CMakeLists.txt @@ -134,6 +134,7 @@ set(SYCL_SOURCES "detail/context_impl.cpp" "detail/device_binary_image.cpp" "detail/device_filter.cpp" + "detail/host_pipe_map.cpp" "detail/device_global_map.cpp" "detail/device_impl.cpp" "detail/error_handling/enqueue_kernel.cpp" diff --git a/sycl/source/detail/host_pipe_map.cpp b/sycl/source/detail/host_pipe_map.cpp new file mode 100644 index 0000000000000..79f7f77f70716 --- /dev/null +++ b/sycl/source/detail/host_pipe_map.cpp @@ -0,0 +1,24 @@ +//==-------------------- host_pipe_map.cpp -----------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace detail { +namespace host_pipe_map { + +__SYCL_EXPORT void add(const void *HostPipePtr, const char *UniqueId) { + detail::ProgramManager::getInstance().addOrInitHostPipeEntry(HostPipePtr, + UniqueId); +} + +} // namespace host_pipe_map +} // namespace detail +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/host_pipe_map_entry.hpp b/sycl/source/detail/host_pipe_map_entry.hpp new file mode 100644 index 0000000000000..2d8dae9f4ba71 --- /dev/null +++ b/sycl/source/detail/host_pipe_map_entry.hpp @@ -0,0 +1,50 @@ +//==----------------- host_pipe_map_entry.hpp --------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace detail { + +struct HostPipeMapEntry { + std::string MUniqueId; + // Pointer to the host_pipe on host. + const void *MHostPipePtr; + // Size of the underlying type in the host_pipe. + std::uint32_t MHostPipeTSize; + + // Constructor only initializes with the pointer and ID. + // Other members will be initialized later + HostPipeMapEntry(std::string UniqueId, const void *HostPipePtr) + : MUniqueId(UniqueId), MHostPipePtr(HostPipePtr), MHostPipeTSize(0) {} + + // Constructor only initializes with the size and ID. + // Other members will be initialized later + HostPipeMapEntry(std::string UniqueId, std::uint32_t HostPipeTSize) + : MUniqueId(UniqueId), MHostPipePtr(nullptr), + MHostPipeTSize(HostPipeTSize) {} + + void initialize(std::uint32_t HostPipeTSize) { + assert(HostPipeTSize != 0 && "Host pipe initialized with 0 size."); + assert(MHostPipeTSize == 0 && "Host pipe has already been initialized."); + MHostPipeTSize = HostPipeTSize; + } + + void initialize(const void *HostPipePtr) { + assert(!MHostPipePtr && "Host pipe pointer has already been initialized."); + MHostPipePtr = HostPipePtr; + } +}; + +} // namespace detail +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/program_manager/program_manager.cpp b/sycl/source/detail/program_manager/program_manager.cpp index 5efea6c0349ee..51fbf739d697c 100644 --- a/sycl/source/detail/program_manager/program_manager.cpp +++ b/sycl/source/detail/program_manager/program_manager.cpp @@ -1220,6 +1220,40 @@ void ProgramManager::addImages(pi_device_binaries DeviceBinary) { Entry->second.initialize(TypeSize, DeviceImageScopeDecorated); } } + // ... and initialize associated host_pipe information + { + std::lock_guard HostPipesGuard(m_HostPipesMutex); + + auto HostPipes = Img->getHostPipes(); + for (const pi_device_binary_property &HostPipe : HostPipes) { + pi::ByteArray HostPipeInfo = + pi::DeviceBinaryProperty(HostPipe).asByteArray(); + + // The supplied host_pipe info property is expected to contain: + // * 8 bytes - Size of the property. + // * 4 bytes - Size of the underlying type in the host_pipe. + // Note: Property may be padded. + constexpr unsigned int NumPropertySizeBytes = 8; + constexpr unsigned int NumTypeBytes = 4; + assert(HostPipeInfo.size() >= NumPropertySizeBytes + NumTypeBytes && + "Unexpected property size"); + auto TypeSize = *reinterpret_cast( + &HostPipeInfo[NumPropertySizeBytes]); + + auto ExistingHostPipe = m_HostPipes.find(HostPipe->Name); + if (ExistingHostPipe != m_HostPipes.end()) { + // If it has already been registered we update the information. + ExistingHostPipe->second->initialize(TypeSize); + } else { + // If it has not already been registered we create a new entry. + // Note: Pointer to the host pipe is not available here, so it + // cannot be set until registration happens. + auto EntryUPtr = + std::make_unique(HostPipe->Name, TypeSize); + m_HostPipes.emplace(HostPipe->Name, std::move(EntryUPtr)); + } + } + } m_DeviceImages[KSId].reset(new std::vector()); cacheKernelUsesAssertInfo(M, *Img); @@ -1469,6 +1503,36 @@ kernel_id ProgramManager::getBuiltInKernelID(const std::string &KernelName) { return KernelID->second; } +void ProgramManager::addOrInitHostPipeEntry(const void *HostPipePtr, + const char *UniqueId) { + std::lock_guard HostPipesGuard(m_HostPipesMutex); + + auto ExistingHostPipe = m_HostPipes.find(UniqueId); + if (ExistingHostPipe != m_HostPipes.end()) { + ExistingHostPipe->second->initialize(HostPipePtr); + m_Ptr2HostPipe.insert({HostPipePtr, ExistingHostPipe->second.get()}); + return; + } + auto EntryUPtr = std::make_unique(UniqueId, HostPipePtr); + auto NewEntry = m_HostPipes.emplace(UniqueId, std::move(EntryUPtr)); + m_Ptr2HostPipe.insert({HostPipePtr, NewEntry.first->second.get()}); +} + +HostPipeMapEntry * +ProgramManager::getHostPipeEntry(const std::string &UniqueId) { + std::lock_guard HostPipesGuard(m_HostPipesMutex); + auto Entry = m_HostPipes.find(UniqueId); + assert(Entry != m_HostPipes.end() && "Host pipe entry not found"); + return Entry->second.get(); +} + +HostPipeMapEntry *ProgramManager::getHostPipeEntry(const void *HostPipePtr) { + std::lock_guard HostPipesGuard(m_HostPipesMutex); + auto Entry = m_Ptr2HostPipe.find(HostPipePtr); + assert(Entry != m_Ptr2HostPipe.end() && "Host pipe entry not found"); + return Entry->second; +} + void ProgramManager::addDeviceGlobalEntry(void *DeviceGlobalPtr, const char *UniqueId) { std::lock_guard DeviceGlobalsGuard(m_DeviceGlobalsMutex); diff --git a/sycl/source/detail/program_manager/program_manager.hpp b/sycl/source/detail/program_manager/program_manager.hpp index a1bd79bfc106d..1c48379c76251 100644 --- a/sycl/source/detail/program_manager/program_manager.hpp +++ b/sycl/source/detail/program_manager/program_manager.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include @@ -183,6 +185,18 @@ class ProgramManager { // built-in kernel name. kernel_id getBuiltInKernelID(const std::string &KernelName); + // The function inserts or initializes a host_pipe entry into the + // host_pipe map. + void addOrInitHostPipeEntry(const void *HostPipePtr, const char *UniqueId); + + // The function gets a host_pipe entry identified by the unique ID from + // the host_pipe map. + HostPipeMapEntry *getHostPipeEntry(const std::string &UniqueId); + + // The function gets a host_pipe entry identified by the pointer to the + // host_pipe object from the host_pipe map. + HostPipeMapEntry *getHostPipeEntry(const void *HostPipePtr); + // The function inserts a device_global entry into the device_global map. void addDeviceGlobalEntry(void *DeviceGlobalPtr, const char *UniqueId); @@ -392,6 +406,14 @@ class ProgramManager { /// Protects m_DeviceGlobals. std::mutex m_DeviceGlobalsMutex; + + // Maps between host_pipe identifiers and associated information. + std::unordered_map> + m_HostPipes; + std::unordered_map m_Ptr2HostPipe; + + /// Protects m_HostPipes and m_Ptr2HostPipe. + std::mutex m_HostPipesMutex; }; } // namespace detail } // namespace sycl diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index 2f2f94e5bcd54..255f02af50006 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -3881,6 +3881,7 @@ _ZN2cl4sycl6detail13MemoryManager8copy_usmEPKvSt10shared_ptrINS1_10queue_implEEm _ZN2cl4sycl6detail13MemoryManager8copy_usmEPKvSt10shared_ptrINS1_10queue_implEEmPvSt6vectorIP9_pi_eventSaISB_EERSB_ _ZN2cl4sycl6detail13MemoryManager8fill_usmEPvSt10shared_ptrINS1_10queue_implEEmiSt6vectorIP9_pi_eventSaIS9_EEPS9_ _ZN2cl4sycl6detail13MemoryManager8fill_usmEPvSt10shared_ptrINS1_10queue_implEEmiSt6vectorIP9_pi_eventSaIS9_EERS9_ +_ZN2cl4sycl6detail13host_pipe_map3addEPKvPKc _ZN2cl4sycl6detail13make_platformEmNS0_7backendE _ZN2cl4sycl6detail14getBorderColorENS0_19image_channel_orderE _ZN2cl4sycl6detail14host_half_impl4halfC1ERKf diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index 5c908b3a3865e..fd8d4b4c80a2e 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -1090,6 +1090,7 @@ ?acospi@__host_std@cl@@YA?AVhalf@half_impl@detail@sycl@2@V34562@@Z ?acospi@__host_std@cl@@YAMM@Z ?acospi@__host_std@cl@@YANN@Z +?add@host_pipe_map@detail@sycl@cl@@YAXPEBXPEBD@Z ?addHostAccessorAndWait@detail@sycl@cl@@YAXPEAVAccessorImplHost@123@@Z ?addOrReplaceAccessorProperties@SYCLMemObjT@detail@sycl@cl@@QEAAXAEBVproperty_list@34@@Z ?addReduction@handler@sycl@cl@@AEAAXAEBV?$shared_ptr@$$CBX@std@@@Z