gpu_darwin.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //go:build darwin
  2. package discover
  3. /*
  4. #cgo CFLAGS: -x objective-c
  5. #cgo CPPFLAGS: -O3
  6. #cgo LDFLAGS: -framework Foundation -framework CoreGraphics -framework Metal
  7. #include "gpu_info_darwin.h"
  8. */
  9. import "C"
  10. import (
  11. "log/slog"
  12. "runtime"
  13. "syscall"
  14. "github.com/ollama/ollama/format"
  15. )
  16. const (
  17. metalMinimumMemory = 512 * format.MebiByte
  18. )
  19. func GetGPUInfo() GpuInfoList {
  20. mem, _ := GetCPUMem()
  21. if runtime.GOARCH == "amd64" {
  22. return []GpuInfo{
  23. {
  24. Library: "cpu",
  25. memInfo: mem,
  26. },
  27. }
  28. }
  29. info := GpuInfo{
  30. Library: "metal",
  31. ID: "0",
  32. }
  33. info.TotalMemory = uint64(C.getRecommendedMaxVRAM())
  34. // TODO is there a way to gather actual allocated video memory? (currentAllocatedSize doesn't work)
  35. info.FreeMemory = info.TotalMemory
  36. info.MinimumMemory = metalMinimumMemory
  37. return []GpuInfo{info}
  38. }
  39. func GetCPUInfo() GpuInfoList {
  40. mem, _ := GetCPUMem()
  41. return []GpuInfo{
  42. {
  43. Library: "cpu",
  44. memInfo: mem,
  45. },
  46. }
  47. }
  48. func GetCPUMem() (memInfo, error) {
  49. return memInfo{
  50. TotalMemory: uint64(C.getPhysicalMemory()),
  51. FreeMemory: uint64(C.getFreeMemory()),
  52. // FreeSwap omitted as Darwin uses dynamic paging
  53. }, nil
  54. }
  55. func (l GpuInfoList) GetVisibleDevicesEnv() (string, string) {
  56. // No-op on darwin
  57. return "", ""
  58. }
  59. func GetSystemInfo() SystemInfo {
  60. mem, _ := GetCPUMem()
  61. query := "hw.perflevel0.physicalcpu"
  62. perfCores, err := syscall.SysctlUint32(query)
  63. if err != nil {
  64. slog.Warn("failed to discover physical CPU details", "query", query, "error", err)
  65. }
  66. query = "hw.perflevel1.physicalcpu"
  67. efficiencyCores, _ := syscall.SysctlUint32(query) // On x86 xeon this wont return data
  68. // Determine thread count
  69. query = "hw.logicalcpu"
  70. logicalCores, _ := syscall.SysctlUint32(query)
  71. return SystemInfo{
  72. System: CPUInfo{
  73. GpuInfo: GpuInfo{
  74. memInfo: mem,
  75. },
  76. CPUs: []CPU{
  77. {
  78. CoreCount: int(perfCores + efficiencyCores),
  79. EfficiencyCoreCount: int(efficiencyCores),
  80. ThreadCount: int(logicalCores),
  81. },
  82. },
  83. },
  84. GPUs: GetGPUInfo(),
  85. }
  86. }