You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

NativeLibraryConfig.cs 4.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System;
  2. namespace LLama
  3. {
  4. #if NET6_0_OR_GREATER
  5. /// <summary>
  6. /// A class about configurations when loading native libraries.
  7. /// Note that it could be configured only once before any call to llama model apis.
  8. /// </summary>
  9. public class NativeLibraryConfig
  10. {
  11. private static NativeLibraryConfig? instance;
  12. private static readonly object lockObject = new object();
  13. /// <summary>
  14. /// Whether there's already a config for native library.
  15. /// </summary>
  16. public bool Initialied { get; private set; }
  17. internal Description Desc { get; private set; }
  18. internal static NativeLibraryConfig GetInstance()
  19. {
  20. if (instance is null)
  21. {
  22. lock (lockObject)
  23. {
  24. if (instance is null)
  25. {
  26. instance = new NativeLibraryConfig();
  27. }
  28. }
  29. }
  30. return instance;
  31. }
  32. /// <summary>
  33. /// Load a specified native library as backend for LLamaSharp
  34. /// </summary>
  35. /// <param name="libraryPath"></param>
  36. /// <exception cref="InvalidOperationException"></exception>
  37. public static void WithLibrary(string libraryPath)
  38. {
  39. var config = GetInstance();
  40. if (config.Initialied)
  41. {
  42. throw new InvalidOperationException("NativeLibraryConfig could be configured only once before any call to llama model apis.");
  43. }
  44. config.Desc = new Description(libraryPath);
  45. }
  46. /// <summary>
  47. /// Ass rules to match a suitable library from installed LLamaSharp backend.
  48. /// </summary>
  49. /// <param name="useCuda"></param>
  50. /// <param name="avxLevel"></param>
  51. /// <param name="allowFallback">Whether to allow fall-back when your hardware doesn't support your configuration.</param>
  52. /// <param name="skipCheck">Whether to skip the check when fallback is allowed.
  53. /// It's especially useful when your cuda library is not in the default path. </param>
  54. /// <exception cref="InvalidOperationException"></exception>
  55. public static void WithMatchRule(bool useCuda = true, AvxLevel avxLevel = AvxLevel.Avx2, bool allowFallback = true, bool skipCheck = false)
  56. {
  57. if(allowFallback && skipCheck)
  58. {
  59. throw new ArgumentException("Cannot skip the check when fallback is allowed.");
  60. }
  61. var config = GetInstance();
  62. if (config.Initialied)
  63. {
  64. throw new InvalidOperationException("NativeLibraryConfig could be configured only once before any call to llama model apis.");
  65. }
  66. config.Desc = new Description(UseCuda: useCuda, AvxLevel: avxLevel, AllowFallback: allowFallback, SkipCheck: skipCheck);
  67. }
  68. internal static string AvxLevelToString(AvxLevel level)
  69. {
  70. return level switch
  71. {
  72. AvxLevel.None => string.Empty,
  73. AvxLevel.Avx => "avx",
  74. AvxLevel.Avx2 => "avx2",
  75. #if NET8_0_OR_GREATER
  76. AvxLevel.Avx512 => "avx512"
  77. #endif
  78. _ => throw new ArgumentException($"Cannot recognize Avx level {level}")
  79. };
  80. }
  81. private NativeLibraryConfig()
  82. {
  83. Desc = new Description();
  84. }
  85. /// <summary>
  86. /// Avx support configuration
  87. /// </summary>
  88. public enum AvxLevel
  89. {
  90. /// <inheritdoc />
  91. None = 0,
  92. /// <inheritdoc />
  93. Avx = 1,
  94. /// <inheritdoc />
  95. Avx2 = 2,
  96. #if NET8_0_OR_GREATER
  97. /// <inheritdoc />
  98. Avx512 = 3,
  99. #endif
  100. }
  101. internal record Description(string Path = "", bool UseCuda = true, AvxLevel AvxLevel = AvxLevel.Avx2, bool AllowFallback = true, bool SkipCheck = false);
  102. }
  103. #endif
  104. }