ports/misc/ollama/files/patch-FreeBSD-compatibility
2024-08-18 13:44:06 -07:00

277 lines
8.6 KiB
Text

-- patch based on https://github.com/ollama/ollama/issues/1102#issuecomment-2270042340
new file mode 100644
--- gpu/gpu_bsd.go.orig 2024-08-18 20:03:12 UTC
+++ gpu/gpu_bsd.go
@@ -0,0 +1,122 @@
+//go:build dragonfly || freebsd || netbsd || openbsd
+
+package gpu
+
+import "github.com/ollama/ollama/format"
+//import sysctl "github.com/lorenzosaino/go-sysctl" // sysctl: this is Linux-only, see https://github.com/lorenzosaino/go-sysctl/issues/7
+import sysctl "github.com/blabber/go-freebsd-sysctl/sysctl" // sysctl: this is FreeBSD-only basic library
+import (
+ "log/slog"
+)
+
+/*
+#cgo CFLAGS: -I/usr/local/include
+#cgo LDFLAGS: -L/usr/local/lib -lvulkan
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <vulkan/vulkan.h>
+
+bool hasVulkanSupport(uint64_t *memSize) {
+ VkInstance instance;
+
+ VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
+ appInfo.pApplicationName = "Ollama";
+ appInfo.apiVersion = VK_API_VERSION_1_0;
+
+ VkInstanceCreateInfo createInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
+ createInfo.pApplicationInfo = &appInfo;
+
+ // Create a Vulkan instance
+ if (vkCreateInstance(&createInfo, NULL, &instance) != VK_SUCCESS)
+ return false;
+
+ // Fetch the first physical Vulkan device. Note that numDevices is overwritten with the number of devices found
+ uint32_t numDevices = 1;
+ VkPhysicalDevice device;
+ vkEnumeratePhysicalDevices(instance, &numDevices, &device);
+ if (numDevices == 0) {
+ vkDestroyInstance(instance, NULL);
+ return false;
+ }
+
+ // Fetch the memory information for this device.
+ VkPhysicalDeviceMemoryProperties memProperties;
+ vkGetPhysicalDeviceMemoryProperties(device, &memProperties);
+
+ // Add up all the heaps.
+ VkDeviceSize totalMemory = 0;
+ for (uint32_t i = 0; i < memProperties.memoryHeapCount; ++i) {
+ if (memProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
+ *memSize += memProperties.memoryHeaps[i].size;
+ }
+ }
+
+ vkDestroyInstance(instance, NULL);
+ return true;
+}
+*/
+import "C"
+
+func GetGPUInfo() GpuInfoList {
+ var gpuMem C.uint64_t
+ if C.hasVulkanSupport(&gpuMem) {
+ // Vulkan supported
+ return []GpuInfo{
+ {
+ Library: "vulkan",
+ ID: "0",
+ MinimumMemory: 512 * format.MebiByte,
+ memInfo: memInfo{
+ FreeMemory: uint64(gpuMem),
+ TotalMemory: uint64(gpuMem),
+ },
+ },
+ }
+ }
+
+ // CPU fallback
+ cpuMem, _ := GetCPUMem()
+ return []GpuInfo{
+ {
+ Library: "cpu",
+ memInfo: cpuMem,
+ },
+ }
+}
+
+func GetCPUInfo() GpuInfoList {
+ mem, _ := GetCPUMem()
+ return []GpuInfo{
+ {
+ Library: "cpu",
+ Variant: GetCPUCapability(),
+ memInfo: mem,
+ },
+ }
+}
+
+func GetCPUMem() (memInfo, error) {
+ // all involved sysctl variables
+ sysctl_vm_page_size, _ := sysctl.GetInt64("vm.stats.vm.v_page_size") // memory page size
+ sysctl_hw_physmem, _ := sysctl.GetInt64("hw.physmem") // physical memory in bytes
+ sysctl_vm_free_count, _ := sysctl.GetInt64("vm.stats.vm.v_free_count") // free page count
+ sysctl_vm_swap_total, _ := sysctl.GetInt64("vm.swap_total") // total swap size in bytes
+
+ // individual values
+ total_memory := uint64(sysctl_hw_physmem)
+ free_memory := uint64(sysctl_vm_free_count) * uint64(sysctl_vm_page_size)
+ free_swap := uint64(sysctl_vm_swap_total) // wrong to use the total swap size here, should be vm.swap_free, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=280909
+
+ slog.Debug("gpu_bsd.go::GetCPUMem::GetCPUMem", "total_memory", total_memory, "free_memory", free_memory, "free_swap", free_swap)
+
+ return memInfo{
+ TotalMemory: uint64(total_memory),
+ FreeMemory: uint64(free_memory),
+ FreeSwap: uint64(free_swap),
+ }, nil
+}
+
+func (l GpuInfoList) GetVisibleDevicesEnv() (string, string) {
+ return "", ""
+}
--- gpu/gpu_test.go.orig 1979-11-30 08:00:00 UTC
+++ gpu/gpu_test.go
@@ -11,7 +11,7 @@ func TestBasicGetGPUInfo(t *testing.T) {
func TestBasicGetGPUInfo(t *testing.T) {
info := GetGPUInfo()
assert.NotEmpty(t, len(info))
- assert.Contains(t, "cuda rocm cpu metal", info[0].Library)
+ assert.Contains(t, "cuda rocm cpu metal vulkan", info[0].Library)
if info[0].Library != "cpu" {
assert.Greater(t, info[0].TotalMemory, uint64(0))
assert.Greater(t, info[0].FreeMemory, uint64(0))
@@ -24,6 +24,8 @@ func TestCPUMemInfo(t *testing.T) {
switch runtime.GOOS {
case "darwin":
t.Skip("CPU memory not populated on darwin")
+ case "dragonfly", "freebsd", "netbsd", "openbsd":
+ t.Skip("CPU memory is not populated on *BSD")
case "linux", "windows":
assert.Greater(t, info.TotalMemory, uint64(0))
assert.Greater(t, info.FreeMemory, uint64(0))
--- llm/generate/gen_bsd.sh.orig 2024-08-06 16:29:05 UTC
+++ llm/generate/gen_bsd.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# This script is intended to run inside the go generate
+# working directory must be ./llm/generate/
+
+set -ex
+set -o pipefail
+echo "Starting BSD generate script"
+. $(dirname $0)/gen_common.sh
+init_vars
+#git_module_setup
+apply_patches
+
+COMMON_BSD_DEFS="-DCMAKE_SYSTEM_NAME=$(uname -s)"
+CMAKE_TARGETS="--target llama --target ggml"
+
+COMMON_CPU_DEFS="${COMMON_BSD_DEFS} -DCMAKE_SYSTEM_PROCESSOR=${ARCH} -DBUILD_SHARED_LIBS=off"
+
+# Static build for linking into the Go binary
+init_vars
+CMAKE_DEFS="${COMMON_CPU_DEFS} -DGGML_VULKAN=on -DGGML_ACCELERATE=off -DGGML_AVX=off -DGGML_AVX2=off -DGGML_AVX512=off -DGGML_FMA=off -DGGML_F16C=off ${CMAKE_DEFS}"
+BUILD_DIR="../build/bsd/${ARCH}_static"
+echo "Building static library"
+build
+
+init_vars
+CMAKE_DEFS="${COMMON_CPU_DEFS} -DGGML_AVX=off -DGGML_AVX2=off -DGGML_AVX512=off -DGGML_FMA=off -DGGML_F16C=off ${CMAKE_DEFS}"
+BUILD_DIR="../build/bsd/${ARCH}/cpu"
+echo "Building LCD CPU"
+build
+compress
+
+init_vars
+CMAKE_DEFS="${COMMON_CPU_DEFS} -DGGML_AVX=on -DGGML_AVX2=off -DGGML_AVX512=off -DGGML_FMA=off -DGGML_F16C=off ${CMAKE_DEFS}"
+BUILD_DIR="../build/bsd/${ARCH}/cpu_avx"
+echo "Building AVX CPU"
+build
+compress
+
+init_vars
+CMAKE_DEFS="${COMMON_CPU_DEFS} -DGGML_AVX=on -DGGML_AVX2=on -DGGML_AVX512=off -DGGML_FMA=on -DGGML_F16C=on ${CMAKE_DEFS}"
+BUILD_DIR="../build/bsd/${ARCH}/cpu_avx2"
+echo "Building AVX2 CPU"
+build
+compress
+
+init_vars
+CMAKE_DEFS="${COMMON_CPU_DEFS} -DGGML_VULKAN=on ${CMAKE_DEFS}"
+BUILD_DIR="../build/bsd/${ARCH}/vulkan"
+echo "Building Vulkan GPU"
+build
+compress
+
+cleanup
+echo "go generate completed. LLM runners: $(cd ${BUILD_DIR}/..; echo *)"
--- llm/generate/generate_bsd.go.orig 2024-08-06 07:41:26 UTC
+++ llm/generate/generate_bsd.go
@@ -0,0 +1,5 @@
+//go:build dragonfly || freebsd || netbsd || openbsd
+
+package generate
+
+//go:generate bash ./gen_bsd.sh
--- llm/llm.go.orig 1979-11-30 08:00:00 UTC
+++ llm/llm.go
@@ -8,6 +8,10 @@ package llm
// #cgo windows,arm64 LDFLAGS: -static-libstdc++ -static-libgcc -static -L${SRCDIR}/build/windows/arm64_static -L${SRCDIR}/build/windows/arm64_static/src -L${SRCDIR}/build/windows/arm64_static/ggml/src
// #cgo linux,amd64 LDFLAGS: -L${SRCDIR}/build/linux/x86_64_static -L${SRCDIR}/build/linux/x86_64_static/src -L${SRCDIR}/build/linux/x86_64_static/ggml/src
// #cgo linux,arm64 LDFLAGS: -L${SRCDIR}/build/linux/arm64_static -L${SRCDIR}/build/linux/arm64_static/src -L${SRCDIR}/build/linux/arm64_static/ggml/src
+// #cgo dragonfly,amd64 LDFLAGS: ${SRCDIR}/build/bsd/x86_64_static/src/libllama.a -lstdc++ -lm
+// #cgo freebsd,amd64 LDFLAGS: -L${SRCDIR}/build/bsd/x86_64_static/src -lllama -L${SRCDIR}/build/bsd/x86_64_static/ggml/src -lggml -lstdc++ -lm -lomp
+// #cgo netbsd,amd64 LDFLAGS: ${SRCDIR}/build/bsd/x86_64_static/src/libllama.a -lstdc++ -lm
+// #cgo openbsd,amd64 LDFLAGS: ${SRCDIR}/build/bsd/x86_64_static/src/libllama.a -lstdc++ -lm
// #include <stdlib.h>
// #include "llama.h"
import "C"
--- llm/llm_bsd.go.orig 2024-08-06 07:41:26 UTC
+++ llm/llm_bsd.go
@@ -0,0 +1,13 @@
+//go:build dragonfly || freebsd || netbsd || openbsd
+
+package llm
+
+import (
+ "embed"
+ "syscall"
+)
+
+//go:embed build/bsd/*/*/bin/*
+var libEmbed embed.FS
+
+var LlamaServerSysProcAttr = &syscall.SysProcAttr{}
--- scripts/build_bsd.sh.orig 2024-08-06 07:41:26 UTC
+++ scripts/build_bsd.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+set -e
+
+case "$(uname -s)" in
+ DragonFly)
+ ;;
+ FreeBSD)
+ ;;
+ NetBSD)
+ ;;
+ OpenBSD)
+ ;;
+ *)
+ echo "$(uname -s) is not supported"
+ exit 1
+ ;;
+esac
+
+export VERSION=${VERSION:-$(git describe --tags --first-parent --abbrev=7 --long --dirty --always | sed -e "s/^v//g")}
+export GOFLAGS="'-ldflags=-w -s \"-X=github.com/ollama/ollama/version.Version=$VERSION\" \"-X=github.com/ollama/ollama/server.mode=release\"'"
+
+mkdir -p dist
+rm -rf llm/llama.cpp/build
+
+go generate ./...
+CGO_ENABLED=1 go build -trimpath -o dist/ollama-bsd
--- scripts/build_freebsd.sh.orig 2024-08-06 07:41:26 UTC
+++ scripts/build_freebsd.sh
@@ -0,0 +1 @@
+build_bsd.sh
\ No newline at end of file