Skip to content

Commit 7a69e10

Browse files
committed
[ur] Introduce urinfo tool
`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 ```
1 parent 8e9f3ff commit 7a69e10

File tree

8 files changed

+895
-2
lines changed

8 files changed

+895
-2
lines changed

scripts/generate_code.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,25 @@ def _mako_params_hpp(path, namespace, tags, version, specs, meta):
296296
specs=specs,
297297
meta=meta)
298298

299+
"""
300+
Entry-point:
301+
generates tools code
302+
"""
303+
def _mako_info_hpp(path, namespace, tags, version, specs, meta):
304+
fin = os.path.join(templates_dir, "tools-info.hpp.mako")
305+
name = f"{namespace}info"
306+
filename = f"{name}.hpp"
307+
fout = os.path.join(path, filename)
308+
print("Generating %s..." % fout)
309+
return util.makoWrite(
310+
fin, fout,
311+
name=name,
312+
ver=version,
313+
namespace=namespace,
314+
tags=tags,
315+
specs=specs,
316+
meta=meta)
317+
299318
"""
300319
Entry-point:
301320
generates lib code
@@ -364,3 +383,15 @@ def generate_common(path, section, namespace, tags, version, specs, meta):
364383
loc += _mako_params_hpp(layer_dstpath, namespace, tags, version, specs, meta)
365384
print("COMMON Generated %s lines of code.\n"%loc)
366385

386+
"""
387+
Entry-point:
388+
generates tools for unified_runtime
389+
"""
390+
def generate_tools(path, section, namespace, tags, version, specs, meta):
391+
loc = 0
392+
393+
infodir = os.path.join(path, f"{namespace}info")
394+
os.makedirs(infodir, exist_ok=True)
395+
loc += _mako_info_hpp(infodir, namespace, tags, version, specs, meta)
396+
397+
print("TOOLS Generated %s lines of code.\n" % loc)

scripts/json2src.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def strip_loader_meta(meta):
5757
add_argument(parser, "layers", "generation of layer files.", True)
5858
add_argument(parser, "adapters", "generation of null adapter files.", True)
5959
add_argument(parser, "common", "generation of common files.", True)
60+
add_argument(parser, "tools", "generation of common files.", True)
6061
parser.add_argument("--debug", action='store_true', help="dump intermediate data to disk.")
6162
parser.add_argument("--sections", type=list, default=None, help="Optional list of sections for which to generate source, default is all")
6263
parser.add_argument("--ver", type=str, default="1.0", help="specification version to generate.")
@@ -69,6 +70,7 @@ def strip_loader_meta(meta):
6970
start = time.time()
7071

7172
srcpath = os.path.join(args.out_dir, "source")
73+
toolspath = os.path.join(args.out_dir, "tools")
7274

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

9094
if args.debug:
9195
util.makoFileListWrite("generated.json")
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<%!
2+
import re
3+
from templates import helper as th
4+
%><%
5+
n=namespace
6+
N=n.upper()
7+
8+
x=tags['$x']
9+
X=x.upper()
10+
%>/*
11+
*
12+
* Copyright (C) 2023 Intel Corporation
13+
*
14+
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
15+
* See LICENSE.TXT
16+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
17+
*
18+
* @file ${name}.cpp
19+
*
20+
*/
21+
22+
#pragma once
23+
24+
#include <ur_api.h>
25+
#include "utils.hpp"
26+
#include <cstdlib>
27+
#include <string_view>
28+
29+
namespace urinfo {
30+
%for obj in th.extract_objs(specs, r"enum"):
31+
## TODO: For some reason the runtime spec isn't in specs.
32+
## %if obj["name"] == '$x_loader_config_info_t':
33+
## inline void printLoaderConfigInfo(${x}_loader_config_t hLoaderConfig,
34+
## std::string_view prefix = "") {
35+
## %for etor in obj['etors']:
36+
## %if 'REFERENCE_COUNT' not in etor['name']:
37+
## std::cout << prefix;
38+
## printLoaderConfigInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hLoaderConfig, ${etor['name'].replace('$X', X)});
39+
## %endif
40+
## %endfor
41+
## }
42+
## %endif
43+
%if obj["name"] == '$x_adapter_info_t':
44+
inline void printAdapterInfos(${x}_adapter_handle_t hAdapter,
45+
std::string_view prefix = " ") {
46+
%for etor in obj['etors']:
47+
%if 'REFERENCE_COUNT' not in etor['name']:
48+
std::cout << prefix;
49+
printAdapterInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hAdapter, ${etor['name'].replace('$X', X)});
50+
%endif
51+
%endfor
52+
}
53+
54+
%endif
55+
%if obj["name"] == '$x_platform_info_t':
56+
inline void printPlatformInfos(${x}_platform_handle_t hPlatform,
57+
std::string_view prefix = " ") {
58+
%for etor in obj['etors']:
59+
std::cout << prefix;
60+
printPlatformInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hPlatform, ${etor['name'].replace('$X', X)});
61+
%endfor
62+
}
63+
64+
%endif
65+
%if obj['name'] == '$x_device_info_t':
66+
inline void printDeviceInfos(${x}_device_handle_t hDevice,
67+
std::string_view prefix = " ") {
68+
%for etor in obj['etors']:
69+
std::cout << prefix;
70+
printDeviceInfo<${etor['desc'][1:etor['desc'].find(' ')-1].replace('$x', x)}>(hDevice, ${etor['name'].replace('$X', X)});
71+
%endfor
72+
}
73+
%endif
74+
%endfor
75+
} // namespace urinfo

tools/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
# See LICENSE.TXT
44
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6-
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
7-
6+
add_subdirectory(urinfo)
87
if(UR_ENABLE_TRACING)
98
add_subdirectory(urtrace)
109
endif()

tools/urinfo/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
add_executable(urinfo
7+
urinfo.hpp
8+
utils.hpp
9+
urinfo.cpp
10+
)
11+
target_compile_definitions(urinfo PRIVATE
12+
UR_VERSION="${PROJECT_VERSION}"
13+
)
14+
target_include_directories(urinfo PRIVATE
15+
${PROJECT_SOURCE_DIR}/source/common
16+
)
17+
target_link_libraries(urinfo PRIVATE
18+
${PROJECT_NAME}::headers
19+
${PROJECT_NAME}::loader
20+
)

tools/urinfo/urinfo.cpp

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
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

Comments
 (0)