Skip to content

Commit 57e3e55

Browse files
committed
Fix clc device selection on multi-device platform
If a platform reports multiple devices, they will all have the same name and --device selection will be ambiguous. This adds a --device-idx cmd-line option to directly select by index.
1 parent 4cf212c commit 57e3e55

File tree

3 files changed

+61
-29
lines changed

3 files changed

+61
-29
lines changed

modules/cargo/include/cargo/argument_parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class argument {
219219
cargo::array_view<cargo::string_view> Choices;
220220
};
221221
union {
222-
bool *Bool;
222+
bool *Bool = {};
223223
cargo::string_view *Value;
224224
ChoiceT Choice;
225225
cargo::small_vector<cargo::string_view, 4> *Values;

source/cl/tools/clc/clc.cpp

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <algorithm>
2727
#include <array>
28+
#include <charconv>
2829
#include <cstdio>
2930
#include <cstdlib>
3031
#include <fstream>
@@ -152,6 +153,7 @@ driver::driver()
152153
dry_run(false),
153154
input_file(),
154155
output_file(""),
156+
device_idx(0),
155157
device_name_substring(""),
156158
cl_build_args(),
157159
strip_binary_header(false),
@@ -185,6 +187,9 @@ optional arguments:
185187
output file path, defaults to the name of the last
186188
input file "<input>.bin" if present, or "-" otherwise
187189
to write to standard output
190+
--device-idx index
191+
the index (1..N) of the device to select. Takes precedence
192+
over --device
188193
-d name, --device name
189194
a substring of the device name to select, choose from:%s
190195
--list-devices print the list of available devices and exit
@@ -275,6 +280,18 @@ result driver::parseArguments(int argc, char **argv) {
275280
CHECK(parser.add_argument({"-o", output_file}));
276281
CHECK(parser.add_argument({"--output", output_file}));
277282

283+
CHECK(parser.add_argument({
284+
"--device-idx",
285+
[](auto&&...){ return parse::INCOMPLETE; },
286+
[this](cargo::string_view str_value){
287+
auto [ptr, ec] = std::from_chars(str_value.begin(), str_value.end(), device_idx);
288+
if ((ptr != str_value.end()) || (device_idx == 0)) {
289+
return parse::INVALID;
290+
}
291+
return parse::COMPLETE;
292+
},
293+
}));
294+
278295
CHECK(parser.add_argument({"-d", device_name_substring}));
279296
CHECK(parser.add_argument({"--device", device_name_substring}));
280297

@@ -743,38 +760,51 @@ result driver::findDevice() {
743760
return result::failure;
744761
}
745762

746-
if (compilers.size() > 1 && device_name_substring.empty()) {
747-
(void)std::fprintf(stderr,
748-
"error: Multiple devices available, please choose one "
749-
"(--device NAME):\n");
750-
printMuxCompilers(compilers);
751-
return result::failure;
752-
}
753-
754-
bool found = false;
755-
for (auto compiler : compilers) {
756-
bool matches = true;
757-
if (!device_name_substring.empty()) {
758-
matches &= matchSubstring(compiler->device_info->device_name,
759-
device_name_substring);
760-
}
761-
if (matches) {
762-
if (found) {
763-
(void)std::fprintf(
764-
stderr, "error: Device selection ambiguous, available devices:\n");
763+
if (device_idx != 0) {
764+
if (device_idx > compilers.size()) {
765+
(void)std::fprintf(stderr,
766+
"error: Invalid device selection; out of bounds. "
767+
"Available devices:\n");
765768
printMuxCompilers(compilers);
766769
return result::failure;
770+
}
771+
772+
compiler_info = compilers[device_idx - 1];
773+
774+
} else {
775+
if (compilers.size() > 1 && device_name_substring.empty()) {
776+
(void)std::fprintf(stderr,
777+
"error: Multiple devices available, please choose one "
778+
"(--device NAME | --device-idx INDEX):\n");
779+
printMuxCompilers(compilers);
780+
return result::failure;
781+
}
782+
783+
bool found = false;
784+
for (auto compiler : compilers) {
785+
bool matches = true;
786+
if (!device_name_substring.empty()) {
787+
matches &= matchSubstring(compiler->device_info->device_name,
788+
device_name_substring);
789+
}
790+
if (matches) {
791+
if (found) {
792+
(void)std::fprintf(
793+
stderr, "error: Device selection ambiguous, available devices:\n");
794+
printMuxCompilers(compilers);
795+
return result::failure;
796+
}
797+
found = true;
798+
compiler_info = compiler;
767799
}
768-
found = true;
769-
compiler_info = compiler;
770800
}
771-
}
772-
if (!found) {
773-
(void)std::fprintf(
774-
stderr,
775-
"error: No device matched the given substring, available devices:\n");
776-
printMuxCompilers(compilers);
777-
return result::failure;
801+
if (!found) {
802+
(void)std::fprintf(
803+
stderr,
804+
"error: No device matched the given substring, available devices:\n");
805+
printMuxCompilers(compilers);
806+
return result::failure;
807+
}
778808
}
779809

780810
if (verbose) {

source/cl/tools/clc/clc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class driver {
6666
std::string input_file;
6767
/// @brief Path to the output file or `"-"` for `stdout`.
6868
cargo::string_view output_file;
69+
/// @brief Device index to select from multiple devices. Takes precedence over device name.
70+
size_t device_idx;
6971
/// @brief Device name substring to select from multiple devices.
7072
cargo::string_view device_name_substring;
7173
/// @brief List of compile options passed to `clBuildProgram`.

0 commit comments

Comments
 (0)