forked from third-party-mirrors/ollama
165 lines
5.8 KiB
C
165 lines
5.8 KiB
C
#include "dyn_ext_server.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifdef __linux__
|
|
#include <dlfcn.h>
|
|
#define LOAD_LIBRARY(lib, flags) dlopen(lib, flags)
|
|
#define LOAD_SYMBOL(handle, sym) dlsym(handle, sym)
|
|
#define LOAD_ERR() strdup(dlerror())
|
|
#define UNLOAD_LIBRARY(handle) dlclose(handle)
|
|
#elif _WIN32
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
|
|
HMODULE LoadLibraryWindows(const char* lib) {
|
|
int len = MultiByteToWideChar(CP_UTF8, 0, lib, -1, NULL, 0);
|
|
wchar_t* wLibPath = (wchar_t*)malloc(len * sizeof(wchar_t));
|
|
MultiByteToWideChar(CP_UTF8, 0, lib, -1, wLibPath, len);
|
|
HMODULE mod = LoadLibraryW(wLibPath);
|
|
free(wLibPath);
|
|
return mod;
|
|
}
|
|
|
|
char* LoadErrorWindows(void) {
|
|
LPWSTR messageBuffer = NULL;
|
|
DWORD size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
|
|
if (size == 0) {
|
|
return strdup("");
|
|
}
|
|
|
|
// convert the wide character string to a character string
|
|
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, messageBuffer, -1, NULL, 0, NULL, NULL);
|
|
char* errorMessage = (char*)malloc(requiredSize);
|
|
WideCharToMultiByte(CP_UTF8, 0, messageBuffer, -1, errorMessage, requiredSize, NULL, NULL);
|
|
|
|
LocalFree(messageBuffer);
|
|
return errorMessage;
|
|
}
|
|
|
|
#define LOAD_LIBRARY(lib, flags) LoadLibraryWindows(lib)
|
|
#define LOAD_SYMBOL(handle, sym) GetProcAddress(handle, sym)
|
|
#define UNLOAD_LIBRARY(handle) FreeLibrary(handle)
|
|
#define LOAD_ERR() LoadErrorWindows()
|
|
|
|
#else
|
|
#include <dlfcn.h>
|
|
#define LOAD_LIBRARY(lib, flags) dlopen(lib, flags)
|
|
#define LOAD_SYMBOL(handle, sym) dlsym(handle, sym)
|
|
#define LOAD_ERR() strdup(dlerror())
|
|
#define UNLOAD_LIBRARY(handle) dlclose(handle)
|
|
#endif
|
|
|
|
void dyn_init(const char *libPath, struct dynamic_llama_server *s,
|
|
ext_server_resp_t *err) {
|
|
int i = 0;
|
|
struct lookup {
|
|
char *s;
|
|
void **p;
|
|
} l[] = {
|
|
{"llama_server_init", (void *)&s->llama_server_init},
|
|
{"llama_server_start", (void *)&s->llama_server_start},
|
|
{"llama_server_stop", (void *)&s->llama_server_stop},
|
|
{"llama_server_completion", (void *)&s->llama_server_completion},
|
|
{"llama_server_completion_next_result",
|
|
(void *)&s->llama_server_completion_next_result},
|
|
{"llama_server_completion_cancel",
|
|
(void *)&s->llama_server_completion_cancel},
|
|
{"llama_server_release_task_result",
|
|
(void *)&s->llama_server_release_task_result},
|
|
{"llama_server_tokenize", (void *)&s->llama_server_tokenize},
|
|
{"llama_server_detokenize", (void *)&s->llama_server_detokenize},
|
|
{"llama_server_embedding", (void *)&s->llama_server_embedding},
|
|
{"llama_server_release_json_resp",
|
|
(void *)&s->llama_server_release_json_resp},
|
|
{"", NULL},
|
|
};
|
|
|
|
printf("loading library %s\n", libPath);
|
|
s->handle = LOAD_LIBRARY(libPath, RTLD_LOCAL|RTLD_NOW);
|
|
if (!s->handle) {
|
|
err->id = -1;
|
|
char *msg = LOAD_ERR();
|
|
snprintf(err->msg, err->msg_len,
|
|
"Unable to load dynamic server library: %s", msg);
|
|
free(msg);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; l[i].p != NULL; i++) {
|
|
*l[i].p = LOAD_SYMBOL(s->handle, l[i].s);
|
|
if (!l[i].p) {
|
|
UNLOAD_LIBRARY(s->handle);
|
|
err->id = -1;
|
|
char *msg = LOAD_ERR();
|
|
snprintf(err->msg, err->msg_len, "symbol lookup for %s failed: %s",
|
|
l[i].s, msg);
|
|
free(msg);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void dyn_llama_server_init(struct dynamic_llama_server s,
|
|
ext_server_params_t *sparams,
|
|
ext_server_resp_t *err) {
|
|
s.llama_server_init(sparams, err);
|
|
}
|
|
|
|
inline void dyn_llama_server_start(struct dynamic_llama_server s) {
|
|
s.llama_server_start();
|
|
}
|
|
|
|
inline void dyn_llama_server_stop(struct dynamic_llama_server s) {
|
|
s.llama_server_stop();
|
|
}
|
|
|
|
inline void dyn_llama_server_completion(struct dynamic_llama_server s,
|
|
const char *json_req,
|
|
ext_server_resp_t *resp) {
|
|
s.llama_server_completion(json_req, resp);
|
|
}
|
|
|
|
inline void dyn_llama_server_completion_next_result(
|
|
struct dynamic_llama_server s, const int task_id,
|
|
ext_server_task_result_t *result) {
|
|
s.llama_server_completion_next_result(task_id, result);
|
|
}
|
|
|
|
inline void dyn_llama_server_completion_cancel(
|
|
struct dynamic_llama_server s, const int task_id, ext_server_resp_t *err) {
|
|
s.llama_server_completion_cancel(task_id, err);
|
|
}
|
|
inline void dyn_llama_server_release_task_result(
|
|
struct dynamic_llama_server s, ext_server_task_result_t *result) {
|
|
s.llama_server_release_task_result(result);
|
|
}
|
|
|
|
inline void dyn_llama_server_tokenize(struct dynamic_llama_server s,
|
|
const char *json_req,
|
|
char **json_resp,
|
|
ext_server_resp_t *err) {
|
|
s.llama_server_tokenize(json_req, json_resp, err);
|
|
}
|
|
|
|
inline void dyn_llama_server_detokenize(struct dynamic_llama_server s,
|
|
const char *json_req,
|
|
char **json_resp,
|
|
ext_server_resp_t *err) {
|
|
s.llama_server_detokenize(json_req, json_resp, err);
|
|
}
|
|
|
|
inline void dyn_llama_server_embedding(struct dynamic_llama_server s,
|
|
const char *json_req,
|
|
char **json_resp,
|
|
ext_server_resp_t *err) {
|
|
s.llama_server_embedding(json_req, json_resp, err);
|
|
}
|
|
|
|
inline void dyn_llama_server_release_json_resp(
|
|
struct dynamic_llama_server s, char **json_resp) {
|
|
s.llama_server_release_json_resp(json_resp);
|
|
}
|