-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Loader] Refactor ONEAPI_DEVICE_SELECTOR, add tests
This patch resolves a number of issues with the extant implementation of the `ONEAPI_DEVICE_SELECTOR`: * Filtering only being applied to devices within a platform, resulting in an incorrect list of devices being returned in a multi-platform, multi-device context. * Device indices being counted only inside a platform, not globally, resulting in multiple devices with 0 index in the presence of multiple platforms. * Lack of testing for non-hardware dependent configurations, e.g. unable to emulate filtering against hypothetical sets of devices. * Parsing the ONEAPI_DEVICE_SELECTOR string each time `urDeviceGetSelected()` was called. This new implementation was written with testing of the individaul terms in the ONEAPI_DEVICE_SELECTOR BNF grammer as a design requirement. It decouples the enumeration of devices from the filtering logic. Both parsing and device enumeration are moved much earlier, into loader initialization, and performed only once.
- Loading branch information
Showing
21 changed files
with
1,604 additions
and
598 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Copyright (C) 2022 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_ur_library(ur_device_selector STATIC | ||
backend.hpp | ||
device.hpp | ||
filter.hpp | ||
selector.cpp # TODO: Remove this and make it header only? | ||
matcher.hpp | ||
) | ||
|
||
add_library(${PROJECT_NAME}::device_selector ALIAS ur_device_selector) | ||
|
||
target_include_directories(ur_device_selector PUBLIC | ||
${CMAKE_CURRENT_SOURCE_DIR}/.. | ||
) | ||
|
||
target_link_libraries(ur_device_selector PUBLIC | ||
${PROJECT_NAME}::headers | ||
${PROJECT_NAME}::common | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright (C) 2024 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 | ||
|
||
#pragma once | ||
|
||
#include "descriptor.hpp" | ||
#include "ur_api.h" | ||
#include <algorithm> | ||
#include <optional> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace ur::device_selector { | ||
|
||
struct BackendMatcher { | ||
/// @brief Initilalize the backend matcher from a string in a case | ||
/// insensitive way. | ||
/// @param[in] backend Backend filter string. | ||
/// @return Returns a diagnostic if an invalid backend is found. | ||
std::optional<Diagnostic> init(std::string_view str) { | ||
if (str.empty()) { | ||
return Diagnostic("empty backend"); | ||
} | ||
std::string lower(str); | ||
std::transform(lower.cbegin(), lower.cend(), lower.begin(), | ||
[](char c) { return std::tolower(c); }); | ||
if (lower == "*") { | ||
matches.insert(matches.begin(), { | ||
UR_PLATFORM_BACKEND_UNKNOWN, | ||
UR_PLATFORM_BACKEND_LEVEL_ZERO, | ||
UR_PLATFORM_BACKEND_OPENCL, | ||
UR_PLATFORM_BACKEND_CUDA, | ||
UR_PLATFORM_BACKEND_HIP, | ||
UR_PLATFORM_BACKEND_OPENCL, | ||
UR_PLATFORM_BACKEND_NATIVE_CPU, | ||
}); | ||
} else if (lower == "opencl") { | ||
matches.push_back(UR_PLATFORM_BACKEND_OPENCL); | ||
} else if (lower == "level_zero" || lower == "ext_oneapi_level_zero") { | ||
matches.push_back(UR_PLATFORM_BACKEND_LEVEL_ZERO); | ||
} else if (lower == "cuda" || lower == "ext_oneapi_cuda") { | ||
matches.push_back(UR_PLATFORM_BACKEND_CUDA); | ||
} else if (lower == "hip" || lower == "ext_oneapi_hip") { | ||
matches.push_back(UR_PLATFORM_BACKEND_HIP); | ||
} else if (lower == "native_cpu") { | ||
matches.push_back(UR_PLATFORM_BACKEND_NATIVE_CPU); | ||
} else { | ||
std::string diagnostic = "invalid backend: '"; | ||
diagnostic.append(str); | ||
return Diagnostic(diagnostic + "'"); | ||
} | ||
return std::nullopt; | ||
} | ||
|
||
friend bool operator==(const BackendMatcher &matcher, | ||
const Descriptor &descriptor) { | ||
return std::any_of( | ||
matcher.matches.begin(), matcher.matches.end(), | ||
[&descriptor](const ur_platform_backend_t &backendMatch) { | ||
return backendMatch == descriptor.backend; | ||
}); | ||
} | ||
|
||
friend bool operator==(const Descriptor &backend, | ||
const BackendMatcher &matcher) { | ||
return matcher == backend; | ||
} | ||
|
||
friend bool operator!=(const BackendMatcher &matcher, | ||
const Descriptor &descriptor) { | ||
return std::none_of( | ||
matcher.matches.begin(), matcher.matches.end(), | ||
[&descriptor](const ur_platform_backend_t &backendMatch) { | ||
return backendMatch == descriptor.backend; | ||
}); | ||
} | ||
|
||
friend bool operator!=(const Descriptor &backend, | ||
const BackendMatcher &matcher) { | ||
return matcher != backend; | ||
} | ||
|
||
private: | ||
std::vector<ur_platform_backend_t> matches; | ||
}; | ||
|
||
} // namespace ur::device_selector |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright (C) 2024 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 | ||
|
||
#pragma once | ||
|
||
#include "ur_api.h" | ||
#include <optional> | ||
#include <string> | ||
|
||
namespace ur::device_selector { | ||
|
||
struct Diagnostic { | ||
Diagnostic(std::string message) : message(message) {} | ||
std::string message; | ||
}; | ||
|
||
struct Descriptor { | ||
Descriptor() = default; | ||
|
||
Descriptor(const Descriptor &other) | ||
: backend(other.backend), type(other.type), index(other.index), | ||
subIndex(other.subIndex), subSubIndex(other.subSubIndex) {} | ||
|
||
Descriptor(ur_platform_backend_t backend, ur_device_type_t type, | ||
uint32_t index) | ||
: backend(backend), type(type), index(index) {} | ||
Descriptor(ur_platform_backend_t backend, ur_device_type_t type, | ||
uint32_t index, uint32_t subDeviceIndex) | ||
: backend(backend), type(type), index(index), subIndex(subDeviceIndex) { | ||
} | ||
Descriptor(ur_platform_backend_t backend, ur_device_type_t type, | ||
uint32_t index, uint32_t subDeviceIndex, | ||
uint32_t subSubDeviceIndex) | ||
: backend(backend), type(type), index(index), subIndex(subDeviceIndex), | ||
subSubIndex(subSubDeviceIndex) {} | ||
|
||
ur_platform_backend_t backend; | ||
ur_device_type_t type; | ||
uint32_t index = 0; | ||
std::optional<uint32_t> subIndex; | ||
std::optional<uint32_t> subSubIndex; | ||
}; | ||
|
||
} // namespace ur::device_selector |
Oops, something went wrong.