Skip to content

Commit 3ebb4ed

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 3ebb4ed

File tree

3 files changed

+64
-29
lines changed

3 files changed

+64
-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: 60 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,19 @@ 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] =
288+
std::from_chars(str_value.begin(), str_value.end(), device_idx);
289+
if ((ptr != str_value.end()) || (device_idx == 0)) {
290+
return parse::INVALID;
291+
}
292+
return parse::COMPLETE;
293+
},
294+
}));
295+
278296
CHECK(parser.add_argument({"-d", device_name_substring}));
279297
CHECK(parser.add_argument({"--device", device_name_substring}));
280298

@@ -743,38 +761,52 @@ result driver::findDevice() {
743761
return result::failure;
744762
}
745763

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-
}
764+
if (device_idx != 0) {
765+
if (device_idx > compilers.size()) {
766+
(void)std::fprintf(stderr,
767+
"error: Invalid device selection; out of bounds. "
768+
"Available devices:\n");
769+
printMuxCompilers(compilers);
770+
return result::failure;
771+
}
772+
773+
compiler_info = compilers[device_idx - 1];
753774

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);
775+
} else {
776+
if (compilers.size() > 1 && device_name_substring.empty()) {
777+
(void)std::fprintf(stderr,
778+
"error: Multiple devices available, please choose one "
779+
"(--device NAME | --device-idx INDEX):\n");
780+
printMuxCompilers(compilers);
781+
return result::failure;
760782
}
761-
if (matches) {
762-
if (found) {
763-
(void)std::fprintf(
764-
stderr, "error: Device selection ambiguous, available devices:\n");
765-
printMuxCompilers(compilers);
766-
return result::failure;
783+
784+
bool found = false;
785+
for (auto compiler : compilers) {
786+
bool matches = true;
787+
if (!device_name_substring.empty()) {
788+
matches &= matchSubstring(compiler->device_info->device_name,
789+
device_name_substring);
790+
}
791+
if (matches) {
792+
if (found) {
793+
(void)std::fprintf(
794+
stderr,
795+
"error: Device selection ambiguous, available devices:\n");
796+
printMuxCompilers(compilers);
797+
return result::failure;
798+
}
799+
found = true;
800+
compiler_info = compiler;
767801
}
768-
found = true;
769-
compiler_info = compiler;
770802
}
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;
803+
if (!found) {
804+
(void)std::fprintf(
805+
stderr,
806+
"error: No device matched the given substring, available devices:\n");
807+
printMuxCompilers(compilers);
808+
return result::failure;
809+
}
778810
}
779811

780812
if (verbose) {

source/cl/tools/clc/clc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ 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
70+
/// device name.
71+
size_t device_idx;
6972
/// @brief Device name substring to select from multiple devices.
7073
cargo::string_view device_name_substring;
7174
/// @brief List of compile options passed to `clBuildProgram`.

0 commit comments

Comments
 (0)