5using System.Collections.Generic;
7using System.Runtime.InteropServices;
16 public class StreamWrapper
19 Callback<string> callback;
21 string previousString =
"";
22 string previousCalledString =
"";
23 int previousBufferSize = 0;
26 public StreamWrapper(LLMLib llmlib, Callback<string> callback,
bool clearOnUpdate =
false)
29 this.callback = callback;
30 this.clearOnUpdate = clearOnUpdate;
31 stringWrapper = (llmlib?.StringWrapper_Construct()).GetValueOrDefault();
39 public string GetString(
bool clear =
false)
42 int bufferSize = (llmlib?.StringWrapper_GetStringSize(stringWrapper)).GetValueOrDefault();
47 else if (previousBufferSize != bufferSize)
49 IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
52 llmlib?.StringWrapper_GetString(stringWrapper, buffer, bufferSize, clear);
53 result = Marshal.PtrToStringAnsi(buffer);
57 Marshal.FreeHGlobal(buffer);
59 previousString = result;
63 result = previousString;
65 previousBufferSize = bufferSize;
74 if (stringWrapper == IntPtr.Zero)
return;
75 string result = GetString(clearOnUpdate);
76 if (result !=
"" && previousCalledString != result)
78 callback?.Invoke(result);
79 previousCalledString = result;
87 public IntPtr GetStringWrapper()
97 if (stringWrapper != IntPtr.Zero) llmlib?.StringWrapper_Delete(stringWrapper);
107 static class LibraryLoader
116 public static T GetSymbolDelegate<T>(IntPtr library,
string name) where T : Delegate
118 var symbol = GetSymbol(library, name);
119 if (symbol == IntPtr.Zero)
120 throw new EntryPointNotFoundException($
"Unable to load symbol '{name}'.");
122 return Marshal.GetDelegateForFunctionPointer<T>(symbol);
130 public static IntPtr LoadLibrary(
string libraryName)
132 if (
string.IsNullOrEmpty(libraryName))
133 throw new ArgumentNullException(nameof(libraryName));
136 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
137 handle = Win32.LoadLibrary(libraryName);
138 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
139 handle = Linux.dlopen(libraryName);
140 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
141 handle = Mac.dlopen(libraryName);
142 else if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.VisionOS)
143 handle = Mobile.dlopen(libraryName);
145 throw new PlatformNotSupportedException($
"Current platform is unknown, unable to load library '{libraryName}'.");
156 public static IntPtr GetSymbol(IntPtr library,
string symbolName)
158 if (
string.IsNullOrEmpty(symbolName))
159 throw new ArgumentNullException(nameof(symbolName));
162 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
163 handle = Win32.GetProcAddress(library, symbolName);
164 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
165 handle = Linux.dlsym(library, symbolName);
166 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
167 handle = Mac.dlsym(library, symbolName);
168 else if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.VisionOS)
169 handle = Mobile.dlsym(library, symbolName);
171 throw new PlatformNotSupportedException($
"Current platform is unknown, unable to load symbol '{symbolName}' from library {library}.");
180 public static void FreeLibrary(IntPtr library)
182 if (library == IntPtr.Zero)
185 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
186 Win32.FreeLibrary(library);
187 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
188 Linux.dlclose(library);
189 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
190 Mac.dlclose(library);
191 else if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.VisionOS)
192 Mobile.dlclose(library);
194 throw new PlatformNotSupportedException($
"Current platform is unknown, unable to close library '{library}'.");
197 private static class Mac
199 private const string SystemLibrary =
"/usr/lib/libSystem.dylib";
201 private const int RTLD_LAZY = 1;
202 private const int RTLD_NOW = 2;
204 public static IntPtr dlopen(
string path,
bool lazy =
true) =>
205 dlopen(path, lazy ? RTLD_LAZY : RTLD_NOW);
207 [DllImport(SystemLibrary)]
208 public static extern IntPtr dlopen(
string path,
int mode);
210 [DllImport(SystemLibrary)]
211 public static extern IntPtr dlsym(IntPtr handle,
string symbol);
213 [DllImport(SystemLibrary)]
214 public static extern void dlclose(IntPtr handle);
217 private static class Linux
219 private const string SystemLibrary =
"libdl.so";
220 private const string SystemLibrary2 =
"libdl.so.2";
222 private const int RTLD_LAZY = 1;
223 private const int RTLD_NOW = 2;
225 private static bool UseSystemLibrary2 =
true;
227 public static IntPtr dlopen(
string path,
bool lazy =
true)
231 return dlopen2(path, lazy ? RTLD_LAZY : RTLD_NOW);
233 catch (DllNotFoundException)
235 UseSystemLibrary2 =
false;
236 return dlopen1(path, lazy ? RTLD_LAZY : RTLD_NOW);
240 public static IntPtr dlsym(IntPtr handle,
string symbol)
242 return UseSystemLibrary2 ? dlsym2(handle, symbol) : dlsym1(handle, symbol);
245 public static void dlclose(IntPtr handle)
247 if (UseSystemLibrary2)
253 [DllImport(SystemLibrary, EntryPoint =
"dlopen")]
254 private static extern IntPtr dlopen1(
string path,
int mode);
256 [DllImport(SystemLibrary, EntryPoint =
"dlsym")]
257 private static extern IntPtr dlsym1(IntPtr handle,
string symbol);
259 [DllImport(SystemLibrary, EntryPoint =
"dlclose")]
260 private static extern void dlclose1(IntPtr handle);
262 [DllImport(SystemLibrary2, EntryPoint =
"dlopen")]
263 private static extern IntPtr dlopen2(
string path,
int mode);
265 [DllImport(SystemLibrary2, EntryPoint =
"dlsym")]
266 private static extern IntPtr dlsym2(IntPtr handle,
string symbol);
268 [DllImport(SystemLibrary2, EntryPoint =
"dlclose")]
269 private static extern void dlclose2(IntPtr handle);
272 private static class Win32
274 private const string SystemLibrary =
"Kernel32.dll";
276 [DllImport(SystemLibrary, SetLastError =
true, CharSet = CharSet.Ansi)]
277 public static extern IntPtr LoadLibrary(
string lpFileName);
279 [DllImport(SystemLibrary, SetLastError =
true, CharSet = CharSet.Ansi)]
280 public static extern IntPtr GetProcAddress(IntPtr hModule,
string lpProcName);
282 [DllImport(SystemLibrary, SetLastError =
true, CharSet = CharSet.Ansi)]
283 public static extern void FreeLibrary(IntPtr hModule);
286 private static class Mobile
288 public static IntPtr dlopen(
string path) => dlopen(path, 1);
290#if UNITY_ANDROID || UNITY_IOS || UNITY_VISIONOS
291 [DllImport(
"__Internal")]
292 public static extern IntPtr dlopen(
string filename,
int flags);
294 [DllImport(
"__Internal")]
295 public static extern IntPtr dlsym(IntPtr handle,
string symbol);
297 [DllImport(
"__Internal")]
298 public static extern int dlclose(IntPtr handle);
300 public static IntPtr dlopen(
string filename,
int flags)
305 public static IntPtr dlsym(IntPtr handle,
string symbol)
310 public static int dlclose(IntPtr handle)
325 public string architecture {
get;
private set; }
326 IntPtr libraryHandle = IntPtr.Zero;
327 static bool has_avx =
false;
328 static bool has_avx2 =
false;
329 static bool has_avx512 =
false;
330 List<IntPtr> dependencyHandles =
new List<IntPtr>();
332#if (UNITY_ANDROID || UNITY_IOS || UNITY_VISIONOS) && !UNITY_EDITOR
334 public LLMLib(
string arch)
340 public const string LibraryName =
"libundreamai_android";
342 public const string LibraryName =
"__Internal";
345 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"Logging")]
346 public static extern void LoggingStatic(IntPtr stringWrapper);
347 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StopLogging")]
348 public static extern void StopLoggingStatic();
349 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Construct")]
350 public static extern IntPtr LLM_ConstructStatic(
string command);
351 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Delete")]
352 public static extern void LLM_DeleteStatic(IntPtr LLMObject);
353 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_StartServer")]
354 public static extern void LLM_StartServerStatic(IntPtr LLMObject);
355 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_StopServer")]
356 public static extern void LLM_StopServerStatic(IntPtr LLMObject);
357 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Start")]
358 public static extern void LLM_StartStatic(IntPtr LLMObject);
359 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Started")]
360 public static extern bool LLM_StartedStatic(IntPtr LLMObject);
361 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Stop")]
362 public static extern void LLM_StopStatic(IntPtr LLMObject);
363 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_SetTemplate")]
364 public static extern void LLM_SetTemplateStatic(IntPtr LLMObject,
string chatTemplate);
365 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_SetSSL")]
366 public static extern void LLM_SetSSLStatic(IntPtr LLMObject,
string SSLCert,
string SSLKey);
367 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Tokenize")]
368 public static extern void LLM_TokenizeStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
369 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Detokenize")]
370 public static extern void LLM_DetokenizeStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
371 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Embeddings")]
372 public static extern void LLM_EmbeddingsStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
373 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Lora_Weight")]
374 public static extern void LLM_LoraWeightStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
375 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Lora_List")]
376 public static extern void LLM_LoraListStatic(IntPtr LLMObject, IntPtr stringWrapper);
377 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Completion")]
378 public static extern void LLM_CompletionStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
379 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Slot")]
380 public static extern void LLM_SlotStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
381 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Cancel")]
382 public static extern void LLM_CancelStatic(IntPtr LLMObject,
int idSlot);
383 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Status")]
384 public static extern int LLM_StatusStatic(IntPtr LLMObject, IntPtr stringWrapper);
385 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_Construct")]
386 public static extern IntPtr StringWrapper_ConstructStatic();
387 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_Delete")]
388 public static extern void StringWrapper_DeleteStatic(IntPtr instance);
389 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_GetStringSize")]
390 public static extern int StringWrapper_GetStringSizeStatic(IntPtr instance);
391 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_GetString")]
392 public static extern void StringWrapper_GetStringStatic(IntPtr instance, IntPtr buffer,
int bufferSize,
bool clear =
false);
394 public void Logging(IntPtr stringWrapper) { LoggingStatic(stringWrapper); }
395 public void StopLogging() { StopLoggingStatic(); }
396 public IntPtr LLM_Construct(
string command) {
return LLM_ConstructStatic(command); }
397 public void LLM_Delete(IntPtr LLMObject) { LLM_DeleteStatic(LLMObject); }
398 public void LLM_StartServer(IntPtr LLMObject) { LLM_StartServerStatic(LLMObject); }
399 public void LLM_StopServer(IntPtr LLMObject) { LLM_StopServerStatic(LLMObject); }
400 public void LLM_Start(IntPtr LLMObject) { LLM_StartStatic(LLMObject); }
401 public bool LLM_Started(IntPtr LLMObject) {
return LLM_StartedStatic(LLMObject); }
402 public void LLM_Stop(IntPtr LLMObject) { LLM_StopStatic(LLMObject); }
403 public void LLM_SetTemplate(IntPtr LLMObject,
string chatTemplate) { LLM_SetTemplateStatic(LLMObject, chatTemplate); }
404 public void LLM_SetSSL(IntPtr LLMObject,
string SSLCert,
string SSLKey) { LLM_SetSSLStatic(LLMObject, SSLCert, SSLKey); }
405 public void LLM_Tokenize(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_TokenizeStatic(LLMObject, jsonData, stringWrapper); }
406 public void LLM_Detokenize(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_DetokenizeStatic(LLMObject, jsonData, stringWrapper); }
407 public void LLM_Embeddings(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_EmbeddingsStatic(LLMObject, jsonData, stringWrapper); }
408 public void LLM_LoraWeight(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_LoraWeightStatic(LLMObject, jsonData, stringWrapper); }
409 public void LLM_LoraList(IntPtr LLMObject, IntPtr stringWrapper) { LLM_LoraListStatic(LLMObject, stringWrapper); }
410 public void LLM_Completion(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_CompletionStatic(LLMObject, jsonData, stringWrapper); }
411 public void LLM_Slot(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_SlotStatic(LLMObject, jsonData, stringWrapper); }
412 public void LLM_Cancel(IntPtr LLMObject,
int idSlot) { LLM_CancelStatic(LLMObject, idSlot); }
413 public int LLM_Status(IntPtr LLMObject, IntPtr stringWrapper) {
return LLM_StatusStatic(LLMObject, stringWrapper); }
414 public IntPtr StringWrapper_Construct() {
return StringWrapper_ConstructStatic(); }
415 public void StringWrapper_Delete(IntPtr instance) { StringWrapper_DeleteStatic(instance); }
416 public int StringWrapper_GetStringSize(IntPtr instance) {
return StringWrapper_GetStringSizeStatic(instance); }
417 public void StringWrapper_GetString(IntPtr instance, IntPtr buffer,
int bufferSize,
bool clear =
false) { StringWrapper_GetStringStatic(instance, buffer, bufferSize, clear); }
421 static bool has_avx_set =
false;
422 static readonly
object staticLock =
new object();
428 if (has_avx_set)
return;
429 string archCheckerPath = GetArchitectureCheckerPath();
430 if (archCheckerPath !=
null)
432 IntPtr archCheckerHandle = LibraryLoader.LoadLibrary(archCheckerPath);
433 if (archCheckerHandle == IntPtr.Zero)
435 LLMUnitySetup.LogError($
"Failed to load library {archCheckerPath}.");
441 has_avx = LibraryLoader.GetSymbolDelegate<HasArchDelegate>(archCheckerHandle,
"has_avx")();
442 has_avx2 = LibraryLoader.GetSymbolDelegate<HasArchDelegate>(archCheckerHandle,
"has_avx2")();
443 has_avx512 = LibraryLoader.GetSymbolDelegate<HasArchDelegate>(archCheckerHandle,
"has_avx512")();
444 LibraryLoader.FreeLibrary(archCheckerHandle);
448 LLMUnitySetup.LogError($
"{e.GetType()}: {e.Message}");
461 public LLMLib(
string arch)
464 foreach (
string dependency
in GetArchitectureDependencies(arch))
466 LLMUnitySetup.Log($
"Loading {dependency}");
467 dependencyHandles.Add(LibraryLoader.LoadLibrary(dependency));
470 libraryHandle = LibraryLoader.LoadLibrary(GetArchitecturePath(arch));
471 if (libraryHandle == IntPtr.Zero)
473 throw new Exception($
"Failed to load library {arch}.");
476 LLM_Construct = LibraryLoader.GetSymbolDelegate<LLM_ConstructDelegate>(libraryHandle,
"LLM_Construct");
477 LLM_Delete = LibraryLoader.GetSymbolDelegate<LLM_DeleteDelegate>(libraryHandle,
"LLM_Delete");
478 LLM_StartServer = LibraryLoader.GetSymbolDelegate<LLM_StartServerDelegate>(libraryHandle,
"LLM_StartServer");
479 LLM_StopServer = LibraryLoader.GetSymbolDelegate<LLM_StopServerDelegate>(libraryHandle,
"LLM_StopServer");
480 LLM_Start = LibraryLoader.GetSymbolDelegate<LLM_StartDelegate>(libraryHandle,
"LLM_Start");
481 LLM_Started = LibraryLoader.GetSymbolDelegate<LLM_StartedDelegate>(libraryHandle,
"LLM_Started");
482 LLM_Stop = LibraryLoader.GetSymbolDelegate<LLM_StopDelegate>(libraryHandle,
"LLM_Stop");
483 LLM_SetTemplate = LibraryLoader.GetSymbolDelegate<LLM_SetTemplateDelegate>(libraryHandle,
"LLM_SetTemplate");
484 LLM_SetSSL = LibraryLoader.GetSymbolDelegate<LLM_SetSSLDelegate>(libraryHandle,
"LLM_SetSSL");
485 LLM_Tokenize = LibraryLoader.GetSymbolDelegate<LLM_TokenizeDelegate>(libraryHandle,
"LLM_Tokenize");
486 LLM_Detokenize = LibraryLoader.GetSymbolDelegate<LLM_DetokenizeDelegate>(libraryHandle,
"LLM_Detokenize");
487 LLM_Embeddings = LibraryLoader.GetSymbolDelegate<LLM_EmbeddingsDelegate>(libraryHandle,
"LLM_Embeddings");
488 LLM_LoraWeight = LibraryLoader.GetSymbolDelegate<LLM_LoraWeightDelegate>(libraryHandle,
"LLM_Lora_Weight");
489 LLM_LoraList = LibraryLoader.GetSymbolDelegate<LLM_LoraListDelegate>(libraryHandle,
"LLM_Lora_List");
490 LLM_Completion = LibraryLoader.GetSymbolDelegate<LLM_CompletionDelegate>(libraryHandle,
"LLM_Completion");
491 LLM_Slot = LibraryLoader.GetSymbolDelegate<LLM_SlotDelegate>(libraryHandle,
"LLM_Slot");
492 LLM_Cancel = LibraryLoader.GetSymbolDelegate<LLM_CancelDelegate>(libraryHandle,
"LLM_Cancel");
493 LLM_Status = LibraryLoader.GetSymbolDelegate<LLM_StatusDelegate>(libraryHandle,
"LLM_Status");
494 StringWrapper_Construct = LibraryLoader.GetSymbolDelegate<StringWrapper_ConstructDelegate>(libraryHandle,
"StringWrapper_Construct");
495 StringWrapper_Delete = LibraryLoader.GetSymbolDelegate<StringWrapper_DeleteDelegate>(libraryHandle,
"StringWrapper_Delete");
496 StringWrapper_GetStringSize = LibraryLoader.GetSymbolDelegate<StringWrapper_GetStringSizeDelegate>(libraryHandle,
"StringWrapper_GetStringSize");
497 StringWrapper_GetString = LibraryLoader.GetSymbolDelegate<StringWrapper_GetStringDelegate>(libraryHandle,
"StringWrapper_GetString");
498 Logging = LibraryLoader.GetSymbolDelegate<LoggingDelegate>(libraryHandle,
"Logging");
499 StopLogging = LibraryLoader.GetSymbolDelegate<StopLoggingDelegate>(libraryHandle,
"StopLogging");
506 public static string GetArchitectureCheckerPath()
509 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
511 filename = $
"windows-archchecker/archchecker.dll";
513 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
515 filename = $
"linux-archchecker/libarchchecker.so";
521 return Path.Combine(LLMUnitySetup.libraryPath, filename);
529 public static List<string> GetArchitectureDependencies(
string arch)
531 List<string> dependencies =
new List<string>();
532 if (arch ==
"cuda-cu12.2.0-full")
534 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
536 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/cudart64_12.dll"));
537 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/cublasLt64_12.dll"));
538 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/cublas64_12.dll"));
541 else if (arch ==
"vulkan")
543 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
545 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/vulkan-1.dll"));
547 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
549 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"linux-{arch}/libvulkan.so.1"));
560 public static string GetArchitecturePath(
string arch)
563 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
565 filename = $
"windows-{arch}/undreamai_windows-{arch}.dll";
567 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
569 filename = $
"linux-{arch}/libundreamai_linux-{arch}.so";
571 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
573 filename = $
"macos-{arch}/libundreamai_macos-{arch}.dylib";
577 string error =
"Unknown OS";
578 LLMUnitySetup.LogError(error);
579 throw new Exception(error);
581 return Path.Combine(LLMUnitySetup.libraryPath, filename);
584 public delegate
bool HasArchDelegate();
585 public delegate
void LoggingDelegate(IntPtr stringWrapper);
586 public delegate
void StopLoggingDelegate();
587 public delegate IntPtr LLM_ConstructDelegate(
string command);
588 public delegate
void LLM_DeleteDelegate(IntPtr LLMObject);
589 public delegate
void LLM_StartServerDelegate(IntPtr LLMObject);
590 public delegate
void LLM_StopServerDelegate(IntPtr LLMObject);
591 public delegate
void LLM_StartDelegate(IntPtr LLMObject);
592 public delegate
bool LLM_StartedDelegate(IntPtr LLMObject);
593 public delegate
void LLM_StopDelegate(IntPtr LLMObject);
594 public delegate
void LLM_SetTemplateDelegate(IntPtr LLMObject,
string chatTemplate);
595 public delegate
void LLM_SetSSLDelegate(IntPtr LLMObject,
string SSLCert,
string SSLKey);
596 public delegate
void LLM_TokenizeDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
597 public delegate
void LLM_DetokenizeDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
598 public delegate
void LLM_EmbeddingsDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
599 public delegate
void LLM_LoraWeightDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
600 public delegate
void LLM_LoraListDelegate(IntPtr LLMObject, IntPtr stringWrapper);
601 public delegate
void LLM_CompletionDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
602 public delegate
void LLM_SlotDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
603 public delegate
void LLM_CancelDelegate(IntPtr LLMObject,
int idSlot);
604 public delegate
int LLM_StatusDelegate(IntPtr LLMObject, IntPtr stringWrapper);
605 public delegate IntPtr StringWrapper_ConstructDelegate();
606 public delegate
void StringWrapper_DeleteDelegate(IntPtr instance);
607 public delegate
int StringWrapper_GetStringSizeDelegate(IntPtr instance);
608 public delegate
void StringWrapper_GetStringDelegate(IntPtr instance, IntPtr buffer,
int bufferSize,
bool clear =
false);
610 public LoggingDelegate Logging;
611 public StopLoggingDelegate StopLogging;
612 public LLM_ConstructDelegate LLM_Construct;
613 public LLM_DeleteDelegate LLM_Delete;
614 public LLM_StartServerDelegate LLM_StartServer;
615 public LLM_StopServerDelegate LLM_StopServer;
616 public LLM_StartDelegate LLM_Start;
617 public LLM_StartedDelegate LLM_Started;
618 public LLM_StopDelegate LLM_Stop;
619 public LLM_SetTemplateDelegate LLM_SetTemplate;
620 public LLM_SetSSLDelegate LLM_SetSSL;
621 public LLM_TokenizeDelegate LLM_Tokenize;
622 public LLM_DetokenizeDelegate LLM_Detokenize;
623 public LLM_CompletionDelegate LLM_Completion;
624 public LLM_EmbeddingsDelegate LLM_Embeddings;
625 public LLM_LoraWeightDelegate LLM_LoraWeight;
626 public LLM_LoraListDelegate LLM_LoraList;
627 public LLM_SlotDelegate LLM_Slot;
628 public LLM_CancelDelegate LLM_Cancel;
629 public LLM_StatusDelegate LLM_Status;
630 public StringWrapper_ConstructDelegate StringWrapper_Construct;
631 public StringWrapper_DeleteDelegate StringWrapper_Delete;
632 public StringWrapper_GetStringSizeDelegate StringWrapper_GetStringSize;
633 public StringWrapper_GetStringDelegate StringWrapper_GetString;
642 public static List<string> PossibleArchitectures(
bool gpu =
false)
644 List<string> architectures =
new List<string>();
645 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer ||
646 Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
650 if (LLMUnitySetup.FullLlamaLib)
652 architectures.Add(
"cuda-cu12.2.0-full");
656 architectures.Add(
"cuda-cu12.2.0");
658 architectures.Add(
"hip");
659 architectures.Add(
"vulkan");
661 if (has_avx512) architectures.Add(
"avx512");
662 if (has_avx2) architectures.Add(
"avx2");
663 if (has_avx) architectures.Add(
"avx");
664 architectures.Add(
"noavx");
666 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)
668 string arch = RuntimeInformation.ProcessArchitecture.ToString().ToLower();
669 if (arch.Contains(
"arm"))
671 architectures.Add(
"arm64-acc");
672 architectures.Add(
"arm64-no_acc");
676 if (arch !=
"x86" && arch !=
"x64") LLMUnitySetup.LogWarning($
"Unknown architecture of processor {arch}! Falling back to x86_64");
677 architectures.Add(
"x64-acc");
678 architectures.Add(
"x64-no_acc");
681 else if (Application.platform == RuntimePlatform.Android)
683 architectures.Add(
"android");
685 else if (Application.platform == RuntimePlatform.IPhonePlayer)
687 architectures.Add(
"ios");
689 else if (Application.platform == RuntimePlatform.VisionOS)
691 architectures.Add(
"visionos");
695 string error =
"Unknown OS";
696 LLMUnitySetup.LogError(error);
697 throw new Exception(error);
699 return architectures;
707 public string GetStringWrapperResult(IntPtr stringWrapper)
710 int bufferSize = StringWrapper_GetStringSize(stringWrapper);
713 IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
716 StringWrapper_GetString(stringWrapper, buffer, bufferSize);
717 result = Marshal.PtrToStringAnsi(buffer);
721 Marshal.FreeHGlobal(buffer);
730 public void Destroy()
732 if (libraryHandle != IntPtr.Zero) LibraryLoader.FreeLibrary(libraryHandle);
733 foreach (IntPtr dependencyHandle
in dependencyHandles) LibraryLoader.FreeLibrary(dependencyHandle);