Skip to content

Commit

Permalink
[ur] Introduce urinfo tool
Browse files Browse the repository at this point in the history
`urinfo` is a command-line tool for inspecting the current execution
environment:

```console
$ build/bin/urinfo --help
usage: build/bin/urinfo [-h] [-v] [-V]

This tool enumerates Unified Runtime layers, adapters, platforms, and
devices which are currently visible in the local execution environment.

options:
  -h, --help            show this help message and exit
  --version             show version number and exit
  -v, --verbose         print additional information
```
  • Loading branch information
kbenzie committed Jul 28, 2023
1 parent e73389f commit f488b56
Show file tree
Hide file tree
Showing 8 changed files with 895 additions and 2 deletions.
31 changes: 31 additions & 0 deletions scripts/generate_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,25 @@ def _mako_params_hpp(path, namespace, tags, version, specs, meta):
specs=specs,
meta=meta)

"""
Entry-point:
generates tools code
"""
def _mako_info_hpp(path, namespace, tags, version, specs, meta):
fin = os.path.join(templates_dir, "tools-info.hpp.mako")
name = f"{namespace}info"
filename = f"{name}.hpp"
fout = os.path.join(path, filename)
print("Generating %s..." % fout)
return util.makoWrite(
fin, fout,
name=name,
ver=version,
namespace=namespace,
tags=tags,
specs=specs,
meta=meta)

"""
Entry-point:
generates lib code
Expand Down Expand Up @@ -364,3 +383,15 @@ def generate_common(path, section, namespace, tags, version, specs, meta):
loc += _mako_params_hpp(layer_dstpath, namespace, tags, version, specs, meta)
print("COMMON Generated %s lines of code.\n"%loc)

"""
Entry-point:
generates tools for unified_runtime
"""
def generate_tools(path, section, namespace, tags, version, specs, meta):
loc = 0

infodir = os.path.join(path, f"{namespace}info")
os.makedirs(infodir, exist_ok=True)
loc += _mako_info_hpp(infodir, namespace, tags, version, specs, meta)

print("TOOLS Generated %s lines of code.\n" % loc)
4 changes: 4 additions & 0 deletions scripts/json2src.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def strip_loader_meta(meta):
add_argument(parser, "layers", "generation of layer files.", True)
add_argument(parser, "adapters", "generation of null adapter files.", True)
add_argument(parser, "common", "generation of common files.", True)
add_argument(parser, "tools", "generation of common files.", True)
parser.add_argument("--debug", action='store_true', help="dump intermediate data to disk.")
parser.add_argument("--sections", type=list, default=None, help="Optional list of sections for which to generate source, default is all")
parser.add_argument("--ver", type=str, default="1.0", help="specification version to generate.")
Expand All @@ -69,6 +70,7 @@ def strip_loader_meta(meta):
start = time.time()

srcpath = os.path.join(args.out_dir, "source")
toolspath = os.path.join(args.out_dir, "tools")

for idx, specs in enumerate(input['specs']):
config = input['configs'][idx]
Expand All @@ -86,6 +88,8 @@ def strip_loader_meta(meta):
generate_code.generate_adapters(srcpath, config['name'], config['namespace'], config['tags'], args.ver, specs, input['meta'])
if args.common:
generate_code.generate_common(srcpath, config['name'], config['namespace'], config['tags'], args.ver, specs, input['meta'])
if args.tools:
generate_code.generate_tools(toolspath, config['name'], config['namespace'], config['tags'], args.ver, specs, input['meta'])

if args.debug:
util.makoFileListWrite("generated.json")
Expand Down
75 changes: 75 additions & 0 deletions scripts/templates/tools-info.hpp.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<%!
import re
from templates import helper as th
%><%
n=namespace
N=n.upper()
x=tags['$x']
X=x.upper()
%>/*
*
* Copyright (C) 2023 Intel Corporation
*
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
* See LICENSE.TXT
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* @file ${name}.cpp
*
*/

#pragma once

#include <ur_api.h>
#include "utils.hpp"
#include <cstdlib>
#include <string_view>

namespace urinfo {
%for obj in th.extract_objs(specs, r"enum"):
## TODO: For some reason the runtime spec isn't in specs.
## %if obj["name"] == '$x_loader_config_info_t':
## inline void printLoaderConfigInfo(${x}_loader_config_t hLoaderConfig,
## std::string_view prefix = "") {
## %for etor in obj['etors']:
## %if 'REFERENCE_COUNT' not in etor['name']:
## std::cout << prefix;
## printLoaderConfigInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hLoaderConfig, ${etor['name'].replace('$X', X)});
## %endif
## %endfor
## }
## %endif
%if obj["name"] == '$x_adapter_info_t':
inline void printAdapterInfos(${x}_adapter_handle_t hAdapter,
std::string_view prefix = " ") {
%for etor in obj['etors']:
%if 'REFERENCE_COUNT' not in etor['name']:
std::cout << prefix;
printAdapterInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hAdapter, ${etor['name'].replace('$X', X)});
%endif
%endfor
}

%endif
%if obj["name"] == '$x_platform_info_t':
inline void printPlatformInfos(${x}_platform_handle_t hPlatform,
std::string_view prefix = " ") {
%for etor in obj['etors']:
std::cout << prefix;
printPlatformInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hPlatform, ${etor['name'].replace('$X', X)});
%endfor
}

%endif
%if obj['name'] == '$x_device_info_t':
inline void printDeviceInfos(${x}_device_handle_t hDevice,
std::string_view prefix = " ") {
%for etor in obj['etors']:
std::cout << prefix;
printDeviceInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hDevice, ${etor['name'].replace('$X', X)});
%endfor
}
%endif
%endfor
} // namespace urinfo
3 changes: 1 addition & 2 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_subdirectory(urinfo)
if(UR_ENABLE_TRACING)
add_subdirectory(urtrace)
endif()
20 changes: 20 additions & 0 deletions tools/urinfo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (C) 2023 Intel Corporation
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

add_executable(urinfo
urinfo.hpp
utils.hpp
urinfo.cpp
)
target_compile_definitions(urinfo PRIVATE
UR_VERSION="${PROJECT_VERSION}"
)
target_include_directories(urinfo PRIVATE
${PROJECT_SOURCE_DIR}/source/common
)
target_link_libraries(urinfo PRIVATE
${PROJECT_NAME}::headers
${PROJECT_NAME}::loader
)
197 changes: 197 additions & 0 deletions tools/urinfo/urinfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Copyright (C) 2023 Intel Corporation
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "urinfo.hpp"
#include <cstdlib>
#include <iostream>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

namespace urinfo {
struct app {
bool verbose = false;
ur_loader_config_handle_t loaderConfig = nullptr;
std::vector<ur_adapter_handle_t> adapters;
std::unordered_map<ur_adapter_handle_t, std::vector<ur_platform_handle_t>>
adapterPlatformsMap;
std::unordered_map<ur_platform_handle_t, std::vector<ur_device_handle_t>>
platformDevicesMap;

app(int argc, const char **argv) {
parseArgs(argc, argv);
UR_CHECK(urLoaderConfigCreate(&loaderConfig));
UR_CHECK(urInit(0, loaderConfig));
enumerateDevices();
}

void parseArgs(int argc, const char **argv) {
static const char *usage = R"(usage: %s [-h] [-v] [-V]
This tool enumerates Unified Runtime layers, adapters, platforms, and
devices which are currently visible in the local execution environment.
options:
-h, --help show this help message and exit
--version show version number and exit
-v, --verbose print additional information
)";
for (int argi = 1; argi < argc; argi++) {
std::string_view arg{argv[argi]};
if (arg == "-h" || arg == "--help") {
std::printf(usage, argv[0]);
std::exit(0);
} else if (arg == "--version") {
std::printf("%s v%s\n", argv[0], UR_VERSION);
std::exit(0);
} else if (arg == "-v" || arg == "--verbose") {
verbose = true;
} else {
std::fprintf(stderr, "error: invalid argument: %s\n",
argv[argi]);
std::fprintf(stderr, usage, argv[0]);
std::exit(1);
}
}
}

void enumerateDevices() {
// Enumerate adapters.
uint32_t numAdapters = 0;
UR_CHECK(urAdapterGet(0, nullptr, &numAdapters));
if (numAdapters == 0) {
std::cout << "No adapters found.\n";
std::exit(0);
}
adapters.resize(numAdapters);
UR_CHECK(urAdapterGet(numAdapters, adapters.data(), nullptr));

for (auto adapter : adapters) {
// Enumerate platforms
uint32_t numPlatforms = 0;
UR_CHECK(urPlatformGet(adapters.data(), numAdapters, 0, nullptr,
&numPlatforms));
if (numPlatforms == 0) {
std::cout << "No platforms found.\n";
std::exit(0);
}
adapterPlatformsMap[adapter].resize(numAdapters);
UR_CHECK(urPlatformGet(adapters.data(), numAdapters, numPlatforms,
adapterPlatformsMap[adapter].data(),
nullptr));

for (auto platform : adapterPlatformsMap[adapter]) {
// Enumerate devices
uint32_t numDevices = 0;
UR_CHECK(urDeviceGet(platform, UR_DEVICE_TYPE_ALL, 0, nullptr,
&numDevices));
if (numDevices == 0) {
std::cout << "No devices found.\n";
continue;
}
platformDevicesMap[platform].resize(numDevices);
UR_CHECK(urDeviceGet(platform, UR_DEVICE_TYPE_ALL, numDevices,
platformDevicesMap[platform].data(),
nullptr));
}
}
}

void printSummary() {
for (size_t adapterIndex = 0; adapterIndex < adapters.size();
adapterIndex++) {
auto adapter = adapters[adapterIndex];
auto &platforms = adapterPlatformsMap[adapter];
for (size_t platformIndex = 0; platformIndex < platforms.size();
platformIndex++) {
auto platform = platforms[platformIndex];
auto &devices = platformDevicesMap[platform];
for (size_t deviceIndex = 0; deviceIndex < devices.size();
deviceIndex++) {
auto device = devices[deviceIndex];
std::cout << "[adapter(" << adapterIndex << ","
<< urinfo::getAdapterBackend(adapter) << "):"
<< "platform(" << platformIndex << "):"
<< "device(" << deviceIndex << ","
<< urinfo::getDeviceType(device) << ")] "
<< urinfo::getPlatformName(platform) << ", "
<< urinfo::getDeviceName(device) << " "
<< urinfo::getDeviceVersion(device) << " "
<< "[" << urinfo::getDeviceDriverVersion(device)
<< "]\n";
}
}
}
}

void printDetail() {
size_t availableLayersSize = 0;
UR_CHECK(urLoaderConfigGetInfo(loaderConfig,
UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS,
0, nullptr, &availableLayersSize));
// TODO: Generate loader config info printer
std::string availableLayers;
if (availableLayersSize != 0) {
availableLayers.resize(availableLayersSize);
UR_CHECK(urLoaderConfigGetInfo(
loaderConfig, UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS,
availableLayersSize, availableLayers.data(), nullptr));
}
std::cout << "\n"
<< "[loader]:"
<< "\n"
<< " UR_LOADER_CONFIG_INFO_AVAILABLE_LAYERS: "
<< availableLayers << "\n";

std::string adapterPrefix = " ";
std::string platformPrefix = " ";
std::string devicePrefix = " ";

for (size_t adapterI = 0; adapterI < adapters.size(); adapterI++) {
auto adapter = adapters[adapterI];
std::cout << "\n"
<< "[adapter(" << adapterI << ")]:"
<< "\n";
urinfo::printAdapterInfos(adapter, adapterPrefix);

size_t numPlatforms = adapterPlatformsMap[adapter].size();
for (size_t platformI = 0; platformI < numPlatforms; platformI++) {
auto platform = adapterPlatformsMap[adapter][platformI];
std::cout << "\n"
<< "[adapter(" << adapterI << "),"
<< "platform(" << platformI << ")]:"
<< "\n";
urinfo::printPlatformInfos(platform, platformPrefix);

size_t numDevices = platformDevicesMap[platform].size();
for (size_t deviceI = 0; deviceI < numDevices; deviceI++) {
auto device = platformDevicesMap[platform][deviceI];
std::cout << "\n"
<< "[adapter(" << adapterI << "),"
<< "platform(" << platformI << "),"
<< "device(" << deviceI << ")]:"
<< "\n";
urinfo::printDeviceInfos(device, devicePrefix);
}
}
}
}

~app() {
UR_CHECK(urLoaderConfigRelease(loaderConfig));
UR_CHECK(urTearDown(nullptr));
}
};
} // namespace urinfo

int main(int argc, const char **argv) {
auto app = urinfo::app{argc, argv};
app.printSummary();
if (app.verbose) {
app.printDetail();
}
return 0;
}
Loading

0 comments on commit f488b56

Please sign in to comment.