|
| 1 | +// Copyright (C) 2023 Intel Corporation |
| 2 | +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. |
| 3 | +// See LICENSE.TXT |
| 4 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 5 | + |
| 6 | +#include "urinfo.hpp" |
| 7 | +#include <cstdlib> |
| 8 | +#include <iostream> |
| 9 | +#include <string> |
| 10 | +#include <string_view> |
| 11 | +#include <unordered_map> |
| 12 | +#include <vector> |
| 13 | + |
| 14 | +namespace urinfo { |
| 15 | +struct app { |
| 16 | + bool verbose = false; |
| 17 | + ur_loader_config_handle_t loaderConfig = nullptr; |
| 18 | + std::vector<ur_adapter_handle_t> adapters; |
| 19 | + std::unordered_map<ur_adapter_handle_t, std::vector<ur_platform_handle_t>> |
| 20 | + adapterPlatformsMap; |
| 21 | + std::unordered_map<ur_platform_handle_t, std::vector<ur_device_handle_t>> |
| 22 | + platformDevicesMap; |
| 23 | + |
| 24 | + app(int argc, const char **argv) { |
| 25 | + parseArgs(argc, argv); |
| 26 | + UR_CHECK(urLoaderConfigCreate(&loaderConfig)); |
| 27 | + UR_CHECK(urInit(0, loaderConfig)); |
| 28 | + enumerateDevices(); |
| 29 | + } |
| 30 | + |
| 31 | + void parseArgs(int argc, const char **argv) { |
| 32 | + static const char *usage = R"(usage: %s [-h] [-v] [-V] |
| 33 | +
|
| 34 | +This tool enumerates Unified Runtime layers, adapters, platforms, and |
| 35 | +devices which are currently visible in the local execution environment. |
| 36 | +
|
| 37 | +options: |
| 38 | + -h, --help show this help message and exit |
| 39 | + --version show version number and exit |
| 40 | + -v, --verbose print additional information |
| 41 | +)"; |
| 42 | + for (int argi = 1; argi < argc; argi++) { |
| 43 | + std::string_view arg{argv[argi]}; |
| 44 | + if (arg == "-h" || arg == "--help") { |
| 45 | + std::printf(usage, argv[0]); |
| 46 | + std::exit(0); |
| 47 | + } else if (arg == "--version") { |
| 48 | + std::printf("%s v%s\n", argv[0], UR_VERSION); |
| 49 | + std::exit(0); |
| 50 | + } else if (arg == "-v" || arg == "--verbose") { |
| 51 | + verbose = true; |
| 52 | + } else { |
| 53 | + std::fprintf(stderr, "error: invalid argument: %s\n", |
| 54 | + argv[argi]); |
| 55 | + std::fprintf(stderr, usage, argv[0]); |
| 56 | + std::exit(1); |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + void enumerateDevices() { |
| 62 | + // Enumerate adapters. |
| 63 | + uint32_t numAdapters = 0; |
| 64 | + UR_CHECK(urAdapterGet(0, nullptr, &numAdapters)); |
| 65 | + if (numAdapters == 0) { |
| 66 | + std::cout << "No adapters found.\n"; |
| 67 | + std::exit(0); |
| 68 | + } |
| 69 | + adapters.resize(numAdapters); |
| 70 | + UR_CHECK(urAdapterGet(numAdapters, adapters.data(), nullptr)); |
| 71 | + |
| 72 | + for (auto adapter : adapters) { |
| 73 | + // Enumerate platforms |
| 74 | + uint32_t numPlatforms = 0; |
| 75 | + UR_CHECK(urPlatformGet(adapters.data(), numAdapters, 0, nullptr, |
| 76 | + &numPlatforms)); |
| 77 | + if (numPlatforms == 0) { |
| 78 | + std::cout << "No platforms found.\n"; |
| 79 | + std::exit(0); |
| 80 | + } |
| 81 | + adapterPlatformsMap[adapter].resize(numAdapters); |
| 82 | + UR_CHECK(urPlatformGet(adapters.data(), numAdapters, numPlatforms, |
| 83 | + adapterPlatformsMap[adapter].data(), |
| 84 | + nullptr)); |
| 85 | + |
| 86 | + for (auto platform : adapterPlatformsMap[adapter]) { |
| 87 | + // Enumerate devices |
| 88 | + uint32_t numDevices = 0; |
| 89 | + UR_CHECK(urDeviceGet(platform, UR_DEVICE_TYPE_ALL, 0, nullptr, |
| 90 | + &numDevices)); |
| 91 | + if (numDevices == 0) { |
| 92 | + std::cout << "No devices found.\n"; |
| 93 | + continue; |
| 94 | + } |
| 95 | + platformDevicesMap[platform].resize(numDevices); |
| 96 | + UR_CHECK(urDeviceGet(platform, UR_DEVICE_TYPE_ALL, numDevices, |
| 97 | + platformDevicesMap[platform].data(), |
| 98 | + nullptr)); |
| 99 | + } |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + void printSummary() { |
| 104 | + for (size_t adapterIndex = 0; adapterIndex < adapters.size(); |
| 105 | + adapterIndex++) { |
| 106 | + auto adapter = adapters[adapterIndex]; |
| 107 | + auto &platforms = adapterPlatformsMap[adapter]; |
| 108 | + for (size_t platformIndex = 0; platformIndex < platforms.size(); |
| 109 | + platformIndex++) { |
| 110 | + auto platform = platforms[platformIndex]; |
| 111 | + auto &devices = platformDevicesMap[platform]; |
| 112 | + for (size_t deviceIndex = 0; deviceIndex < devices.size(); |
| 113 | + deviceIndex++) { |
| 114 | + auto device = devices[deviceIndex]; |
| 115 | + std::cout << "[adapter(" << adapterIndex << "," |
| 116 | + << urinfo::getAdapterBackend(adapter) << "):" |
| 117 | + << "platform(" << platformIndex << "):" |
| 118 | + << "device(" << deviceIndex << "," |
| 119 | + << urinfo::getDeviceType(device) << ")] " |
| 120 | + << urinfo::getPlatformName(platform) << ", " |
| 121 | + << urinfo::getDeviceName(device) << " " |
| 122 | + << urinfo::getDeviceVersion(device) << " " |
| 123 | + << "[" << urinfo::getDeviceDriverVersion(device) |
| 124 | + << "]\n"; |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + void printDetail() { |
| 131 | + size_t availableLayersSize = 0; |
| 132 | + UR_CHECK(urLoaderConfigGetInfo(loaderConfig, |
| 133 | + UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS, |
| 134 | + 0, nullptr, &availableLayersSize)); |
| 135 | + // TODO: Generate loader config info printer |
| 136 | + std::string availableLayers; |
| 137 | + if (availableLayersSize != 0) { |
| 138 | + availableLayers.resize(availableLayersSize); |
| 139 | + UR_CHECK(urLoaderConfigGetInfo( |
| 140 | + loaderConfig, UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS, |
| 141 | + availableLayersSize, availableLayers.data(), nullptr)); |
| 142 | + } |
| 143 | + std::cout << "\n" |
| 144 | + << "[loader]:" |
| 145 | + << "\n" |
| 146 | + << " UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS: " |
| 147 | + << availableLayers << "\n"; |
| 148 | + |
| 149 | + std::string adapterPrefix = " "; |
| 150 | + std::string platformPrefix = " "; |
| 151 | + std::string devicePrefix = " "; |
| 152 | + |
| 153 | + for (size_t adapterI = 0; adapterI < adapters.size(); adapterI++) { |
| 154 | + auto adapter = adapters[adapterI]; |
| 155 | + std::cout << "\n" |
| 156 | + << "[adapter(" << adapterI << ")]:" |
| 157 | + << "\n"; |
| 158 | + urinfo::printAdapterInfos(adapter, adapterPrefix); |
| 159 | + |
| 160 | + size_t numPlatforms = adapterPlatformsMap[adapter].size(); |
| 161 | + for (size_t platformI = 0; platformI < numPlatforms; platformI++) { |
| 162 | + auto platform = adapterPlatformsMap[adapter][platformI]; |
| 163 | + std::cout << "\n" |
| 164 | + << "[adapter(" << adapterI << ")," |
| 165 | + << "platform(" << platformI << ")]:" |
| 166 | + << "\n"; |
| 167 | + urinfo::printPlatformInfos(platform, platformPrefix); |
| 168 | + |
| 169 | + size_t numDevices = platformDevicesMap[platform].size(); |
| 170 | + for (size_t deviceI = 0; deviceI < numDevices; deviceI++) { |
| 171 | + auto device = platformDevicesMap[platform][deviceI]; |
| 172 | + std::cout << "\n" |
| 173 | + << "[adapter(" << adapterI << ")," |
| 174 | + << "platform(" << platformI << ")," |
| 175 | + << "device(" << deviceI << ")]:" |
| 176 | + << "\n"; |
| 177 | + urinfo::printDeviceInfos(device, devicePrefix); |
| 178 | + } |
| 179 | + } |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + ~app() { |
| 184 | + UR_CHECK(urLoaderConfigRelease(loaderConfig)); |
| 185 | + UR_CHECK(urTearDown(nullptr)); |
| 186 | + } |
| 187 | +}; |
| 188 | +} // namespace urinfo |
| 189 | + |
| 190 | +int main(int argc, const char **argv) { |
| 191 | + auto app = urinfo::app{argc, argv}; |
| 192 | + app.printSummary(); |
| 193 | + if (app.verbose) { |
| 194 | + app.printDetail(); |
| 195 | + } |
| 196 | + return 0; |
| 197 | +} |
0 commit comments