Skip to content

[SYCL] Implement initial host_pipe registration #5766

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/PropertySetIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/PropertySetIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 21 additions & 0 deletions sycl/include/CL/sycl/detail/host_pipe_map.hpp
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 2 additions & 0 deletions sycl/include/CL/sycl/detail/pi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions sycl/include/CL/sycl/detail/pi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

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

This do-not-break-my-ABI story starts being a technical debt generator... :-(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment removed.

Copy link
Contributor

Choose a reason for hiding this comment

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

It was not against your comment, but more generally targeted at the project itself. @bader
@sherry-yuan So I want your great comment back! :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

@keryell, I'm aware of that problem. I think we should start tracking these in terms of tasks for the future, when we can break old ABI compatibility.
@s-kanaev, do we track technical debt caused by ABI compatibility requirement?

Copy link
Contributor

Choose a reason for hiding this comment

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

@keryell, I'm aware of that problem. I think we should start tracking these in terms of tasks for the future, when we can break old ABI compatibility. @s-kanaev, do we track technical debt caused by ABI compatibility requirement?

I know @pvchupin has a link where it is tracked

Copy link
Contributor

Choose a reason for hiding this comment

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

Adding TODO here (like

// TODO: This field is not used anymore.
) would be a good idea.
@s-kanaev, list you generated recently could be updated with this one.

Copy link
Contributor Author

@sherry-yuan sherry-yuan Mar 28, 2022

Choose a reason for hiding this comment

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

Thanks! I will add //TODO in a separate PR that annotated all places in this files that will require changes after ABI policy change.

Copy link
Contributor

Choose a reason for hiding this comment

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

Updated the list.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The TODOs are annotated in #5929

DeviceBinaryImage::PropertyRange HostPipes;
HostPipes.init(Bin, __SYCL_PI_PROPERTY_SET_SYCL_HOST_PIPES);
return HostPipes;
}
virtual ~DeviceBinaryImage() {}

protected:
Expand Down
1 change: 1 addition & 0 deletions sycl/source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
24 changes: 24 additions & 0 deletions sycl/source/detail/host_pipe_map.cpp
Original file line number Diff line number Diff line change
@@ -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 <detail/program_manager/program_manager.hpp>

__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)
50 changes: 50 additions & 0 deletions sycl/source/detail/host_pipe_map_entry.hpp
Original file line number Diff line number Diff line change
@@ -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 <cstdint>
#include <unordered_map>

__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)
64 changes: 64 additions & 0 deletions sycl/source/detail/program_manager/program_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const std::uint32_t *>(
&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<HostPipeMapEntry>(HostPipe->Name, TypeSize);
m_HostPipes.emplace(HostPipe->Name, std::move(EntryUPtr));
}
}
}
m_DeviceImages[KSId].reset(new std::vector<RTDeviceBinaryImageUPtr>());

cacheKernelUsesAssertInfo(M, *Img);
Expand Down Expand Up @@ -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<std::mutex> 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<HostPipeMapEntry>(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<std::mutex> 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<std::mutex> 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<std::mutex> DeviceGlobalsGuard(m_DeviceGlobalsMutex);
Expand Down
22 changes: 22 additions & 0 deletions sycl/source/detail/program_manager/program_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#include <CL/sycl/detail/common.hpp>
#include <CL/sycl/detail/device_binary_image.hpp>
#include <CL/sycl/detail/export.hpp>
#include <CL/sycl/detail/host_pipe_map.hpp>
#include <CL/sycl/detail/os_util.hpp>
#include <CL/sycl/detail/pi.hpp>
#include <CL/sycl/detail/util.hpp>
#include <CL/sycl/device.hpp>
#include <CL/sycl/kernel_bundle.hpp>
#include <CL/sycl/stl.hpp>
#include <detail/device_global_map_entry.hpp>
#include <detail/host_pipe_map_entry.hpp>
#include <detail/spec_constant_impl.hpp>

#include <cstdint>
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -392,6 +406,14 @@ class ProgramManager {

/// Protects m_DeviceGlobals.
std::mutex m_DeviceGlobalsMutex;

// Maps between host_pipe identifiers and associated information.
std::unordered_map<std::string, std::unique_ptr<HostPipeMapEntry>>
m_HostPipes;
std::unordered_map<const void *, HostPipeMapEntry *> m_Ptr2HostPipe;

/// Protects m_HostPipes and m_Ptr2HostPipe.
std::mutex m_HostPipesMutex;
};
} // namespace detail
} // namespace sycl
Expand Down
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_linux.dump
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_windows.dump
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down