llama_darwin.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. actualSum := sha256.New()
  37. if _, err := io.Copy(actualSum, actual); err != nil {
  38. return err
  39. }
  40. expect, err := fs.Open("ggml-metal.metal")
  41. if err != nil {
  42. return err
  43. }
  44. expectSum := sha256.New()
  45. if _, err := io.Copy(expectSum, expect); err != nil {
  46. return err
  47. }
  48. if bytes.Equal(actualSum.Sum(nil), expectSum.Sum(nil)) {
  49. return nil
  50. }
  51. }
  52. dst, err := os.Create(filepath.Join(filepath.Dir(exec), "ggml-metal.metal"))
  53. if err != nil {
  54. return err
  55. }
  56. defer dst.Close()
  57. src, err := fs.Open("ggml-metal.metal")
  58. if err != nil {
  59. return err
  60. }
  61. defer src.Close()
  62. if _, err := io.Copy(dst, src); err != nil {
  63. return err
  64. }
  65. return nil
  66. }