Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f5b4d8a
add apple device_discovery.cc
edgchen1 Jun 11, 2025
f58ea4d
log discovered devices across platforms
edgchen1 Jun 12, 2025
d7b598d
save work - linux CPU discovery
edgchen1 Jun 13, 2025
f34b674
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jun 17, 2025
6101b99
support parsing hex string to int
edgchen1 Jun 18, 2025
a82a10c
save work - linux GPU impl
edgchen1 Jun 18, 2025
64e0a82
fix Linux GPU device_id
edgchen1 Jun 18, 2025
3bba325
Rename onnxruntime/core/platform/device_discovery.cc to device_discov…
edgchen1 Jun 18, 2025
0594d5a
finish renaming
edgchen1 Jun 18, 2025
757d27a
add TODO for vendor name
edgchen1 Jun 18, 2025
3481e99
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jun 18, 2025
34141a1
add default impl, add todo comment for apple
edgchen1 Jun 18, 2025
849b365
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jun 27, 2025
cc25212
clean up code for linux gpu discovery
edgchen1 Jun 27, 2025
04b0758
add card_idx to linux gpu metadata
edgchen1 Jun 28, 2025
f03f229
update OrtKeyValuePairs - add copy/move, make data members private, k…
edgchen1 Jun 28, 2025
c089033
save work - apple cpu discovery
edgchen1 Jun 28, 2025
55c3a8c
fix up cpu vendor detection
edgchen1 Jul 1, 2025
231d347
add check for non-zero detected vendor id
edgchen1 Jul 1, 2025
9e686ca
fix formatting
edgchen1 Jul 1, 2025
b474e4f
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jul 1, 2025
c53921d
fix build error
edgchen1 Jul 1, 2025
48c6bb4
hardcoded apple device discovery
edgchen1 Jul 2, 2025
6aa11ab
fix build issue in onnxruntime_pybind_state.cc
edgchen1 Jul 2, 2025
537ab69
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jul 24, 2025
f926cdc
enable logging before ORT logging is up
edgchen1 Jul 25, 2025
5b8764e
debug - dump /proc/cpuinfo file lines as they are read
edgchen1 Jul 25, 2025
d0f9653
make /proc/cpuinfo vendor field not mandatory, remove debug output
edgchen1 Jul 26, 2025
920c821
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jul 26, 2025
a56c2ff
update comment
edgchen1 Jul 26, 2025
8ef49c2
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Jul 28, 2025
5b721ec
add some ARM CPU vendor detection support
edgchen1 Jul 28, 2025
c31e336
fix build issues
edgchen1 Jul 29, 2025
9ae765a
replace /proc/cpuinfo parsing with cpuinfo library usage
edgchen1 Jul 30, 2025
53dbbf9
try enabling vendor id check in test
edgchen1 Jul 30, 2025
d9a7a5a
add endif comment, remove constexpr on FindCpuVendorInfo() because st…
edgchen1 Jul 30, 2025
46d60a3
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Aug 14, 2025
8dfeb2f
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Aug 14, 2025
1ddd31a
disable DeviceDiscoveryTest.HasCpuDevice for WASM
edgchen1 Aug 14, 2025
e1e1014
debugging - dump android logs if java test fails
edgchen1 Aug 14, 2025
3ad0927
disable gpu device discovery via sysfs on Android. there are permissi…
edgchen1 Aug 14, 2025
6adf61f
format
edgchen1 Aug 14, 2025
100228f
use ExitStack to dump Android logs
edgchen1 Aug 14, 2025
b8b5db0
Merge remote-tracking branch 'origin/main' into edgchen1/device_disco…
edgchen1 Aug 14, 2025
1afaa3e
add get CPU device helper function, remove ANDROID handling from linu…
edgchen1 Aug 15, 2025
cdca7a9
remove TODO about extending hex parsing to other types. largely hypot…
edgchen1 Aug 15, 2025
35b3796
remove commented out test
edgchen1 Aug 15, 2025
30370bc
add comment about std::fum_chars not accepting 0x prefix
edgchen1 Aug 15, 2025
c3138a7
linux - log GPU discovery error instead of throwing exception
edgchen1 Aug 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions cmake/onnxruntime_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ set(onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/check_intel.h"
"${ONNXRUNTIME_ROOT}/core/platform/check_intel.cc"
"${ONNXRUNTIME_ROOT}/core/platform/device_discovery.h"
"${ONNXRUNTIME_ROOT}/core/platform/device_discovery.cc"
"${ONNXRUNTIME_ROOT}/core/platform/device_discovery_common.cc"
"${ONNXRUNTIME_ROOT}/core/platform/env.h"
"${ONNXRUNTIME_ROOT}/core/platform/env.cc"
"${ONNXRUNTIME_ROOT}/core/platform/env_time.h"
Expand All @@ -32,26 +32,45 @@ set(onnxruntime_common_src_patterns

if(WIN32)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/windows/*.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/*.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/debug_alloc.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/debug_alloc.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/dll_load_error.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/dll_load_error.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/env_time.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/env.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/env.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/hardware_core_enumerator.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/hardware_core_enumerator.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/stacktrace.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/telemetry.cc"
"${ONNXRUNTIME_ROOT}/core/platform/windows/telemetry.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/logging/*.h"
"${ONNXRUNTIME_ROOT}/core/platform/windows/logging/*.cc"
)

else()
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/posix/*.h"
"${ONNXRUNTIME_ROOT}/core/platform/posix/*.cc"
"${ONNXRUNTIME_ROOT}/core/platform/posix/env_time.cc"
"${ONNXRUNTIME_ROOT}/core/platform/posix/env.cc"
"${ONNXRUNTIME_ROOT}/core/platform/posix/stacktrace.cc"
)

if(LINUX)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/linux/cpuinfo.h"
"${ONNXRUNTIME_ROOT}/core/platform/linux/cpuinfo.cc"
)
endif()

# logging files
if (onnxruntime_USE_SYSLOG)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/posix/logging/*.h"
"${ONNXRUNTIME_ROOT}/core/platform/posix/logging/*.cc"
)
endif()

if (CMAKE_SYSTEM_NAME STREQUAL "Android")
if (ANDROID)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/android/logging/*.h"
"${ONNXRUNTIME_ROOT}/core/platform/android/logging/*.cc"
Expand All @@ -66,6 +85,21 @@ else()
endif()
endif()

# platform-specific device discovery files
if (WIN32)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/windows/device_discovery.cc")
elseif (LINUX OR ANDROID)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/linux/device_discovery.cc")
elseif (APPLE)
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/apple/device_discovery.cc")
else()
list(APPEND onnxruntime_common_src_patterns
"${ONNXRUNTIME_ROOT}/core/platform/device_discovery_default.cc")
endif()

if(onnxruntime_target_platform STREQUAL "ARM64EC")
if (MSVC)
link_directories("$ENV{VCINSTALLDIR}/Tools/MSVC/$ENV{VCToolsVersion}/lib/ARM64EC")
Expand Down
23 changes: 20 additions & 3 deletions include/onnxruntime/core/common/parse_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,30 @@
std::enable_if_t<detail::ParseWithFromChars<T>, bool>
TryParseStringWithClassicLocale(std::string_view str, T& value) {
T parsed_value{};
const auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), parsed_value);

if (ec != std::errc{}) {
std::from_chars_result conversion_result{};
if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>) {
// For unsigned integral types, also handle hex values, i.e., those beginning with "0x".
// TODO We could also extend this to other types. For that, we would need to handle negative values.

Check warning on line 42 in include/onnxruntime/core/common/parse_string.h

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2] Raw Output: include/onnxruntime/core/common/parse_string.h:42: Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2]
const bool has_hex_prefix = str.size() >= 2 &&
str[0] == '0' &&
(str[1] == 'x' || str[1] == 'X');

if (has_hex_prefix) {
str = str.substr(2);
}

const int base = has_hex_prefix ? 16 : 10;
conversion_result = std::from_chars(str.data(), str.data() + str.size(), parsed_value, base);
} else {
conversion_result = std::from_chars(str.data(), str.data() + str.size(), parsed_value);
}

if (conversion_result.ec != std::errc{}) {
return false;
}

if (ptr != str.data() + str.size()) {
if (conversion_result.ptr != str.data() + str.size()) {
return false;
}

Expand Down
80 changes: 79 additions & 1 deletion onnxruntime/core/common/cpuid_info.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "core/common/cpuid_info.h"

#include <optional>

#include "core/common/logging/logging.h"
#include "core/common/logging/severity.h"
#include "core/platform/check_intel.h"
Expand Down Expand Up @@ -39,6 +42,8 @@

#endif // ARM

#include "core/platform/linux/cpuinfo.h"

#endif // Linux

#if _WIN32
Expand All @@ -51,6 +56,14 @@

#endif // _WIN32

#if defined(__APPLE__)
#if defined(CPUIDINFO_ARCH_ARM)

#include <sys/sysctl.h>

#endif // defined(CPUIDINFO_ARCH_ARM)
#endif // defined(__APPLE__)

#if defined(CPUINFO_SUPPORTED)
#include <cpuinfo.h>
#if defined(CPUIDINFO_ARCH_ARM)
Expand Down Expand Up @@ -170,9 +183,10 @@

uint32_t CPUIDInfo::GetVendorId(const std::string& vendor) {
if (vendor == "GenuineIntel") return 0x8086;
if (vendor == "GenuineAMD") return 0x1022;
if (vendor == "AuthenticAMD") return 0x1022;
if (vendor.find("Qualcomm") == 0) return 'Q' | ('C' << 8) | ('O' << 16) | ('M' << 24);
if (vendor.find("NV") == 0) return 0x10DE;
if (vendor == "Apple") return 0x106B;
return 0;
}

Expand All @@ -181,6 +195,9 @@
#if defined(__linux__)

void CPUIDInfo::ArmLinuxInit() {
vendor_ = GetArmLinuxVendor();
vendor_id_ = GetVendorId(vendor_);

// Assuming no hyper-threading, no NUMA groups
#if defined(CPUINFO_SUPPORTED)
if (pytorch_cpuinfo_init_) {
Expand Down Expand Up @@ -224,6 +241,23 @@
}
}

std::string CPUIDInfo::GetArmLinuxVendor() {
std::string vendor{};

CpuInfo cpu_info{};
Status parse_status = ParseCpuInfoFile(cpu_info);
if (!parse_status.IsOK()) {
LOGS_DEFAULT(WARNING) << "Failed to parse /proc/cpuinfo file. Error: " << parse_status;
}

if (cpu_info.size() > 0) {
// just use the vendor from the first processor's information
vendor = cpu_info[0].vendor_id;
}

return vendor;
}

#elif defined(_WIN32) // ^ defined(__linux__)

void CPUIDInfo::ArmWindowsInit() {
Expand Down Expand Up @@ -334,6 +368,9 @@
#elif defined(__APPLE__) // ^ defined(_WIN32)

void CPUIDInfo::ArmAppleInit() {
vendor_ = GetArmAppleVendor();
vendor_id_ = GetVendorId(vendor_);

#if defined(CPUINFO_SUPPORTED)
if (pytorch_cpuinfo_init_) {
is_hybrid_ = cpuinfo_get_uarchs_count() > 1;
Expand All @@ -354,6 +391,47 @@
}
}

std::string CPUIDInfo::GetArmAppleVendor() {
auto get_sysctl_value = [](const char* key) -> std::optional<std::string> {
size_t value_length{};
if (sysctlbyname(key, nullptr, &value_length, nullptr, 0) != 0) {
const auto error = errno;
if (error == ENOENT) {
LOGS_DEFAULT(INFO) << "sysctlbyname() key not found: '" << key << "'";
} else {
LOGS_DEFAULT(WARNING) << "Failed to get '" << key << "' value length with sysctlbyname(). "
<< "Error: " << error;
}
return std::nullopt;
}

std::string value{};
value.resize(value_length);
if (sysctlbyname(key, value.data(), &value_length, nullptr, 0) != 0) {
const auto error = errno;
LOGS_DEFAULT(WARNING) << "Failed to get '" << key << "' value with sysctlbyname(). "
<< "Error: " << error;
}

return value;
};

constexpr auto vendor_key = "machdep.cpu.vendor";
if (auto vendor = get_sysctl_value(vendor_key); vendor.has_value()) {
return *vendor;
}

constexpr auto brand_string_key = "machdep.cpu.brand_string";
if (auto brand_string = get_sysctl_value(brand_string_key); brand_string.has_value()) {
if (brand_string->find("Apple") != std::string::npos) {

Check warning on line 426 in onnxruntime/core/common/cpuid_info.cc

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Add #include <string> for string [build/include_what_you_use] [4] Raw Output: onnxruntime/core/common/cpuid_info.cc:426: Add #include <string> for string [build/include_what_you_use] [4]
return "Apple";
}
}

LOGS_DEFAULT(WARNING) << "Unable to determine CPU vendor.";
return "";
}

#endif // defined(__APPLE__)

#endif // defined(CPUIDINFO_ARCH_ARM)
Expand Down
2 changes: 2 additions & 0 deletions onnxruntime/core/common/cpuid_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
#if defined(__linux__)

void ArmLinuxInit();
std::string GetArmLinuxVendor();

#elif defined(_WIN32)

Expand All @@ -157,6 +158,7 @@
#elif defined(__APPLE__)

void ArmAppleInit();
std::string GetArmAppleVendor();

Check warning on line 161 in onnxruntime/core/common/cpuid_info.h

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Add #include <string> for string [build/include_what_you_use] [4] Raw Output: onnxruntime/core/common/cpuid_info.h:161: Add #include <string> for string [build/include_what_you_use] [4]

#endif

Expand Down
9 changes: 5 additions & 4 deletions onnxruntime/core/common/string_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ inline void TrimStringFromRight(std::string& s) {
* @param s The string to trim.
* @return The trimmed string.
*/
inline std::string TrimString(std::string s) {
TrimStringFromRight(s);
TrimStringFromLeft(s);
return s;
inline std::string TrimString(std::string_view s) {
std::string s_trimmed{s};
TrimStringFromRight(s_trimmed);
TrimStringFromLeft(s_trimmed);
return s_trimmed;
}

/**
Expand Down
40 changes: 40 additions & 0 deletions onnxruntime/core/platform/apple/device_discovery.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "core/platform/device_discovery.h"

#include "core/common/cpuid_info.h"

namespace onnxruntime {

namespace {

OrtHardwareDevice GetCpuDevice() {
const auto& cpuid_info = CPUIDInfo::GetCPUIDInfo();

OrtHardwareDevice cpu_device{};
cpu_device.vendor = cpuid_info.GetCPUVendor();
cpu_device.vendor_id = cpuid_info.GetCPUVendorId();
cpu_device.device_id = 0;
cpu_device.type = OrtHardwareDeviceType_CPU;

return cpu_device;
}

} // namespace

std::unordered_set<OrtHardwareDevice> DeviceDiscovery::DiscoverDevicesForPlatform() {
std::unordered_set<OrtHardwareDevice> devices;

Check warning on line 27 in onnxruntime/core/platform/apple/device_discovery.cc

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Add #include <unordered_set> for unordered_set<> [build/include_what_you_use] [4] Raw Output: onnxruntime/core/platform/apple/device_discovery.cc:27: Add #include <unordered_set> for unordered_set<> [build/include_what_you_use] [4]

// get CPU devices
devices.insert(GetCpuDevice());

// TODO

Check warning on line 32 in onnxruntime/core/platform/apple/device_discovery.cc

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2] Raw Output: onnxruntime/core/platform/apple/device_discovery.cc:32: Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2]

// get GPU devices

// get NPU devices

return devices;
}
} // namespace onnxruntime
11 changes: 3 additions & 8 deletions onnxruntime/core/platform/device_discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,19 @@

#pragma once

#include <string>
#include <unordered_set>

#include "core/session/abi_devices.h"

namespace onnxruntime {

class DeviceDiscovery {
public:
static std::unordered_set<OrtHardwareDevice>& GetDevices() {
// assumption: devices don't change. we assume the machine must be shutdown to change cpu/gpu/npu devices.
// technically someone could disable/enable a device in a running OS. we choose not to add complexity to support
// that scenario.
static std::unordered_set<OrtHardwareDevice> devices(DiscoverDevicesForPlatform());
return devices;
}
static const std::unordered_set<OrtHardwareDevice>& GetDevices();

private:
DeviceDiscovery() = default;

// platform specific code implements this method
static std::unordered_set<OrtHardwareDevice> DiscoverDevicesForPlatform();
};
Expand Down
42 changes: 42 additions & 0 deletions onnxruntime/core/platform/device_discovery_common.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// This file contains platform-agnostic device discovery implementation.

#include "core/platform/device_discovery.h"

#include <sstream>

#include "core/common/logging/logging.h"

namespace onnxruntime {

const std::unordered_set<OrtHardwareDevice>& DeviceDiscovery::GetDevices() {
// assumption: devices don't change. we assume the machine must be shutdown to change cpu/gpu/npu devices.
// technically someone could disable/enable a device in a running OS. we choose not to add complexity to support
// that scenario.
static std::unordered_set<OrtHardwareDevice> devices = []() {

Check warning on line 18 in onnxruntime/core/platform/device_discovery_common.cc

View workflow job for this annotation

GitHub Actions / Optional Lint C++

[cpplint] reported by reviewdog 🐶 Add #include <unordered_set> for unordered_set<> [build/include_what_you_use] [4] Raw Output: onnxruntime/core/platform/device_discovery_common.cc:18: Add #include <unordered_set> for unordered_set<> [build/include_what_you_use] [4]
auto discovered_devices = DiscoverDevicesForPlatform();

// log discovered devices
for (const auto& ortdevice : discovered_devices) {
std::ostringstream oss;
oss << "Discovered OrtHardwareDevice {vendor_id:0x" << std::hex << ortdevice.vendor_id
<< ", device_id:0x" << ortdevice.device_id
<< ", vendor:" << ortdevice.vendor
<< ", type:" << std::dec << static_cast<int>(ortdevice.type)
<< ", metadata: [";
for (auto& [key, value] : ortdevice.metadata.Entries()) {
oss << key << "=" << value << ", ";
}
oss << "]}";
LOGS_DEFAULT(INFO) << oss.str();
}

return discovered_devices;
}();

return devices;
}

} // namespace onnxruntime
Loading
Loading