Removed libcap related code
libcap is not directly related to Vulkan and should be added by its own PR. It adds additional library dependencies for building and also requires users to run setcap or run ollama as root, which is not ideal for easy use
This commit is contained in:
parent
834a66689e
commit
af5f5bdf60
|
|
@ -20,7 +20,7 @@ ENV PATH=/opt/rh/gcc-toolset-10/root/usr/bin:$PATH
|
|||
ARG VULKANVERSION
|
||||
RUN wget https://sdk.lunarg.com/sdk/download/${VULKANVERSION}/linux/vulkansdk-linux-x86_64-${VULKANVERSION}.tar.xz -O /tmp/vulkansdk-linux-x86_64-${VULKANVERSION}.tar.xz \
|
||||
&& tar xvf /tmp/vulkansdk-linux-x86_64-${VULKANVERSION}.tar.xz \
|
||||
&& dnf -y install ninja-build libcap-devel \
|
||||
&& dnf -y install ninja-build \
|
||||
&& ln -s /usr/bin/python3 /usr/bin/python \
|
||||
&& /${VULKANVERSION}/vulkansdk -j 8 vulkan-headers \
|
||||
&& /${VULKANVERSION}/vulkansdk -j 8 shaderc
|
||||
|
|
@ -126,7 +126,7 @@ COPY --from=build /bin/ollama /bin/ollama
|
|||
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y ca-certificates libcap2 libvulkan1 \
|
||||
&& apt-get install -y ca-certificates libvulkan1 \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=archive /bin /usr/bin
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ var (
|
|||
cudartLibPath string
|
||||
oneapiLibPath string
|
||||
vulkanLibPath string
|
||||
libcapLibPath string
|
||||
nvmlLibPath string
|
||||
rocmGPUs []RocmGPUInfo
|
||||
oneapiGPUs []OneapiGPUInfo
|
||||
|
|
@ -187,19 +186,18 @@ func initVulkanHandles() *vulkanHandles {
|
|||
vHandles := &vulkanHandles{}
|
||||
|
||||
// Short Circuit if we already know which library to use
|
||||
if vulkanLibPath != "" && libcapLibPath != "" {
|
||||
vHandles.deviceCount, vHandles.vulkan, _, _ = LoadVulkanMgmt([]string{vulkanLibPath}, []string{libcapLibPath})
|
||||
if vulkanLibPath != "" {
|
||||
vHandles.deviceCount, vHandles.vulkan, _ = LoadVulkanMgmt([]string{vulkanLibPath})
|
||||
return vHandles
|
||||
}
|
||||
|
||||
vulkanPaths := FindGPULibs(VulkanMgmtName, VulkanGlobs)
|
||||
libcapPaths := FindLibCapLibs()
|
||||
|
||||
if len(vulkanPaths) > 0 && len(libcapPaths) > 0 {
|
||||
slog.Info("vulkan: load libvulkan and libcap ok")
|
||||
vHandles.deviceCount, vHandles.vulkan, vulkanLibPath, libcapLibPath = LoadVulkanMgmt(vulkanPaths, libcapPaths)
|
||||
if len(vulkanPaths) > 0 {
|
||||
slog.Info("vulkan: load libvulkan ok")
|
||||
vHandles.deviceCount, vHandles.vulkan, vulkanLibPath = LoadVulkanMgmt(vulkanPaths)
|
||||
} else {
|
||||
slog.Info("vulkan: failed to load libvulkan or libcap")
|
||||
slog.Info("vulkan: failed to load libvulkan")
|
||||
}
|
||||
|
||||
return vHandles
|
||||
|
|
@ -760,32 +758,27 @@ func loadOneapiMgmt(oneapiLibPaths []string) (int, *C.oneapi_handle_t, string, e
|
|||
return 0, nil, "", err
|
||||
}
|
||||
|
||||
func LoadVulkanMgmt(vulkanLibPaths []string, capLibPaths []string) (int, *C.vk_handle_t, string, string) {
|
||||
func LoadVulkanMgmt(vulkanLibPaths []string) (int, *C.vk_handle_t, string) {
|
||||
var resp C.vk_init_resp_t
|
||||
resp.ch.verbose = getVerboseState()
|
||||
for _, vkLibPath := range vulkanLibPaths {
|
||||
for _, capLibPath := range capLibPaths {
|
||||
vkLib := C.CString(vkLibPath)
|
||||
capLib := C.CString(capLibPath)
|
||||
defer C.free(unsafe.Pointer(vkLib))
|
||||
defer C.free(unsafe.Pointer(capLib))
|
||||
vkLib := C.CString(vkLibPath)
|
||||
defer C.free(unsafe.Pointer(vkLib))
|
||||
|
||||
C.vk_init(vkLib, capLib, &resp)
|
||||
if resp.err != nil {
|
||||
slog.Error(
|
||||
"Unable to load vulkan",
|
||||
"vulkan_library", vkLibPath,
|
||||
"cap_library", capLibPath,
|
||||
"error", C.GoString(resp.err),
|
||||
)
|
||||
C.free(unsafe.Pointer(resp.err))
|
||||
} else {
|
||||
return int(resp.num_devices), &resp.ch, vkLibPath, capLibPath
|
||||
}
|
||||
C.vk_init(vkLib, &resp)
|
||||
if resp.err != nil {
|
||||
slog.Error(
|
||||
"Unable to load vulkan",
|
||||
"vulkan_library", vkLibPath,
|
||||
"error", C.GoString(resp.err),
|
||||
)
|
||||
C.free(unsafe.Pointer(resp.err))
|
||||
} else {
|
||||
return int(resp.num_devices), &resp.ch, vkLibPath
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil, "", ""
|
||||
return 0, nil, ""
|
||||
}
|
||||
|
||||
func getVerboseState() C.uint16_t {
|
||||
|
|
|
|||
|
|
@ -2,28 +2,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
int check_perfmon(vk_handle_t* rh) {
|
||||
#ifdef __linux__
|
||||
cap_t caps;
|
||||
const cap_value_t cap_list[1] = {CAP_PERFMON};
|
||||
|
||||
caps = (*rh->cap_get_proc)();
|
||||
if (caps == NULL)
|
||||
return -1;
|
||||
|
||||
if ((*rh->cap_set_flag)(caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET) == -1)
|
||||
return -1;
|
||||
|
||||
if ((*rh->cap_set_proc)(caps) == -1)
|
||||
return -1;
|
||||
|
||||
if ((*rh->cap_free)(caps) == -1)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_extension_supported(vk_handle_t* rh, VkPhysicalDevice device, char* extension) {
|
||||
VkPhysicalDeviceProperties properties;
|
||||
(*rh->vkGetPhysicalDeviceProperties)(device, &properties);
|
||||
|
|
@ -53,30 +31,22 @@ int is_extension_supported(vk_handle_t* rh, VkPhysicalDevice device, char* exten
|
|||
return 0;
|
||||
}
|
||||
|
||||
void vk_init(char* vk_lib_path, char* cap_lib_path, vk_init_resp_t *resp) {
|
||||
void vk_init(char* vk_lib_path, vk_init_resp_t *resp) {
|
||||
const int buflen = 256;
|
||||
char buf[buflen + 1];
|
||||
int i;
|
||||
|
||||
struct lookup {
|
||||
int is_cap;
|
||||
char *s;
|
||||
void **p;
|
||||
} l[] = {
|
||||
#ifdef __linux__
|
||||
{1, "cap_get_proc", (void *)&resp->ch.cap_get_proc},
|
||||
{1, "cap_get_bound", (void *)&resp->ch.cap_get_bound},
|
||||
{1, "cap_set_flag", (void *)&resp->ch.cap_set_flag},
|
||||
{1, "cap_set_proc", (void *)&resp->ch.cap_set_proc},
|
||||
{1, "cap_free", (void *)&resp->ch.cap_free},
|
||||
#endif
|
||||
{0, "vkGetPhysicalDeviceProperties", (void *)&resp->ch.vkGetPhysicalDeviceProperties},
|
||||
{0, "vkEnumerateDeviceExtensionProperties", (void *)&resp->ch.vkEnumerateDeviceExtensionProperties},
|
||||
{0, "vkCreateInstance", (void *)&resp->ch.vkCreateInstance},
|
||||
{0, "vkEnumeratePhysicalDevices", (void *)&resp->ch.vkEnumeratePhysicalDevices},
|
||||
{0, "vkGetPhysicalDeviceMemoryProperties2", (void *)&resp->ch.vkGetPhysicalDeviceMemoryProperties2},
|
||||
{0, "vkDestroyInstance", (void *)&resp->ch.vkDestroyInstance},
|
||||
{0, NULL, NULL},
|
||||
{"vkGetPhysicalDeviceProperties", (void *)&resp->ch.vkGetPhysicalDeviceProperties},
|
||||
{"vkEnumerateDeviceExtensionProperties", (void *)&resp->ch.vkEnumerateDeviceExtensionProperties},
|
||||
{"vkCreateInstance", (void *)&resp->ch.vkCreateInstance},
|
||||
{"vkEnumeratePhysicalDevices", (void *)&resp->ch.vkEnumeratePhysicalDevices},
|
||||
{"vkGetPhysicalDeviceMemoryProperties2", (void *)&resp->ch.vkGetPhysicalDeviceMemoryProperties2},
|
||||
{"vkDestroyInstance", (void *)&resp->ch.vkDestroyInstance},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
resp->ch.vk_handle = LOAD_LIBRARY(vk_lib_path, RTLD_LAZY);
|
||||
|
|
@ -91,39 +61,13 @@ void vk_init(char* vk_lib_path, char* cap_lib_path, vk_init_resp_t *resp) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
resp->ch.cap_handle = LOAD_LIBRARY(cap_lib_path, RTLD_LAZY);
|
||||
if (!resp->ch.cap_handle) {
|
||||
char *msg = LOAD_ERR();
|
||||
LOG(resp->ch.verbose, "library %s load err: %s\n", cap_lib_path, msg);
|
||||
snprintf(buf, buflen,
|
||||
"Unable to load %s library to query for Vulkan GPUs: %s",
|
||||
cap_lib_path, msg);
|
||||
free(msg);
|
||||
resp->err = strdup(buf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; l[i].s != NULL; i++) {
|
||||
if (l[i].is_cap)
|
||||
#ifdef __linux__
|
||||
*l[i].p = LOAD_SYMBOL(resp->ch.cap_handle, l[i].s);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
else
|
||||
*l[i].p = LOAD_SYMBOL(resp->ch.vk_handle, l[i].s);
|
||||
*l[i].p = LOAD_SYMBOL(resp->ch.vk_handle, l[i].s);
|
||||
if (!*l[i].p) {
|
||||
char *msg = LOAD_ERR();
|
||||
LOG(resp->ch.verbose, "dlerr: %s\n", msg);
|
||||
if (l[i].is_cap) {
|
||||
UNLOAD_LIBRARY(resp->ch.cap_handle);
|
||||
resp->ch.cap_handle = NULL;
|
||||
} else {
|
||||
UNLOAD_LIBRARY(resp->ch.vk_handle);
|
||||
resp->ch.vk_handle = NULL;
|
||||
}
|
||||
UNLOAD_LIBRARY(resp->ch.vk_handle);
|
||||
resp->ch.vk_handle = NULL;
|
||||
snprintf(buf, buflen, "symbol lookup for %s failed: %s", l[i].s,
|
||||
msg);
|
||||
free(msg);
|
||||
|
|
@ -132,12 +76,6 @@ void vk_init(char* vk_lib_path, char* cap_lib_path, vk_init_resp_t *resp) {
|
|||
}
|
||||
}
|
||||
|
||||
if (check_perfmon(&resp->ch) != 0) {
|
||||
resp->err = strdup("performance monitoring is not allowed. Please enable CAP_PERFMON or run as root to use Vulkan.");
|
||||
LOG(resp->ch.verbose, "vulkan: %s", resp->err);
|
||||
return;
|
||||
}
|
||||
|
||||
VkInstance instance;
|
||||
|
||||
VkApplicationInfo appInfo = {};
|
||||
|
|
@ -277,10 +215,4 @@ void vk_release(vk_handle_t rh) {
|
|||
(*rh.vkDestroyInstance)(rh.vk, NULL);
|
||||
UNLOAD_LIBRARY(rh.vk_handle);
|
||||
rh.vk_handle = NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
LOG(rh.verbose, "releasing libcap library\n");
|
||||
UNLOAD_LIBRARY(rh.cap_handle);
|
||||
rh.cap_handle = NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,29 +4,15 @@
|
|||
|
||||
#include "gpu_info.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
typedef struct {
|
||||
void* vk_handle;
|
||||
void* cap_handle;
|
||||
uint16_t verbose;
|
||||
|
||||
VkInstance vk;
|
||||
int num_devices;
|
||||
|
||||
#ifdef __linux__
|
||||
cap_t (*cap_get_proc)(void);
|
||||
|
||||
int (*cap_get_bound)(cap_value_t);
|
||||
int (*cap_set_flag)(cap_t, cap_flag_t, int, const cap_value_t *, cap_flag_value_t);
|
||||
int (*cap_set_proc)(cap_t);
|
||||
int (*cap_free)(cap_t);
|
||||
#endif
|
||||
|
||||
void (*vkGetPhysicalDeviceProperties)(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceProperties* pProperties);
|
||||
|
|
@ -58,7 +44,7 @@ typedef struct vk_init_resp
|
|||
vk_handle_t ch;
|
||||
} vk_init_resp_t;
|
||||
|
||||
void vk_init(char* vk_lib_path, char* cap_lib_path, vk_init_resp_t *resp);
|
||||
void vk_init(char* vk_lib_path, vk_init_resp_t *resp);
|
||||
void vk_check_vram(vk_handle_t rh, int i, mem_info_t *resp);
|
||||
int vk_check_flash_attention(vk_handle_t rh, int i);
|
||||
void vk_release(vk_handle_t rh);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ var (
|
|||
NvmlMgmtName = "" // not currently wired on linux
|
||||
OneapiMgmtName = "libze_intel_gpu.so*"
|
||||
VulkanMgmtName = "libvulkan.so*"
|
||||
libcapMgmtName = "libcap.so*"
|
||||
)
|
||||
|
||||
var VulkanGlobs = []string{
|
||||
|
|
@ -62,16 +61,6 @@ var VulkanGlobs = []string{
|
|||
"/usr/lib*/libvulkan.so*",
|
||||
}
|
||||
|
||||
var capLinuxGlobs = []string{
|
||||
"/usr/lib/x86_64-linux-gnu/libcap.so*",
|
||||
"/usr/lib/aarch64-linux-gnu/libvulkan.so*",
|
||||
"/usr/lib*/libcap.so*",
|
||||
}
|
||||
|
||||
func FindLibCapLibs() []string {
|
||||
return FindGPULibs(libcapMgmtName, capLinuxGlobs)
|
||||
}
|
||||
|
||||
func GetCPUMem() (memInfo, error) {
|
||||
var mem memInfo
|
||||
var total, available, free, buffers, cached, freeSwap uint64
|
||||
|
|
|
|||
Loading…
Reference in New Issue