Skip to content

Commit 39f19f2

Browse files
authored
[Offload] Store device info tree in device handle (#145913)
Rather than creating a new device info tree for each call to `olGetDeviceInfo`, we instead do it on device initialisation. As well as improving performance, this fixes a few lifetime issues with returned strings. This does unfortunately mean that device information is immutable, but hopefully that shouldn't be a problem for any queries we want to implement. This also meant allowing offload initialization to fail, which it can now do.
1 parent 102cf1b commit 39f19f2

File tree

1 file changed

+21
-20
lines changed

1 file changed

+21
-20
lines changed

offload/liboffload/src/OffloadImpl.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,19 @@ using namespace error;
4343
// interface.
4444
struct ol_device_impl_t {
4545
ol_device_impl_t(int DeviceNum, GenericDeviceTy *Device,
46-
ol_platform_handle_t Platform)
47-
: DeviceNum(DeviceNum), Device(Device), Platform(Platform) {}
46+
ol_platform_handle_t Platform, InfoTreeNode &&DevInfo)
47+
: DeviceNum(DeviceNum), Device(Device), Platform(Platform),
48+
Info(std::forward<InfoTreeNode>(DevInfo)) {}
4849
int DeviceNum;
4950
GenericDeviceTy *Device;
5051
ol_platform_handle_t Platform;
52+
InfoTreeNode Info;
5153
};
5254

5355
struct ol_platform_impl_t {
5456
ol_platform_impl_t(std::unique_ptr<GenericPluginTy> Plugin,
55-
std::vector<ol_device_impl_t> Devices,
5657
ol_platform_backend_t BackendType)
57-
: Plugin(std::move(Plugin)), Devices(Devices), BackendType(BackendType) {}
58+
: Plugin(std::move(Plugin)), BackendType(BackendType) {}
5859
std::unique_ptr<GenericPluginTy> Plugin;
5960
std::vector<ol_device_impl_t> Devices;
6061
ol_platform_backend_t BackendType;
@@ -144,15 +145,14 @@ constexpr ol_platform_backend_t pluginNameToBackend(StringRef Name) {
144145
#define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
145146
#include "Shared/Targets.def"
146147

147-
void initPlugins() {
148+
Error initPlugins() {
148149
auto *Context = new OffloadContext{};
149150

150151
// Attempt to create an instance of each supported plugin.
151152
#define PLUGIN_TARGET(Name) \
152153
do { \
153154
Context->Platforms.emplace_back(ol_platform_impl_t{ \
154155
std::unique_ptr<GenericPluginTy>(createPlugin_##Name()), \
155-
{}, \
156156
pluginNameToBackend(#Name)}); \
157157
} while (false);
158158
#include "Shared/Targets.def"
@@ -167,31 +167,39 @@ void initPlugins() {
167167
for (auto DevNum = 0; DevNum < Platform.Plugin->number_of_devices();
168168
DevNum++) {
169169
if (Platform.Plugin->init_device(DevNum) == OFFLOAD_SUCCESS) {
170-
Platform.Devices.emplace_back(ol_device_impl_t{
171-
DevNum, &Platform.Plugin->getDevice(DevNum), &Platform});
170+
auto Device = &Platform.Plugin->getDevice(DevNum);
171+
auto Info = Device->obtainInfoImpl();
172+
if (auto Err = Info.takeError())
173+
return Err;
174+
Platform.Devices.emplace_back(DevNum, Device, &Platform,
175+
std::move(*Info));
172176
}
173177
}
174178
}
175179

176180
// Add the special host device
177181
auto &HostPlatform = Context->Platforms.emplace_back(
178-
ol_platform_impl_t{nullptr,
179-
{ol_device_impl_t{-1, nullptr, nullptr}},
180-
OL_PLATFORM_BACKEND_HOST});
182+
ol_platform_impl_t{nullptr, OL_PLATFORM_BACKEND_HOST});
183+
HostPlatform.Devices.emplace_back(-1, nullptr, nullptr, InfoTreeNode{});
181184
Context->HostDevice()->Platform = &HostPlatform;
182185

183186
Context->TracingEnabled = std::getenv("OFFLOAD_TRACE");
184187
Context->ValidationEnabled = !std::getenv("OFFLOAD_DISABLE_VALIDATION");
185188

186189
OffloadContextVal = Context;
190+
191+
return Plugin::success();
187192
}
188193

189194
// TODO: We can properly reference count here and manage the resources in a more
190195
// clever way
191196
Error olInit_impl() {
192197
static std::once_flag InitFlag;
193-
std::call_once(InitFlag, initPlugins);
198+
std::optional<Error> InitResult{};
199+
std::call_once(InitFlag, [&] { InitResult = initPlugins(); });
194200

201+
if (InitResult)
202+
return std::move(*InitResult);
195203
return Error::success();
196204
}
197205
Error olShutDown_impl() { return Error::success(); }
@@ -250,15 +258,8 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
250258
if (Device == OffloadContext::get().HostDevice())
251259
return "Host";
252260

253-
if (!Device->Device)
254-
return "";
255-
256-
auto Info = Device->Device->obtainInfoImpl();
257-
if (auto Err = Info.takeError())
258-
return "";
259-
260261
for (auto Name : Names) {
261-
if (auto Entry = Info->get(Name))
262+
if (auto Entry = Device->Info.get(Name))
262263
return std::get<std::string>((*Entry)->Value).c_str();
263264
}
264265

0 commit comments

Comments
 (0)