amd_common.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. //go:build linux || windows
  2. package discover
  3. import (
  4. "errors"
  5. "log/slog"
  6. "os"
  7. "path/filepath"
  8. "runtime"
  9. "strings"
  10. "github.com/ollama/ollama/envconfig"
  11. )
  12. // Determine if the given ROCm lib directory is usable by checking for existence of some glob patterns
  13. func rocmLibUsable(libDir string) bool {
  14. slog.Debug("evaluating potential rocm lib dir " + libDir)
  15. for _, g := range ROCmLibGlobs {
  16. res, _ := filepath.Glob(filepath.Join(libDir, g))
  17. if len(res) == 0 {
  18. return false
  19. }
  20. }
  21. return true
  22. }
  23. func GetSupportedGFX(libDir string) ([]string, error) {
  24. var ret []string
  25. files, err := filepath.Glob(filepath.Join(libDir, "rocblas", "library", "TensileLibrary_lazy_gfx*.dat"))
  26. if err != nil {
  27. return nil, err
  28. }
  29. for _, file := range files {
  30. ret = append(ret, strings.TrimSuffix(strings.TrimPrefix(filepath.Base(file), "TensileLibrary_lazy_"), ".dat"))
  31. }
  32. return ret, nil
  33. }
  34. func commonAMDValidateLibDir() (string, error) {
  35. // Favor our bundled version
  36. // Installer payload location if we're running the installed binary
  37. exe, err := os.Executable()
  38. if err == nil {
  39. rocmTargetDir := filepath.Join(filepath.Dir(exe), envconfig.LibRelativeToExe(), "lib", "ollama")
  40. if rocmLibUsable(rocmTargetDir) {
  41. slog.Debug("detected ROCM next to ollama executable " + rocmTargetDir)
  42. return rocmTargetDir, nil
  43. }
  44. }
  45. // Prefer explicit HIP env var
  46. hipPath := os.Getenv("HIP_PATH")
  47. if hipPath != "" {
  48. hipLibDir := filepath.Join(hipPath, "bin")
  49. if rocmLibUsable(hipLibDir) {
  50. slog.Debug("detected ROCM via HIP_PATH=" + hipPath)
  51. return hipLibDir, nil
  52. }
  53. }
  54. // Scan the LD_LIBRARY_PATH or PATH
  55. pathEnv := "LD_LIBRARY_PATH"
  56. if runtime.GOOS == "windows" {
  57. pathEnv = "PATH"
  58. }
  59. paths := os.Getenv(pathEnv)
  60. for _, path := range filepath.SplitList(paths) {
  61. d, err := filepath.Abs(path)
  62. if err != nil {
  63. continue
  64. }
  65. if rocmLibUsable(d) {
  66. return d, nil
  67. }
  68. }
  69. // Well known location(s)
  70. for _, path := range RocmStandardLocations {
  71. if rocmLibUsable(path) {
  72. return path, nil
  73. }
  74. }
  75. return "", errors.New("no suitable rocm found, falling back to CPU")
  76. }