Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 18 additions & 2 deletions Source/MLX/GPU+Metal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,29 @@ public enum GPU {
}

/// Get information about the GPU device and system settings
///
/// The value is computed once per process.
public static func deviceInfo() -> DeviceInfo {
cachedDeviceInfo
}

private static let cachedDeviceInfo: DeviceInfo = {
var mib = [CTL_HW, HW_MEMSIZE]
var memSize: size_t = 0
var length: size_t = MemoryLayout.size(ofValue: memSize)
sysctl(&mib, 2, &memSize, &length, nil, 0)

if let device = MTLCreateSystemDefaultDevice() {
// Select the device the same way as MLX (metal::load_device): the first
// device of MTLCopyAllDevices(), else the system default device. In a
// command-line process MTLCreateSystemDefaultDevice() opens a window
// server session, which can stall for several seconds.
#if os(macOS)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might also want to cover macCatalyst here too -- the same calls are available but it isn't os(macOS):

#if os(macOS) || targetEnvironment(macCatalyst)

Though if the primary concern is for command line tools, I am not sure you can create one that is macCatalyst.

let device = MTLCopyAllDevices().first ?? MTLCreateSystemDefaultDevice()
#else
let device = MTLCreateSystemDefaultDevice()
#endif

if let device {
let architecture: String
if #available(macOS 14.0, iOS 17.0, tvOS 17.0, *) {
architecture = device.architecture.name
Expand All @@ -265,5 +281,5 @@ public enum GPU {
architecture: "Unknown", maxBufferSize: 0, maxRecommendedWorkingSetSize: 0,
memorySize: memSize)
}
}
}()
}
15 changes: 15 additions & 0 deletions Tests/MLXTests/MemoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,19 @@ class MemoryTests: XCTestCase {
print(x * x)
}
}

func testDeviceInfo() {
let info = GPU.deviceInfo()
XCTAssertGreaterThan(info.memorySize, 0)

guard Device.defaultDevice().deviceType == .gpu else { return }
XCTAssertNotEqual(info.architecture, "Unknown")
XCTAssertGreaterThan(info.maxBufferSize, 0)
XCTAssertGreaterThan(info.maxRecommendedWorkingSetSize, 0)

let again = GPU.deviceInfo()
XCTAssertEqual(again.architecture, info.architecture)
XCTAssertEqual(again.maxBufferSize, info.maxBufferSize)
XCTAssertEqual(again.maxRecommendedWorkingSetSize, info.maxRecommendedWorkingSetSize)
}
}
Loading