Skip to content

Commit 7102592

Browse files
authored
[Offload] Repair and rename llvm-omp-device-info (to -offload-) (#100309)
The `llvm-omp-device-info` tool is very handy, but broke due to the lazy evaluation of devices. This repairs the functionality and adds a test. The tool is also renamed into `llvm-offload-device-info` as `-omp-` is going away.
1 parent 5a53add commit 7102592

File tree

9 files changed

+100
-54
lines changed

9 files changed

+100
-54
lines changed

offload/cmake/OpenMPTesting.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ function(find_standalone_test_dependencies)
3737
return()
3838
endif()
3939

40+
find_program(OFFLOAD_DEVICE_INFO_EXECUTABLE
41+
NAMES llvm-offload-device-info
42+
PATHS ${OPENMP_LLVM_TOOLS_DIR})
43+
if (NOT OFFLOAD_DEVICE_INFO_EXECUTABLE)
44+
message(STATUS "Cannot find 'llvm-offload-device-info'.")
45+
message(STATUS "Please put 'not' in your PATH, set OFFLOAD_DEVICE_INFO_EXECUTABLE to its full path, or point OPENMP_LLVM_TOOLS_DIR to its directory.")
46+
message(WARNING "The check targets will not be available!")
47+
set(ENABLE_CHECK_TARGETS FALSE PARENT_SCOPE)
48+
return()
49+
endif()
50+
4051
find_program(OPENMP_NOT_EXECUTABLE
4152
NAMES not
4253
PATHS ${OPENMP_LLVM_TOOLS_DIR})
@@ -71,6 +82,7 @@ else()
7182
set(OPENMP_FILECHECK_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/FileCheck)
7283
endif()
7384
set(OPENMP_NOT_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/not)
85+
set(OFFLOAD_DEVICE_INFO_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-offload-device-info)
7486
endif()
7587

7688
# Macro to extract information about compiler from file. (no own scope)

offload/include/PluginManager.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,14 @@ struct PluginManager {
113113
return Devices.getExclusiveAccessor();
114114
}
115115

116-
// Initialize all plugins.
117-
void initAllPlugins();
116+
/// Initialize \p Plugin. Returns true on success.
117+
bool initializePlugin(GenericPluginTy &Plugin);
118+
119+
/// Initialize device \p DeviceNo of \p Plugin. Returns true on success.
120+
bool initializeDevice(GenericPluginTy &Plugin, int32_t DeviceId);
121+
122+
/// Eagerly initialize all plugins and their devices.
123+
void initializeAllDevices();
118124

119125
/// Iterator range for all plugins (in use or not, but always valid).
120126
auto plugins() { return llvm::make_pointee_range(Plugins); }

offload/src/PluginManager.cpp

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "PluginManager.h"
1414
#include "Shared/Debug.h"
1515
#include "Shared/Profile.h"
16+
#include "device.h"
1617

1718
#include "llvm/Support/Error.h"
1819
#include "llvm/Support/ErrorHandling.h"
@@ -60,15 +61,61 @@ void PluginManager::deinit() {
6061
DP("RTLs unloaded!\n");
6162
}
6263

63-
void PluginManager::initAllPlugins() {
64-
for (auto &R : plugins()) {
65-
if (auto Err = R.init()) {
66-
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
67-
DP("Failed to init plugin: %s\n", InfoMsg.c_str());
64+
bool PluginManager::initializePlugin(GenericPluginTy &Plugin) {
65+
if (Plugin.is_initialized())
66+
return true;
67+
68+
if (auto Err = Plugin.init()) {
69+
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
70+
DP("Failed to init plugin: %s\n", InfoMsg.c_str());
71+
return false;
72+
}
73+
74+
DP("Registered plugin %s with %d visible device(s)\n", Plugin.getName(),
75+
Plugin.number_of_devices());
76+
return true;
77+
}
78+
79+
bool PluginManager::initializeDevice(GenericPluginTy &Plugin,
80+
int32_t DeviceId) {
81+
if (Plugin.is_device_initialized(DeviceId))
82+
return true;
83+
84+
// Initialize the device information for the RTL we are about to use.
85+
auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
86+
87+
int32_t UserId = ExclusiveDevicesAccessor->size();
88+
89+
// Set the device identifier offset in the plugin.
90+
#ifdef OMPT_SUPPORT
91+
Plugin.set_device_identifier(UserId, DeviceId);
92+
#endif
93+
94+
auto Device = std::make_unique<DeviceTy>(&Plugin, UserId, DeviceId);
95+
if (auto Err = Device->init()) {
96+
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
97+
DP("Failed to init device %d: %s\n", DeviceId, InfoMsg.c_str());
98+
return false;
99+
}
100+
101+
ExclusiveDevicesAccessor->push_back(std::move(Device));
102+
103+
// We need to map between the plugin's device identifier and the one
104+
// that OpenMP will use.
105+
PM->DeviceIds[std::make_pair(&Plugin, DeviceId)] = UserId;
106+
107+
return true;
108+
}
109+
110+
void PluginManager::initializeAllDevices() {
111+
for (auto &Plugin : plugins()) {
112+
if (!initializePlugin(Plugin))
68113
continue;
114+
115+
for (int32_t DeviceId = 0; DeviceId < Plugin.number_of_devices();
116+
++DeviceId) {
117+
initializeDevice(Plugin, DeviceId);
69118
}
70-
DP("Registered plugin %s with %d visible device(s)\n", R.getName(),
71-
R.number_of_devices());
72119
}
73120
}
74121

@@ -94,19 +141,12 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
94141

95142
// Scan the RTLs that have associated images until we find one that supports
96143
// the current image.
97-
for (auto &R : PM->plugins()) {
144+
for (auto &R : plugins()) {
98145
if (!R.is_plugin_compatible(Img))
99146
continue;
100147

101-
if (!R.is_initialized()) {
102-
if (auto Err = R.init()) {
103-
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
104-
DP("Failed to init plugin: %s\n", InfoMsg.c_str());
105-
continue;
106-
}
107-
DP("Registered plugin %s with %d visible device(s)\n", R.getName(),
108-
R.number_of_devices());
109-
}
148+
if (!initializePlugin(R))
149+
continue;
110150

111151
if (!R.number_of_devices()) {
112152
DP("Skipping plugin %s with no visible devices\n", R.getName());
@@ -120,30 +160,8 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
120160
DP("Image " DPxMOD " is compatible with RTL %s device %d!\n",
121161
DPxPTR(Img->ImageStart), R.getName(), DeviceId);
122162

123-
if (!R.is_device_initialized(DeviceId)) {
124-
// Initialize the device information for the RTL we are about to use.
125-
auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
126-
127-
int32_t UserId = ExclusiveDevicesAccessor->size();
128-
129-
// Set the device identifier offset in the plugin.
130-
#ifdef OMPT_SUPPORT
131-
R.set_device_identifier(UserId, DeviceId);
132-
#endif
133-
134-
auto Device = std::make_unique<DeviceTy>(&R, UserId, DeviceId);
135-
if (auto Err = Device->init()) {
136-
[[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
137-
DP("Failed to init device %d: %s\n", DeviceId, InfoMsg.c_str());
138-
continue;
139-
}
140-
141-
ExclusiveDevicesAccessor->push_back(std::move(Device));
142-
143-
// We need to map between the plugin's device identifier and the one
144-
// that OpenMP will use.
145-
PM->DeviceIds[std::make_pair(&R, DeviceId)] = UserId;
146-
}
163+
if (!initializeDevice(R, DeviceId))
164+
continue;
147165

148166
// Initialize (if necessary) translation table for this library.
149167
PM->TrlTblMtx.lock();
@@ -219,7 +237,7 @@ void PluginManager::unregisterLib(__tgt_bin_desc *Desc) {
219237

220238
// Scan the RTLs that have associated images until we find one that supports
221239
// the current image. We only need to scan RTLs that are already being used.
222-
for (auto &R : PM->plugins()) {
240+
for (auto &R : plugins()) {
223241
if (R.is_initialized())
224242
continue;
225243

offload/src/interface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ EXTERN void __tgt_register_lib(__tgt_bin_desc *Desc) {
5757
/// Initialize all available devices without registering any image
5858
EXTERN void __tgt_init_all_rtls() {
5959
assert(PM && "Runtime not initialized");
60-
PM->initAllPlugins();
60+
PM->initializeAllDevices();
6161
}
6262

6363
////////////////////////////////////////////////////////////////////////////////

offload/test/lit.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,5 @@ config.substitutions.append(("%flags_clang", config.test_flags_clang))
408408
config.substitutions.append(("%flags_flang", config.test_flags_flang))
409409
config.substitutions.append(("%flags", config.test_flags))
410410
config.substitutions.append(("%not", config.libomptarget_not))
411+
config.substitutions.append(("%offload-device-info",
412+
config.offload_device_info))

offload/test/lit.site.cfg.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ config.libomptarget_all_targets = "@LIBOMPTARGET_ALL_TARGETS@".split()
2323
config.libomptarget_current_target = "@CURRENT_TARGET@"
2424
config.libomptarget_filecheck = "@OPENMP_FILECHECK_EXECUTABLE@"
2525
config.libomptarget_not = "@OPENMP_NOT_EXECUTABLE@"
26+
config.offload_device_info = "@OFFLOAD_DEVICE_INFO_EXECUTABLE@"
2627
config.libomptarget_debug = @LIBOMPTARGET_DEBUG@
2728
config.has_libomptarget_ompt = @LIBOMPTARGET_OMPT_SUPPORT@
2829
config.libomptarget_has_libc = @LIBOMPTARGET_GPU_LIBC_SUPPORT@
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %offload-device-info | %fcheck-generic
2+
//
3+
// Just check any device was found and something is printed
4+
//
5+
// CHECK: Found {{[1-9].*}} devices:
6+
// CHECK: Device 0:
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
message(STATUS "Building the llvm-omp-device-info tool")
1+
message(STATUS "Building the llvm-offload-device-info tool")
22

3-
add_openmp_tool(llvm-omp-device-info llvm-omp-device-info.cpp)
3+
add_openmp_tool(llvm-offload-device-info llvm-offload-device-info.cpp)
44

5-
llvm_update_compile_flags(llvm-omp-device-info)
5+
llvm_update_compile_flags(llvm-offload-device-info)
66

7-
target_include_directories(llvm-omp-device-info PRIVATE
7+
target_include_directories(llvm-offload-device-info PRIVATE
88
${LIBOMPTARGET_INCLUDE_DIR}
99
)
10-
target_link_libraries(llvm-omp-device-info PRIVATE
10+
target_link_libraries(llvm-offload-device-info PRIVATE
1111
omp
1212
omptarget
1313
)

offload/tools/deviceinfo/llvm-omp-device-info.cpp renamed to offload/tools/deviceinfo/llvm-offload-device-info.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
//===- llvm-omp-device-info.cpp - Obtain device info as seen from OpenMP --===//
1+
//===- llvm-offload-device-info.cpp - Device info as seen by LLVM/Offload -===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This is a command line utility that, by using Libomptarget, and the device
10-
// plugins, list devices information as seen from the OpenMP Runtime.
9+
// This is a command line utility that, by using LLVM/Offload, and the device
10+
// plugins, list devices information as seen by the runtime.
1111
//
1212
//===----------------------------------------------------------------------===//
1313

@@ -19,8 +19,9 @@ int main(int argc, char **argv) {
1919
__tgt_register_lib(&EmptyDesc);
2020
__tgt_init_all_rtls();
2121

22+
printf("Found %d devices:\n", omp_get_num_devices());
2223
for (int Dev = 0; Dev < omp_get_num_devices(); Dev++) {
23-
printf("Device (%d):\n", Dev);
24+
printf(" Device %d:\n", Dev);
2425
if (!__tgt_print_device_info(Dev))
2526
printf(" print_device_info not implemented\n");
2627
printf("\n");

0 commit comments

Comments
 (0)