Skip to content

Commit bc4551a

Browse files
committed
Updated bindings
1 parent 1864caa commit bc4551a

File tree

11 files changed

+216
-6
lines changed

11 files changed

+216
-6
lines changed

Makefile

+24-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Paths to packages
22
DOCKER=$(shell which docker)
33
GIT=$(shell which git)
4+
GO=$(shell which go)
45

56
# Other paths
67
ROOT_PATH := $(CURDIR)
@@ -26,6 +27,16 @@ ifdef CUDA_HOME
2627
ONNXRUNTIME_FLAGS += --use_cuda --cuda_home=${CUDA_HOME} --cudnn_home=${CUDA_HOME}
2728
endif
2829

30+
# Generate the pkg-config files
31+
generate: mkdir go-tidy
32+
@echo "Generating pkg-config"
33+
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} go generate ./sys/llamacpp
34+
35+
# Test llamacpp bindings
36+
test: generate llamacpp
37+
@echo "Running tests (sys)"
38+
@PKG_CONFIG_PATH=${ROOT_PATH}/${BUILD_DIR} ${GO} test -v ./sys/llamacpp/...
39+
2940
# Base images for building and running CUDA containers
3041
docker-base: docker-dep
3142
@echo "Building ${DOCKER_TAG_BASE_BUILD}"
@@ -51,10 +62,10 @@ docker: docker-dep docker-base
5162
--build-arg BASE_IMAGE_RUNTIME=${DOCKER_TAG_BASE_RUNTIME} \
5263
-f Dockerfile.llamacpp .
5364

54-
# Build llama-server
65+
# Build llama libraries
5566
llamacpp: submodule-checkout
5667
@echo "Building llamacpp"
57-
@cd llama.cpp && make -j$(nproc) libllama.a
68+
@cd llama.cpp && make -j$(nproc) libllama.a libggml.a
5869

5970
onnxruntime: submodule-checkout
6071
@echo "Building onnxruntime"
@@ -95,8 +106,13 @@ mkdir:
95106
@echo Mkdir ${BUILD_DIR}
96107
@install -d ${BUILD_DIR}
97108

109+
# go mod tidy
110+
go-tidy: go-dep
111+
@echo Tidy
112+
@go mod tidy
113+
98114
# Clean
99-
clean: submodule-clean
115+
clean: submodule-clean go-tidy
100116
@echo "Cleaning"
101117
@rm -rf ${BUILD_DIR}
102118

@@ -106,4 +122,8 @@ docker-dep:
106122

107123
# Check for git
108124
git-dep:
109-
@test -f "${GIT}" && test -x "${GIT}" || (echo "Missing git binary" && exit 1)
125+
@test -f "${GIT}" && test -x "${GIT}" || (echo "Missing git binary" && exit 1)
126+
127+
# Check for go
128+
go-dep:
129+
@test -f "${GO}" && test -x "${GO}" || (echo "Missing go binary" && exit 1)

build/libllamacpp.pc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
prefix=/Users/djt/projects/docker-llamacpp
2+
3+
Name: libllamacpp.pc
4+
Description: No description
5+
Version: 0.0.0
6+
Cflags: -I${prefix}/llama.cpp/include
7+
Libs: -L${prefix}/llama.cpp -lllamacpp

build/llamacpp-darwin.pc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Name: llamacpp-darwin.pc
2+
Description: No description
3+
Version: 0.0.0
4+
Libs: -framework Accelerate -framework Metal -framework Foundation -framework CoreGraphics

build/llamacpp.pc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
prefix=/Users/djt/projects/docker-llamacpp
2+
3+
Name: llamacpp.pc
4+
Description: No description
5+
Version: 0.0.0
6+
Cflags: -I${prefix}/llama.cpp/include -I${prefix}/llama.cpp/ggml/include
7+
Libs: -L${prefix}/llama.cpp -lllama -lggml -lm -lstdc++

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/mutablelogic/docker-llamacpp
2+
3+
go 1.22.3

llama.cpp

sys/llamacpp/generate.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package llamacpp
2+
3+
///////////////////////////////////////////////////////////////////////////////
4+
// CGO
5+
6+
/*
7+
#cgo pkg-config: llamacpp
8+
#cgo darwin pkg-config: llamacpp-darwin
9+
*/
10+
import "C"
11+
12+
// Generate the llamacpp pkg-config files
13+
// Setting the prefix to the base of the repository
14+
15+
//go:generate go run ../pkg-config --version "0.0.0" --libs "-framework Accelerate -framework Metal -framework Foundation -framework CoreGraphics" llamacpp-darwin.pc
16+
//go:generate go run ../pkg-config --version "0.0.0" --prefix "../.." --cflags "-I$DOLLAR{prefix}/llama.cpp/include -I$DOLLAR{prefix}/llama.cpp/ggml/include" --libs "-L$DOLLAR{prefix}/llama.cpp -lllama -lggml -lm -lstdc++" llamacpp.pc

sys/llamacpp/llamacpp.go

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package llamacpp
2+
3+
///////////////////////////////////////////////////////////////////////////////
4+
// CGO
5+
6+
/*
7+
#cgo pkg-config: llamacpp
8+
#include <llama.h>
9+
#include <stdlib.h>
10+
*/
11+
import "C"
12+
import "unsafe"
13+
14+
///////////////////////////////////////////////////////////////////////////////
15+
// TYPES
16+
17+
type (
18+
Ggml_numa_strategy C.enum_ggml_numa_strategy
19+
Llama_model C.struct_llama_model
20+
Llama_model_params C.struct_llama_model_params
21+
)
22+
23+
///////////////////////////////////////////////////////////////////////////////
24+
// GLOBALS
25+
26+
const (
27+
GGML_NUMA_STRATEGY_DISABLED = C.GGML_NUMA_STRATEGY_DISABLED
28+
GGML_NUMA_STRATEGY_DISTRIBUTE = C.GGML_NUMA_STRATEGY_DISTRIBUTE
29+
GGML_NUMA_STRATEGY_ISOLATE = C.GGML_NUMA_STRATEGY_ISOLATE
30+
GGML_NUMA_STRATEGY_NUMACTL = C.GGML_NUMA_STRATEGY_NUMACTL
31+
GGML_NUMA_STRATEGY_MIRROR = C.GGML_NUMA_STRATEGY_MIRROR
32+
)
33+
34+
///////////////////////////////////////////////////////////////////////////////
35+
// LIFECYCLE
36+
37+
// Initialize the llama + ggml backend. If numa is true, use NUMA optimizations
38+
// Call once at the start of the program
39+
func Llama_backend_init() {
40+
C.llama_backend_init()
41+
}
42+
43+
func Llama_numa_init(numa Ggml_numa_strategy) {
44+
C.llama_numa_init(C.enum_ggml_numa_strategy(numa))
45+
}
46+
47+
// Call once at the end of the program - currently only used for MPI
48+
func Llama_backend_free() {
49+
C.llama_backend_free()
50+
}
51+
52+
// Load a model from a file
53+
func Llama_load_model_from_file(path string, params Llama_model_params) *Llama_model {
54+
cPath := C.CString(path)
55+
defer C.free(unsafe.Pointer(cPath))
56+
return (*Llama_model)(C.llama_load_model_from_file(cPath, C.struct_llama_model_params(params)))
57+
}
58+
59+
// Free a model
60+
func Llama_free_model(model *Llama_model) {
61+
C.llama_free_model((*C.struct_llama_model)(model))
62+
}

sys/llamacpp/llamacpp_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package llamacpp_test
2+
3+
import (
4+
"testing"
5+
6+
// Packages
7+
"github.com/mutablelogic/docker-llamacpp/sys/llamacpp"
8+
)
9+
10+
// 483MB
11+
const MODEL = "https://huggingface.co/ggerganov/ggml/resolve/main/ggml-model-gpt-2-117M.bin?download=true"
12+
13+
func Test_llamacpp_000(t *testing.T) {
14+
llamacpp.Llama_backend_free()
15+
llamacpp.Llama_backend_free()
16+
}
17+
18+
func Test_llamacpp_001(t *testing.T) {
19+
llamacpp.Llama_backend_free()
20+
t.Cleanup(func() {
21+
llamacpp.Llama_backend_free()
22+
})
23+
24+
model := llamacpp.Llama_load_model_from_file("/private/tmp/ggml-model-gpt-2-117M.bin", llamacpp.Llama_model_params{})
25+
llamacpp.Llama_free_model(model)
26+
}

sys/pkg-config/main.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
var (
11+
flagDir = flag.String("dir", "${PKG_CONFIG_PATH}", "Destination directory")
12+
flagPrefix = flag.String("prefix", "", "Prefix for the package")
13+
flagVersion = flag.String("version", "", "Version for the package")
14+
flagDescription = flag.String("description", "", "Description for the package")
15+
flagCompileFlags = flag.String("cflags", "", "Compiler flag")
16+
flagLinkerFlags = flag.String("libs", "", "Linker flags")
17+
)
18+
19+
func main() {
20+
flag.Parse()
21+
if flag.NArg() != 1 {
22+
fmt.Fprintln(os.Stderr, "Missing filename")
23+
os.Exit(-1)
24+
}
25+
dest := filepath.Join(os.ExpandEnv(*flagDir), flag.Arg(0))
26+
27+
fmt.Println("Generating", dest)
28+
29+
var prefix string
30+
if *flagPrefix != "" {
31+
var err error
32+
prefix, err = filepath.Abs(*flagPrefix)
33+
if err != nil {
34+
fmt.Fprintln(os.Stderr, err)
35+
os.Exit(-1)
36+
}
37+
}
38+
39+
w, err := os.Create(dest)
40+
if err != nil {
41+
fmt.Fprintln(os.Stderr, err)
42+
os.Exit(-1)
43+
}
44+
defer w.Close()
45+
46+
// Write the package
47+
if prefix != "" {
48+
fmt.Fprintf(w, "prefix=%s\n\n", prefix)
49+
}
50+
fmt.Fprintf(w, "Name: %s\n", filepath.Base(dest))
51+
if *flagDescription != "" {
52+
fmt.Fprintf(w, "Description: %s\n", *flagDescription)
53+
} else {
54+
fmt.Fprintf(w, "Description: No description\n")
55+
}
56+
if *flagVersion != "" {
57+
fmt.Fprintf(w, "Version: %s\n", *flagVersion)
58+
}
59+
if *flagCompileFlags != "" {
60+
fmt.Fprintf(w, "Cflags: %s\n", *flagCompileFlags)
61+
}
62+
if *flagLinkerFlags != "" {
63+
fmt.Fprintf(w, "Libs: %s\n", *flagLinkerFlags)
64+
}
65+
}

0 commit comments

Comments
 (0)