llama_darwin.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package llm
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "errors"
  6. "io"
  7. "log"
  8. "os"
  9. "path/filepath"
  10. )
  11. func init() {
  12. if err := initBackend(); err != nil {
  13. log.Printf("WARNING: GPU could not be initialized correctly: %v", err)
  14. log.Printf("WARNING: falling back to CPU")
  15. }
  16. }
  17. func initBackend() error {
  18. exec, err := os.Executable()
  19. if err != nil {
  20. return err
  21. }
  22. exec, err = filepath.EvalSymlinks(exec)
  23. if err != nil {
  24. return err
  25. }
  26. metal := filepath.Join(filepath.Dir(exec), "ggml-metal.metal")
  27. fi, err := os.Stat(metal)
  28. if err != nil && !errors.Is(err, os.ErrNotExist) {
  29. return err
  30. }
  31. if fi != nil {
  32. actual, err := os.Open(metal)
  33. if err != nil {
  34. return err
  35. }
  36. defer actual.Close()
  37. actualSum := sha256.New()
  38. if _, err := io.Copy(actualSum, actual); err != nil {
  39. return err
  40. }
  41. expect, err := fs.Open("ggml-metal.metal")
  42. if err != nil {
  43. return err
  44. }
  45. expectSum := sha256.New()
  46. if _, err := io.Copy(expectSum, expect); err != nil {
  47. return err
  48. }
  49. if bytes.Equal(actualSum.Sum(nil), expectSum.Sum(nil)) {
  50. return nil
  51. }
  52. }
  53. dst, err := os.Create(filepath.Join(filepath.Dir(exec), "ggml-metal.metal"))
  54. if err != nil {
  55. return err
  56. }
  57. defer dst.Close()
  58. src, err := fs.Open("ggml-metal.metal")
  59. if err != nil {
  60. return err
  61. }
  62. defer src.Close()
  63. if _, err := io.Copy(dst, src); err != nil {
  64. return err
  65. }
  66. return nil
  67. }