gpu_darwin.go 2.0 KB

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