[llvm] [Offload] Add new llvm-liboffload-device-info tool (PR #155626)

Ross Brunton via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 28 07:53:29 PDT 2025


https://github.com/RossBrunton updated https://github.com/llvm/llvm-project/pull/155626

>From ecae36901cd3355d8b4f292dfe7d43d935dd50e1 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Wed, 27 Aug 2025 15:13:56 +0100
Subject: [PATCH 1/3] [Offload] Add new llvm-liboffload-device-info tool

This is a tool similar to llvm-offload-device-info, urinfo, etc. that
simply prints properties of all devices. The difference between this
and llvm-offload-device-info is that this uses liboffload rather than
openmp.
---
 offload/tools/CMakeLists.txt                  |   1 +
 .../liboffload-deviceinfo/CMakeLists.txt      |   9 +
 .../llvm-liboffload-device-info.cpp           | 265 ++++++++++++++++++
 3 files changed, 275 insertions(+)
 create mode 100644 offload/tools/liboffload-deviceinfo/CMakeLists.txt
 create mode 100644 offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp

diff --git a/offload/tools/CMakeLists.txt b/offload/tools/CMakeLists.txt
index 13772a4a675e5..860eed30905f4 100644
--- a/offload/tools/CMakeLists.txt
+++ b/offload/tools/CMakeLists.txt
@@ -14,3 +14,4 @@ endmacro()
 
 add_subdirectory(deviceinfo)
 add_subdirectory(kernelreplay)
+add_subdirectory(liboffload-deviceinfo)
diff --git a/offload/tools/liboffload-deviceinfo/CMakeLists.txt b/offload/tools/liboffload-deviceinfo/CMakeLists.txt
new file mode 100644
index 0000000000000..37ce65721ca0f
--- /dev/null
+++ b/offload/tools/liboffload-deviceinfo/CMakeLists.txt
@@ -0,0 +1,9 @@
+message(STATUS "Building the llvm-liboffload-device-info tool")
+
+add_openmp_tool(llvm-liboffload-device-info llvm-liboffload-device-info.cpp)
+
+llvm_update_compile_flags(llvm-liboffload-device-info)
+
+target_link_libraries(llvm-liboffload-device-info PRIVATE
+  LLVMOffload
+)
diff --git a/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp b/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
new file mode 100644
index 0000000000000..93c67af0ecea6
--- /dev/null
+++ b/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
@@ -0,0 +1,265 @@
+//===- llvm-liboffload-device-info.cpp - Print liboffload properties ------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a command line utility that, by using the new liboffload API, prints
+// all devices and properties
+//
+//===----------------------------------------------------------------------===//
+
+#include <OffloadAPI.h>
+#include <iostream>
+#include <vector>
+
+#define OFFLOAD_ERR(X)                                                         \
+  if (auto Err = X) {                                                          \
+    return Err;                                                                \
+  }
+
+enum class PrintKind {
+  NORMAL,
+  FP_FLAGS,
+};
+
+template <typename T, PrintKind PK = PrintKind::NORMAL>
+void doWrite(std::ostream &S, T &&Val) {
+  S << Val;
+}
+
+template <>
+void doWrite<ol_platform_backend_t>(std::ostream &S,
+                                    ol_platform_backend_t &&Val) {
+  switch (Val) {
+  case OL_PLATFORM_BACKEND_UNKNOWN:
+    S << "UNKNOWN";
+    break;
+  case OL_PLATFORM_BACKEND_CUDA:
+    S << "CUDA";
+    break;
+  case OL_PLATFORM_BACKEND_AMDGPU:
+    S << "AMDGPU";
+    break;
+  case OL_PLATFORM_BACKEND_HOST:
+    S << "HOST";
+    break;
+  default:
+    S << "<< INVALID >>";
+    break;
+  }
+}
+template <>
+void doWrite<ol_device_type_t>(std::ostream &S, ol_device_type_t &&Val) {
+  switch (Val) {
+  case OL_DEVICE_TYPE_GPU:
+    S << "GPU";
+    break;
+  case OL_DEVICE_TYPE_CPU:
+    S << "CPU";
+    break;
+  case OL_DEVICE_TYPE_HOST:
+    S << "HOST";
+    break;
+  default:
+    S << "<< INVALID >>";
+    break;
+  }
+}
+template <>
+void doWrite<ol_dimensions_t>(std::ostream &S, ol_dimensions_t &&Val) {
+  S << "{x: " << Val.x << ", y: " << Val.y << ", z: " << Val.z << "}";
+}
+template <>
+void doWrite<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+    std::ostream &S, ol_device_fp_capability_flags_t &&Val) {
+  S << Val << " {";
+
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT) {
+    S << " CORRECTLY_ROUNDED_DIVIDE_SQRT";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST) {
+    S << " ROUND_TO_NEAREST";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO) {
+    S << " ROUND_TO_ZERO";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF) {
+    S << " ROUND_TO_INF";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN) {
+    S << " INF_NAN";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_DENORM) {
+    S << " DENORM";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_FMA) {
+    S << " FMA";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_SOFT_FLOAT) {
+    S << " SOFT_FLOAT";
+  }
+
+  S << " }";
+}
+
+template <typename T>
+ol_result_t printPlatformValue(std::ostream &S, ol_platform_handle_t Plat,
+                               ol_platform_info_t Info, const char *Desc) {
+  S << Desc << ": ";
+
+  if constexpr (std::is_pointer_v<T>) {
+    std::vector<uint8_t> Val;
+    size_t Size;
+    OFFLOAD_ERR(olGetPlatformInfoSize(Plat, Info, &Size));
+    Val.resize(Size);
+    OFFLOAD_ERR(olGetPlatformInfo(Plat, Info, sizeof(Val), Val.data()));
+    doWrite(S, reinterpret_cast<T>(Val.data()));
+  } else {
+    T Val;
+    OFFLOAD_ERR(olGetPlatformInfo(Plat, Info, sizeof(Val), &Val));
+    doWrite(S, std::move(Val));
+  }
+  S << "\n";
+  return OL_SUCCESS;
+}
+
+template <typename T, PrintKind PK = PrintKind::NORMAL>
+ol_result_t printDeviceValue(std::ostream &S, ol_device_handle_t Dev,
+                             ol_device_info_t Info, const char *Desc,
+                             const char *Units = "") {
+  S << Desc << ": ";
+
+  if constexpr (std::is_pointer_v<T>) {
+    std::vector<uint8_t> Val;
+    size_t Size;
+    OFFLOAD_ERR(olGetDeviceInfoSize(Dev, Info, &Size));
+    Val.resize(Size);
+    OFFLOAD_ERR(olGetDeviceInfo(Dev, Info, sizeof(Val), Val.data()));
+    doWrite<T, PK>(S, reinterpret_cast<T>(Val.data()));
+  } else {
+    T Val;
+    OFFLOAD_ERR(olGetDeviceInfo(Dev, Info, sizeof(Val), &Val));
+    doWrite<T, PK>(S, std::move(Val));
+  }
+  S << Units << "\n";
+  return OL_SUCCESS;
+}
+
+ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
+  ol_platform_handle_t Platform;
+  OFFLOAD_ERR(
+      olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform), &Platform));
+
+  std::vector<char> Name;
+  size_t NameSize;
+  OFFLOAD_ERR(olGetDeviceInfoSize(D, OL_DEVICE_INFO_NAME, &NameSize))
+  Name.resize(NameSize);
+  OFFLOAD_ERR(olGetDeviceInfo(D, OL_DEVICE_INFO_NAME, NameSize, Name.data()));
+  S << "[" << Name.data() << "]\n";
+
+  OFFLOAD_ERR(printPlatformValue<const char *>(
+      S, Platform, OL_PLATFORM_INFO_NAME, "Platform Name"));
+  OFFLOAD_ERR(printPlatformValue<const char *>(
+      S, Platform, OL_PLATFORM_INFO_VENDOR_NAME, "Platform Vendor Name"));
+  OFFLOAD_ERR(printPlatformValue<const char *>(
+      S, Platform, OL_PLATFORM_INFO_VERSION, "Platform Version"));
+  OFFLOAD_ERR(printPlatformValue<ol_platform_backend_t>(
+      S, Platform, OL_PLATFORM_INFO_BACKEND, "Platform Backend"));
+
+  OFFLOAD_ERR(
+      printDeviceValue<ol_device_type_t>(S, D, OL_DEVICE_INFO_TYPE, "Type"));
+  OFFLOAD_ERR(printDeviceValue<const char *>(
+      S, D, OL_DEVICE_INFO_DRIVER_VERSION, "Driver Version"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(
+      S, D, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE, "Max Work Group Size"));
+  OFFLOAD_ERR(printDeviceValue<ol_dimensions_t>(
+      S, D, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE_PER_DIMENSION,
+      "Max Work Group Size Per Dimension"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_VENDOR_ID, "Vendor ID"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NUM_COMPUTE_UNITS,
+                                         "Num Compute Units"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(
+      S, D, OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY, "Max Clock Frequency", "MHz"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_MEMORY_CLOCK_RATE,
+                                         "Memory Clock Rate", "MHz"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_ADDRESS_BITS,
+                                         "Address Bits"));
+  OFFLOAD_ERR(printDeviceValue<uint64_t>(
+      S, D, OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE, "Max Mem Allocation Size", "B"));
+  OFFLOAD_ERR(printDeviceValue<uint64_t>(S, D, OL_DEVICE_INFO_GLOBAL_MEM_SIZE,
+                                         "Global Mem Size", "B"));
+  OFFLOAD_ERR(
+      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+          S, D, OL_DEVICE_INFO_SINGLE_FP_CONFIG,
+          "Single Precision Floating Point Capability")));
+  OFFLOAD_ERR(
+      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+          S, D, OL_DEVICE_INFO_DOUBLE_FP_CONFIG,
+          "Double Precision Floating Point Capability")));
+  OFFLOAD_ERR(
+      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+          S, D, OL_DEVICE_INFO_HALF_FP_CONFIG,
+          "Half Precision Floating Point Capability")));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR,
+                                 "Native Vector Width For Char"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT,
+                                 "Native Vector Width For Short"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D,
+                                         OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT,
+                                         "Native Vector Width For Int"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG,
+                                 "Native Vector Width For Long"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT,
+                                 "Native Vector Width For Float"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(
+      S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE,
+      "Native Vector Width For Double"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF,
+                                 "Native Vector Width For Half"));
+
+  return OL_SUCCESS;
+}
+
+ol_result_t printRoot(std::ostream &S) {
+  OFFLOAD_ERR(olInit());
+  S << "Liboffload Version: " << OL_VERSION_MAJOR << "." << OL_VERSION_MINOR
+    << "." << OL_VERSION_PATCH << "\n";
+
+  std::vector<ol_device_handle_t> Devices;
+  OFFLOAD_ERR(olIterateDevices(
+      [](ol_device_handle_t Device, void *UserData) {
+        reinterpret_cast<decltype(Devices) *>(UserData)->push_back(Device);
+        return true;
+      },
+      &Devices));
+
+  S << "Num Devices: " << Devices.size() << "\n";
+
+  for (auto &D : Devices) {
+    S << "\n";
+    OFFLOAD_ERR(printDevice(S, D));
+  }
+
+  OFFLOAD_ERR(olShutDown());
+  return OL_SUCCESS;
+}
+
+int main(int argc, char **argv) {
+  auto Err = printRoot(std::cout);
+
+  if (Err) {
+    std::cerr << "[Liboffload error " << Err->Code << "]: " << Err->Details
+              << "\n";
+    return 1;
+  }
+  return 0;
+}

>From c9f6e6db7247d523d63958846073cd021a6581e7 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Thu, 28 Aug 2025 15:51:13 +0100
Subject: [PATCH 2/3] Add product name

---
 .../liboffload-deviceinfo/llvm-liboffload-device-info.cpp  | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp b/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
index 93c67af0ecea6..22d553c368fed 100644
--- a/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
+++ b/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
@@ -155,9 +155,10 @@ ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
 
   std::vector<char> Name;
   size_t NameSize;
-  OFFLOAD_ERR(olGetDeviceInfoSize(D, OL_DEVICE_INFO_NAME, &NameSize))
+  OFFLOAD_ERR(olGetDeviceInfoSize(D, OL_DEVICE_INFO_PRODUCT_NAME, &NameSize))
   Name.resize(NameSize);
-  OFFLOAD_ERR(olGetDeviceInfo(D, OL_DEVICE_INFO_NAME, NameSize, Name.data()));
+  OFFLOAD_ERR(
+      olGetDeviceInfo(D, OL_DEVICE_INFO_PRODUCT_NAME, NameSize, Name.data()));
   S << "[" << Name.data() << "]\n";
 
   OFFLOAD_ERR(printPlatformValue<const char *>(
@@ -169,6 +170,8 @@ ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
   OFFLOAD_ERR(printPlatformValue<ol_platform_backend_t>(
       S, Platform, OL_PLATFORM_INFO_BACKEND, "Platform Backend"));
 
+  OFFLOAD_ERR(
+      printDeviceValue<const char *>(S, D, OL_DEVICE_INFO_NAME, "Name"));
   OFFLOAD_ERR(
       printDeviceValue<ol_device_type_t>(S, D, OL_DEVICE_INFO_TYPE, "Type"));
   OFFLOAD_ERR(printDeviceValue<const char *>(

>From 852dbdd0d9e9e0011ef19cd4a005cf2b0c466265 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Thu, 28 Aug 2025 15:53:12 +0100
Subject: [PATCH 3/3] Replace binary entirely

---
 offload/tools/CMakeLists.txt                  |   1 -
 offload/tools/deviceinfo/CMakeLists.txt       |   6 +-
 .../deviceinfo/llvm-offload-device-info.cpp   | 268 ++++++++++++++++--
 .../liboffload-deviceinfo/CMakeLists.txt      |   9 -
 .../llvm-liboffload-device-info.cpp           | 268 ------------------
 5 files changed, 253 insertions(+), 299 deletions(-)
 delete mode 100644 offload/tools/liboffload-deviceinfo/CMakeLists.txt
 delete mode 100644 offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp

diff --git a/offload/tools/CMakeLists.txt b/offload/tools/CMakeLists.txt
index 860eed30905f4..13772a4a675e5 100644
--- a/offload/tools/CMakeLists.txt
+++ b/offload/tools/CMakeLists.txt
@@ -14,4 +14,3 @@ endmacro()
 
 add_subdirectory(deviceinfo)
 add_subdirectory(kernelreplay)
-add_subdirectory(liboffload-deviceinfo)
diff --git a/offload/tools/deviceinfo/CMakeLists.txt b/offload/tools/deviceinfo/CMakeLists.txt
index 3787c12f940a6..cc2d0a6add8b9 100644
--- a/offload/tools/deviceinfo/CMakeLists.txt
+++ b/offload/tools/deviceinfo/CMakeLists.txt
@@ -4,10 +4,6 @@ add_openmp_tool(llvm-offload-device-info llvm-offload-device-info.cpp)
 
 llvm_update_compile_flags(llvm-offload-device-info)
 
-target_include_directories(llvm-offload-device-info PRIVATE
-  ${LIBOMPTARGET_INCLUDE_DIR}
-)
 target_link_libraries(llvm-offload-device-info PRIVATE
-  omp
-  omptarget
+  LLVMOffload
 )
diff --git a/offload/tools/deviceinfo/llvm-offload-device-info.cpp b/offload/tools/deviceinfo/llvm-offload-device-info.cpp
index 2228fbf3ec173..22d553c368fed 100644
--- a/offload/tools/deviceinfo/llvm-offload-device-info.cpp
+++ b/offload/tools/deviceinfo/llvm-offload-device-info.cpp
@@ -1,4 +1,4 @@
-//===- llvm-offload-device-info.cpp - Device info as seen by LLVM/Offload -===//
+//===- llvm-liboffload-device-info.cpp - Print liboffload properties ------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,27 +6,263 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This is a command line utility that, by using LLVM/Offload, and the device
-// plugins, list devices information as seen by the runtime.
+// This is a command line utility that, by using the new liboffload API, prints
+// all devices and properties
 //
 //===----------------------------------------------------------------------===//
 
-#include "omptarget.h"
-#include <cstdio>
+#include <OffloadAPI.h>
+#include <iostream>
+#include <vector>
 
-int main(int argc, char **argv) {
-  __tgt_bin_desc EmptyDesc = {0, nullptr, nullptr, nullptr};
-  __tgt_register_lib(&EmptyDesc);
-  __tgt_init_all_rtls();
+#define OFFLOAD_ERR(X)                                                         \
+  if (auto Err = X) {                                                          \
+    return Err;                                                                \
+  }
+
+enum class PrintKind {
+  NORMAL,
+  FP_FLAGS,
+};
+
+template <typename T, PrintKind PK = PrintKind::NORMAL>
+void doWrite(std::ostream &S, T &&Val) {
+  S << Val;
+}
+
+template <>
+void doWrite<ol_platform_backend_t>(std::ostream &S,
+                                    ol_platform_backend_t &&Val) {
+  switch (Val) {
+  case OL_PLATFORM_BACKEND_UNKNOWN:
+    S << "UNKNOWN";
+    break;
+  case OL_PLATFORM_BACKEND_CUDA:
+    S << "CUDA";
+    break;
+  case OL_PLATFORM_BACKEND_AMDGPU:
+    S << "AMDGPU";
+    break;
+  case OL_PLATFORM_BACKEND_HOST:
+    S << "HOST";
+    break;
+  default:
+    S << "<< INVALID >>";
+    break;
+  }
+}
+template <>
+void doWrite<ol_device_type_t>(std::ostream &S, ol_device_type_t &&Val) {
+  switch (Val) {
+  case OL_DEVICE_TYPE_GPU:
+    S << "GPU";
+    break;
+  case OL_DEVICE_TYPE_CPU:
+    S << "CPU";
+    break;
+  case OL_DEVICE_TYPE_HOST:
+    S << "HOST";
+    break;
+  default:
+    S << "<< INVALID >>";
+    break;
+  }
+}
+template <>
+void doWrite<ol_dimensions_t>(std::ostream &S, ol_dimensions_t &&Val) {
+  S << "{x: " << Val.x << ", y: " << Val.y << ", z: " << Val.z << "}";
+}
+template <>
+void doWrite<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+    std::ostream &S, ol_device_fp_capability_flags_t &&Val) {
+  S << Val << " {";
+
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT) {
+    S << " CORRECTLY_ROUNDED_DIVIDE_SQRT";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST) {
+    S << " ROUND_TO_NEAREST";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO) {
+    S << " ROUND_TO_ZERO";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF) {
+    S << " ROUND_TO_INF";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN) {
+    S << " INF_NAN";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_DENORM) {
+    S << " DENORM";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_FMA) {
+    S << " FMA";
+  }
+  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_SOFT_FLOAT) {
+    S << " SOFT_FLOAT";
+  }
+
+  S << " }";
+}
 
-  printf("Found %d devices:\n", omp_get_num_devices());
-  for (int Dev = 0; Dev < omp_get_num_devices(); Dev++) {
-    printf("  Device %d:\n", Dev);
-    if (!__tgt_print_device_info(Dev))
-      printf("    print_device_info not implemented\n");
-    printf("\n");
+template <typename T>
+ol_result_t printPlatformValue(std::ostream &S, ol_platform_handle_t Plat,
+                               ol_platform_info_t Info, const char *Desc) {
+  S << Desc << ": ";
+
+  if constexpr (std::is_pointer_v<T>) {
+    std::vector<uint8_t> Val;
+    size_t Size;
+    OFFLOAD_ERR(olGetPlatformInfoSize(Plat, Info, &Size));
+    Val.resize(Size);
+    OFFLOAD_ERR(olGetPlatformInfo(Plat, Info, sizeof(Val), Val.data()));
+    doWrite(S, reinterpret_cast<T>(Val.data()));
+  } else {
+    T Val;
+    OFFLOAD_ERR(olGetPlatformInfo(Plat, Info, sizeof(Val), &Val));
+    doWrite(S, std::move(Val));
+  }
+  S << "\n";
+  return OL_SUCCESS;
+}
+
+template <typename T, PrintKind PK = PrintKind::NORMAL>
+ol_result_t printDeviceValue(std::ostream &S, ol_device_handle_t Dev,
+                             ol_device_info_t Info, const char *Desc,
+                             const char *Units = "") {
+  S << Desc << ": ";
+
+  if constexpr (std::is_pointer_v<T>) {
+    std::vector<uint8_t> Val;
+    size_t Size;
+    OFFLOAD_ERR(olGetDeviceInfoSize(Dev, Info, &Size));
+    Val.resize(Size);
+    OFFLOAD_ERR(olGetDeviceInfo(Dev, Info, sizeof(Val), Val.data()));
+    doWrite<T, PK>(S, reinterpret_cast<T>(Val.data()));
+  } else {
+    T Val;
+    OFFLOAD_ERR(olGetDeviceInfo(Dev, Info, sizeof(Val), &Val));
+    doWrite<T, PK>(S, std::move(Val));
+  }
+  S << Units << "\n";
+  return OL_SUCCESS;
+}
+
+ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
+  ol_platform_handle_t Platform;
+  OFFLOAD_ERR(
+      olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform), &Platform));
+
+  std::vector<char> Name;
+  size_t NameSize;
+  OFFLOAD_ERR(olGetDeviceInfoSize(D, OL_DEVICE_INFO_PRODUCT_NAME, &NameSize))
+  Name.resize(NameSize);
+  OFFLOAD_ERR(
+      olGetDeviceInfo(D, OL_DEVICE_INFO_PRODUCT_NAME, NameSize, Name.data()));
+  S << "[" << Name.data() << "]\n";
+
+  OFFLOAD_ERR(printPlatformValue<const char *>(
+      S, Platform, OL_PLATFORM_INFO_NAME, "Platform Name"));
+  OFFLOAD_ERR(printPlatformValue<const char *>(
+      S, Platform, OL_PLATFORM_INFO_VENDOR_NAME, "Platform Vendor Name"));
+  OFFLOAD_ERR(printPlatformValue<const char *>(
+      S, Platform, OL_PLATFORM_INFO_VERSION, "Platform Version"));
+  OFFLOAD_ERR(printPlatformValue<ol_platform_backend_t>(
+      S, Platform, OL_PLATFORM_INFO_BACKEND, "Platform Backend"));
+
+  OFFLOAD_ERR(
+      printDeviceValue<const char *>(S, D, OL_DEVICE_INFO_NAME, "Name"));
+  OFFLOAD_ERR(
+      printDeviceValue<ol_device_type_t>(S, D, OL_DEVICE_INFO_TYPE, "Type"));
+  OFFLOAD_ERR(printDeviceValue<const char *>(
+      S, D, OL_DEVICE_INFO_DRIVER_VERSION, "Driver Version"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(
+      S, D, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE, "Max Work Group Size"));
+  OFFLOAD_ERR(printDeviceValue<ol_dimensions_t>(
+      S, D, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE_PER_DIMENSION,
+      "Max Work Group Size Per Dimension"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_VENDOR_ID, "Vendor ID"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NUM_COMPUTE_UNITS,
+                                         "Num Compute Units"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(
+      S, D, OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY, "Max Clock Frequency", "MHz"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_MEMORY_CLOCK_RATE,
+                                         "Memory Clock Rate", "MHz"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_ADDRESS_BITS,
+                                         "Address Bits"));
+  OFFLOAD_ERR(printDeviceValue<uint64_t>(
+      S, D, OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE, "Max Mem Allocation Size", "B"));
+  OFFLOAD_ERR(printDeviceValue<uint64_t>(S, D, OL_DEVICE_INFO_GLOBAL_MEM_SIZE,
+                                         "Global Mem Size", "B"));
+  OFFLOAD_ERR(
+      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+          S, D, OL_DEVICE_INFO_SINGLE_FP_CONFIG,
+          "Single Precision Floating Point Capability")));
+  OFFLOAD_ERR(
+      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+          S, D, OL_DEVICE_INFO_DOUBLE_FP_CONFIG,
+          "Double Precision Floating Point Capability")));
+  OFFLOAD_ERR(
+      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
+          S, D, OL_DEVICE_INFO_HALF_FP_CONFIG,
+          "Half Precision Floating Point Capability")));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR,
+                                 "Native Vector Width For Char"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT,
+                                 "Native Vector Width For Short"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D,
+                                         OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT,
+                                         "Native Vector Width For Int"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG,
+                                 "Native Vector Width For Long"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT,
+                                 "Native Vector Width For Float"));
+  OFFLOAD_ERR(printDeviceValue<uint32_t>(
+      S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE,
+      "Native Vector Width For Double"));
+  OFFLOAD_ERR(
+      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF,
+                                 "Native Vector Width For Half"));
+
+  return OL_SUCCESS;
+}
+
+ol_result_t printRoot(std::ostream &S) {
+  OFFLOAD_ERR(olInit());
+  S << "Liboffload Version: " << OL_VERSION_MAJOR << "." << OL_VERSION_MINOR
+    << "." << OL_VERSION_PATCH << "\n";
+
+  std::vector<ol_device_handle_t> Devices;
+  OFFLOAD_ERR(olIterateDevices(
+      [](ol_device_handle_t Device, void *UserData) {
+        reinterpret_cast<decltype(Devices) *>(UserData)->push_back(Device);
+        return true;
+      },
+      &Devices));
+
+  S << "Num Devices: " << Devices.size() << "\n";
+
+  for (auto &D : Devices) {
+    S << "\n";
+    OFFLOAD_ERR(printDevice(S, D));
   }
 
-  __tgt_unregister_lib(&EmptyDesc);
+  OFFLOAD_ERR(olShutDown());
+  return OL_SUCCESS;
+}
+
+int main(int argc, char **argv) {
+  auto Err = printRoot(std::cout);
+
+  if (Err) {
+    std::cerr << "[Liboffload error " << Err->Code << "]: " << Err->Details
+              << "\n";
+    return 1;
+  }
   return 0;
 }
diff --git a/offload/tools/liboffload-deviceinfo/CMakeLists.txt b/offload/tools/liboffload-deviceinfo/CMakeLists.txt
deleted file mode 100644
index 37ce65721ca0f..0000000000000
--- a/offload/tools/liboffload-deviceinfo/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-message(STATUS "Building the llvm-liboffload-device-info tool")
-
-add_openmp_tool(llvm-liboffload-device-info llvm-liboffload-device-info.cpp)
-
-llvm_update_compile_flags(llvm-liboffload-device-info)
-
-target_link_libraries(llvm-liboffload-device-info PRIVATE
-  LLVMOffload
-)
diff --git a/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp b/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
deleted file mode 100644
index 22d553c368fed..0000000000000
--- a/offload/tools/liboffload-deviceinfo/llvm-liboffload-device-info.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-//===- llvm-liboffload-device-info.cpp - Print liboffload properties ------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a command line utility that, by using the new liboffload API, prints
-// all devices and properties
-//
-//===----------------------------------------------------------------------===//
-
-#include <OffloadAPI.h>
-#include <iostream>
-#include <vector>
-
-#define OFFLOAD_ERR(X)                                                         \
-  if (auto Err = X) {                                                          \
-    return Err;                                                                \
-  }
-
-enum class PrintKind {
-  NORMAL,
-  FP_FLAGS,
-};
-
-template <typename T, PrintKind PK = PrintKind::NORMAL>
-void doWrite(std::ostream &S, T &&Val) {
-  S << Val;
-}
-
-template <>
-void doWrite<ol_platform_backend_t>(std::ostream &S,
-                                    ol_platform_backend_t &&Val) {
-  switch (Val) {
-  case OL_PLATFORM_BACKEND_UNKNOWN:
-    S << "UNKNOWN";
-    break;
-  case OL_PLATFORM_BACKEND_CUDA:
-    S << "CUDA";
-    break;
-  case OL_PLATFORM_BACKEND_AMDGPU:
-    S << "AMDGPU";
-    break;
-  case OL_PLATFORM_BACKEND_HOST:
-    S << "HOST";
-    break;
-  default:
-    S << "<< INVALID >>";
-    break;
-  }
-}
-template <>
-void doWrite<ol_device_type_t>(std::ostream &S, ol_device_type_t &&Val) {
-  switch (Val) {
-  case OL_DEVICE_TYPE_GPU:
-    S << "GPU";
-    break;
-  case OL_DEVICE_TYPE_CPU:
-    S << "CPU";
-    break;
-  case OL_DEVICE_TYPE_HOST:
-    S << "HOST";
-    break;
-  default:
-    S << "<< INVALID >>";
-    break;
-  }
-}
-template <>
-void doWrite<ol_dimensions_t>(std::ostream &S, ol_dimensions_t &&Val) {
-  S << "{x: " << Val.x << ", y: " << Val.y << ", z: " << Val.z << "}";
-}
-template <>
-void doWrite<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
-    std::ostream &S, ol_device_fp_capability_flags_t &&Val) {
-  S << Val << " {";
-
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_CORRECTLY_ROUNDED_DIVIDE_SQRT) {
-    S << " CORRECTLY_ROUNDED_DIVIDE_SQRT";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_NEAREST) {
-    S << " ROUND_TO_NEAREST";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_ZERO) {
-    S << " ROUND_TO_ZERO";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_ROUND_TO_INF) {
-    S << " ROUND_TO_INF";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_INF_NAN) {
-    S << " INF_NAN";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_DENORM) {
-    S << " DENORM";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_FMA) {
-    S << " FMA";
-  }
-  if (Val & OL_DEVICE_FP_CAPABILITY_FLAG_SOFT_FLOAT) {
-    S << " SOFT_FLOAT";
-  }
-
-  S << " }";
-}
-
-template <typename T>
-ol_result_t printPlatformValue(std::ostream &S, ol_platform_handle_t Plat,
-                               ol_platform_info_t Info, const char *Desc) {
-  S << Desc << ": ";
-
-  if constexpr (std::is_pointer_v<T>) {
-    std::vector<uint8_t> Val;
-    size_t Size;
-    OFFLOAD_ERR(olGetPlatformInfoSize(Plat, Info, &Size));
-    Val.resize(Size);
-    OFFLOAD_ERR(olGetPlatformInfo(Plat, Info, sizeof(Val), Val.data()));
-    doWrite(S, reinterpret_cast<T>(Val.data()));
-  } else {
-    T Val;
-    OFFLOAD_ERR(olGetPlatformInfo(Plat, Info, sizeof(Val), &Val));
-    doWrite(S, std::move(Val));
-  }
-  S << "\n";
-  return OL_SUCCESS;
-}
-
-template <typename T, PrintKind PK = PrintKind::NORMAL>
-ol_result_t printDeviceValue(std::ostream &S, ol_device_handle_t Dev,
-                             ol_device_info_t Info, const char *Desc,
-                             const char *Units = "") {
-  S << Desc << ": ";
-
-  if constexpr (std::is_pointer_v<T>) {
-    std::vector<uint8_t> Val;
-    size_t Size;
-    OFFLOAD_ERR(olGetDeviceInfoSize(Dev, Info, &Size));
-    Val.resize(Size);
-    OFFLOAD_ERR(olGetDeviceInfo(Dev, Info, sizeof(Val), Val.data()));
-    doWrite<T, PK>(S, reinterpret_cast<T>(Val.data()));
-  } else {
-    T Val;
-    OFFLOAD_ERR(olGetDeviceInfo(Dev, Info, sizeof(Val), &Val));
-    doWrite<T, PK>(S, std::move(Val));
-  }
-  S << Units << "\n";
-  return OL_SUCCESS;
-}
-
-ol_result_t printDevice(std::ostream &S, ol_device_handle_t D) {
-  ol_platform_handle_t Platform;
-  OFFLOAD_ERR(
-      olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform), &Platform));
-
-  std::vector<char> Name;
-  size_t NameSize;
-  OFFLOAD_ERR(olGetDeviceInfoSize(D, OL_DEVICE_INFO_PRODUCT_NAME, &NameSize))
-  Name.resize(NameSize);
-  OFFLOAD_ERR(
-      olGetDeviceInfo(D, OL_DEVICE_INFO_PRODUCT_NAME, NameSize, Name.data()));
-  S << "[" << Name.data() << "]\n";
-
-  OFFLOAD_ERR(printPlatformValue<const char *>(
-      S, Platform, OL_PLATFORM_INFO_NAME, "Platform Name"));
-  OFFLOAD_ERR(printPlatformValue<const char *>(
-      S, Platform, OL_PLATFORM_INFO_VENDOR_NAME, "Platform Vendor Name"));
-  OFFLOAD_ERR(printPlatformValue<const char *>(
-      S, Platform, OL_PLATFORM_INFO_VERSION, "Platform Version"));
-  OFFLOAD_ERR(printPlatformValue<ol_platform_backend_t>(
-      S, Platform, OL_PLATFORM_INFO_BACKEND, "Platform Backend"));
-
-  OFFLOAD_ERR(
-      printDeviceValue<const char *>(S, D, OL_DEVICE_INFO_NAME, "Name"));
-  OFFLOAD_ERR(
-      printDeviceValue<ol_device_type_t>(S, D, OL_DEVICE_INFO_TYPE, "Type"));
-  OFFLOAD_ERR(printDeviceValue<const char *>(
-      S, D, OL_DEVICE_INFO_DRIVER_VERSION, "Driver Version"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(
-      S, D, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE, "Max Work Group Size"));
-  OFFLOAD_ERR(printDeviceValue<ol_dimensions_t>(
-      S, D, OL_DEVICE_INFO_MAX_WORK_GROUP_SIZE_PER_DIMENSION,
-      "Max Work Group Size Per Dimension"));
-  OFFLOAD_ERR(
-      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_VENDOR_ID, "Vendor ID"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NUM_COMPUTE_UNITS,
-                                         "Num Compute Units"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(
-      S, D, OL_DEVICE_INFO_MAX_CLOCK_FREQUENCY, "Max Clock Frequency", "MHz"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_MEMORY_CLOCK_RATE,
-                                         "Memory Clock Rate", "MHz"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_ADDRESS_BITS,
-                                         "Address Bits"));
-  OFFLOAD_ERR(printDeviceValue<uint64_t>(
-      S, D, OL_DEVICE_INFO_MAX_MEM_ALLOC_SIZE, "Max Mem Allocation Size", "B"));
-  OFFLOAD_ERR(printDeviceValue<uint64_t>(S, D, OL_DEVICE_INFO_GLOBAL_MEM_SIZE,
-                                         "Global Mem Size", "B"));
-  OFFLOAD_ERR(
-      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
-          S, D, OL_DEVICE_INFO_SINGLE_FP_CONFIG,
-          "Single Precision Floating Point Capability")));
-  OFFLOAD_ERR(
-      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
-          S, D, OL_DEVICE_INFO_DOUBLE_FP_CONFIG,
-          "Double Precision Floating Point Capability")));
-  OFFLOAD_ERR(
-      (printDeviceValue<ol_device_fp_capability_flags_t, PrintKind::FP_FLAGS>(
-          S, D, OL_DEVICE_INFO_HALF_FP_CONFIG,
-          "Half Precision Floating Point Capability")));
-  OFFLOAD_ERR(
-      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR,
-                                 "Native Vector Width For Char"));
-  OFFLOAD_ERR(
-      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT,
-                                 "Native Vector Width For Short"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(S, D,
-                                         OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT,
-                                         "Native Vector Width For Int"));
-  OFFLOAD_ERR(
-      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG,
-                                 "Native Vector Width For Long"));
-  OFFLOAD_ERR(
-      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT,
-                                 "Native Vector Width For Float"));
-  OFFLOAD_ERR(printDeviceValue<uint32_t>(
-      S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE,
-      "Native Vector Width For Double"));
-  OFFLOAD_ERR(
-      printDeviceValue<uint32_t>(S, D, OL_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF,
-                                 "Native Vector Width For Half"));
-
-  return OL_SUCCESS;
-}
-
-ol_result_t printRoot(std::ostream &S) {
-  OFFLOAD_ERR(olInit());
-  S << "Liboffload Version: " << OL_VERSION_MAJOR << "." << OL_VERSION_MINOR
-    << "." << OL_VERSION_PATCH << "\n";
-
-  std::vector<ol_device_handle_t> Devices;
-  OFFLOAD_ERR(olIterateDevices(
-      [](ol_device_handle_t Device, void *UserData) {
-        reinterpret_cast<decltype(Devices) *>(UserData)->push_back(Device);
-        return true;
-      },
-      &Devices));
-
-  S << "Num Devices: " << Devices.size() << "\n";
-
-  for (auto &D : Devices) {
-    S << "\n";
-    OFFLOAD_ERR(printDevice(S, D));
-  }
-
-  OFFLOAD_ERR(olShutDown());
-  return OL_SUCCESS;
-}
-
-int main(int argc, char **argv) {
-  auto Err = printRoot(std::cout);
-
-  if (Err) {
-    std::cerr << "[Liboffload error " << Err->Code << "]: " << Err->Details
-              << "\n";
-    return 1;
-  }
-  return 0;
-}



More information about the llvm-commits mailing list