shim_darwin.go 1.75 KB
Newer Older
1
2
3
package llm

import (
4
	"embed"
5
	"errors"
6
	"fmt"
7
8
	"io"
	"io/fs"
9
10
	"log"
	"os"
11
	"path/filepath"
12
13
14
15

	"github.com/jmorganca/ollama/api"
)

16
//go:embed llama.cpp/ggml-metal.metal
17
var libEmbed embed.FS
18

19
func newDynamicShimExtServer(library, model string, adapters, projectors []string, numLayers int64, opts api.Options) (extServer, error) {
20
	// should never happen...
21
	return nil, fmt.Errorf("Dynamic library loading not supported on Mac")
22
23
}

24
func nativeInit(workdir string) error {
25
	err := extractPayloadFiles(workdir, "llama.cpp/ggml-metal.metal")
26
27
28
29
30
31
32
33
34
	if err != nil {
		if err == payloadMissing {
			// TODO perhaps consider this a hard failure on arm macs?
			log.Printf("ggml-meta.metal payload missing")
			return nil
		}
		return err
	}
	os.Setenv("GGML_METAL_PATH_RESOURCES", workdir)
35
36
	return nil
}
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

func extractPayloadFiles(workDir, glob string) error {
	files, err := fs.Glob(libEmbed, glob)
	if err != nil || len(files) == 0 {
		return payloadMissing
	}

	for _, file := range files {
		srcFile, err := libEmbed.Open(file)
		if err != nil {
			return fmt.Errorf("read payload %s: %v", file, err)
		}
		defer srcFile.Close()
		if err := os.MkdirAll(workDir, 0o755); err != nil {
			return fmt.Errorf("create payload temp dir %s: %v", workDir, err)
		}

		destFile := filepath.Join(workDir, filepath.Base(file))
		_, err = os.Stat(destFile)
		switch {
		case errors.Is(err, os.ErrNotExist):
			destFile, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o755)
			if err != nil {
				return fmt.Errorf("write payload %s: %v", file, err)
			}
			defer destFile.Close()
			if _, err := io.Copy(destFile, srcFile); err != nil {
				return fmt.Errorf("copy payload %s: %v", file, err)
			}
		case err != nil:
			return fmt.Errorf("stat payload %s: %v", file, err)
		}
	}
	return nil
}