Skip to content

Commit 9cdb2b0

Browse files
authored
[lit][offloader][ninja] Add ability to toggle gpu by name (#646)
This change allows you to set an enviornment variable to pick which gpu the offloader will use. For example say I have an Intel GPU I can do: ``` set "OFFLOADTEST_GPU_NAME=Intel(R) Arc(TM) A770 Graphics" && ninja -C ..\llvm-build\ check-hlsl-clang-d3d12 ``` Or if I just want to specify the vendor I can do ``` set "OFFLOADTEST_GPU_NAME=Intel" && ninja -C ..\llvm-build\ check-hlsl-clang-d3d12 ``` This was made via `llvm::regex` so you can use any casing. Say on linux we would do ```bash vulkaninfo --summary | grep deviceName deviceName = NVIDIA GeForce RTX 4070 Ti (NVK AD104) deviceName = llvmpipe (LLVM 20.1.2, 256 bits) OFFLOADTEST_GPU_NAME=nvidia ninja -C ../llvm_builds/llvm_rel_with_debug_offload/ check-hlsl-clang-vk OFFLOADTEST_GPU_NAME=llvmpipe ninja -C ../llvm_builds/llvm_rel_with_debug_offload/ check-hlsl-clang-vk ``` I am also adding a way to use the adapter index because in testing I found typing out even just the substring can be more annoying than a single char for the gpu index. The index is just the order we see them in the device array. I am also adding the ability to toggle between vulkan drivers on the mac. To do this we just needed to encode the driver name into the Description. Since `KosmicKrisp` is apple silicon only I limit its usage to `if defined(__APPLE__) && defined(__aarch64__)`. ```bash OFFLOADTEST_GPU_NAME=KosmicKrisp ninja -C ../builds/llvm_relwithdebinfo_offload check-hlsl-clang-vk ``` This change was useful for me to pick between multiple discrete gpus on a single rig, egpus, and integrated gpus. It works now for both DirectX and Vulkan devices.
1 parent d1fa558 commit 9cdb2b0

3 files changed

Lines changed: 51 additions & 7 deletions

File tree

lib/API/VK/Device.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ class VKDevice : public offloadtest::Device {
268268
private:
269269
VkPhysicalDevice Device;
270270
VkPhysicalDeviceProperties Props;
271+
VkPhysicalDeviceProperties2 Props2;
272+
VkPhysicalDeviceDriverProperties DriverProps;
271273
Capabilities Caps;
272274
using LayerVector = std::vector<VkLayerProperties>;
273275
LayerVector Layers;
@@ -377,9 +379,20 @@ class VKDevice : public offloadtest::Device {
377379
public:
378380
VKDevice(VkPhysicalDevice D) : Device(D) {
379381
vkGetPhysicalDeviceProperties(Device, &Props);
380-
const uint64_t StrSz =
382+
const uint64_t DeviceNameSz =
381383
strnlen(Props.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
382-
Description = std::string(Props.deviceName, StrSz);
384+
Description = std::string(Props.deviceName, DeviceNameSz);
385+
#if defined(__APPLE__) && defined(__aarch64__)
386+
DriverProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
387+
DriverProps.pNext = nullptr;
388+
Props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
389+
Props2.pNext = &DriverProps;
390+
vkGetPhysicalDeviceProperties2(Device, &Props2);
391+
const uint64_t DriverNameSz =
392+
strnlen(DriverProps.driverName, VK_MAX_DRIVER_NAME_SIZE);
393+
Description +=
394+
" (" + std::string(DriverProps.driverName, DriverNameSz) + ")";
395+
#endif
383396
}
384397
VKDevice(const VKDevice &) = default;
385398

test/lit.cfg.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
# Tweak the PATH to include the tools dir.
4242
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
4343

44+
# Environment equivalents (useful for ninja):
45+
# OFFLOADTEST_GPU_NAME
46+
GPUName = os.environ.get("OFFLOADTEST_GPU_NAME", "")
47+
ShouldSearchByGPuName = len(GPUName) > 0
48+
4449
tools = [
4550
ToolSubst("FileCheck", FindTool("FileCheck")),
4651
ToolSubst("split-file", FindTool("split-file")),
@@ -138,7 +143,8 @@ def setDeviceFeatures(config, device, compiler):
138143
offloader_args.append("-debug-layer")
139144
if config.offloadtest_enable_validation:
140145
offloader_args.append("-validation-layer")
141-
146+
if ShouldSearchByGPuName:
147+
offloader_args.extend([f'-adapter-regex="{GPUName}"'])
142148
tools.append(
143149
ToolSubst("%offloader", command=FindTool("offloader"), extra_args=offloader_args)
144150
)
@@ -197,19 +203,29 @@ def setDeviceFeatures(config, device, compiler):
197203
query_string = subprocess.check_output(api_query)
198204
devices = yaml.safe_load(query_string)
199205
target_device = None
200-
201206
# Find the right device to configure against
207+
pattern = re.compile(GPUName, re.IGNORECASE)
202208
for device in devices["Devices"]:
203209
is_warp = "Microsoft Basic Render Driver" in device["Description"]
210+
is_gpu_name_match = bool(pattern.search(device["Description"]))
204211
if device["API"] == "DirectX" and config.offloadtest_enable_d3d12:
205-
if is_warp and config.offloadtest_test_warp:
212+
if ShouldSearchByGPuName and is_gpu_name_match:
213+
target_device = device
214+
elif is_warp and config.offloadtest_test_warp:
206215
target_device = device
207-
elif not is_warp and not config.offloadtest_test_warp:
216+
elif (
217+
not ShouldSearchByGPuName
218+
and not is_warp
219+
and not config.offloadtest_test_warp
220+
):
208221
target_device = device
209222
if device["API"] == "Metal" and config.offloadtest_enable_metal:
210223
target_device = device
211224
if device["API"] == "Vulkan" and config.offloadtest_enable_vulkan:
212-
target_device = device
225+
if ShouldSearchByGPuName and is_gpu_name_match:
226+
target_device = device
227+
elif not ShouldSearchByGPuName:
228+
target_device = device
213229
# Bail from the loop if we found a device that matches what we're looking for.
214230
if target_device:
215231
break

tools/offloader/offloader.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ static cl::opt<bool> Validation("validation-layer",
6363

6464
static cl::opt<bool> UseWarp("warp", cl::desc("Use warp"));
6565

66+
static cl::opt<std::string> AdapterRegex(
67+
"adapter-regex",
68+
cl::desc(
69+
"Case-insensitive regular expression to match GPU adapter description"),
70+
cl::value_desc("<regex>"), cl::init(""));
71+
6672
static std::unique_ptr<MemoryBuffer> readFile(const std::string &Path) {
6773
const ExitOnError ExitOnErr("gpu-exec: error: ");
6874
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
@@ -84,6 +90,12 @@ int main(int ArgC, char **ArgV) {
8490
return 0;
8591
}
8692

93+
static bool matchesRegexIgnoreCase(StringRef GPUDescription,
94+
StringRef SearchExpr) {
95+
const llvm::Regex R(SearchExpr, llvm::Regex::IgnoreCase);
96+
return R.isValid() && R.match(GPUDescription);
97+
}
98+
8799
int run() {
88100
const ExitOnError ExitOnErr("gpu-exec: error: ");
89101
const DeviceConfig Config = {Debug, Validation};
@@ -141,6 +153,9 @@ int run() {
141153
continue;
142154
if (UseWarp && D->getDescription() != "Microsoft Basic Render Driver")
143155
continue;
156+
if (!AdapterRegex.empty() &&
157+
!matchesRegexIgnoreCase(D->getDescription(), AdapterRegex))
158+
continue;
144159
ExitOnErr(D->executeProgram(PipelineDesc));
145160

146161
// check the results

0 commit comments

Comments
 (0)