yum-archive/TaSTT-Whisper
High-performance GPGPU inference of OpenAI's Whisper automatic speech recognition (ASR) model
git clone https://git.yummers.dev/yum-archive/TaSTT-Whisper
8c4603c
master
1using System . Runtime . CompilerServices ; 2using System . Runtime . ExceptionServices ; 3using System . Runtime . InteropServices ; 4 5namespace Whisper . Internal 6{ 7/// <summary>Utility class to supply logging function pointer to the C++ library,<br/> 8/// and provide custom calling conventions to ComLight runtime to convert error messages printed in C++ into .NET exception messages</summary> 9public static class NativeLogger 10{ 11internal static void startup () { } 12 13static NativeLogger () 14{ 15sink = logSink ; 16sLoggerSetup setup = default ; 17setup . sink = sink ; 18setup . level = eLogLevel . Warning ; 19Library . setupLogger ( ref setup ); 20} 21 22internal static void setup ( eLogLevel lvl , eLoggerFlags flags , pfnLogMessage ? pfn ) 23{ 24logMessage = pfn ; 25 26sLoggerSetup setup = default ; 27setup . sink = sink ; 28setup . level = lvl ; 29setup . flags = flags ; 30Library . setupLogger ( ref setup ); 31} 32 33// This field is here to protect the function pointer from being collected by the GC 34static readonly pfnLoggerSink sink ; 35 36static void logSink ( IntPtr context , eLogLevel lvl , string message ) 37{ 38if ( lvl == eLogLevel . Error ) 39state . setText ( message ); 40logMessage ? . Invoke ( lvl , message ); 41} 42 43sealed class ThreadState 44{ 45string ? errorText = null ; 46ExceptionDispatchInfo ? dispatchInfo = null ; 47 48public void setText ( string text ) => errorText = text ; 49public void capture ( Exception ex ) => dispatchInfo = ExceptionDispatchInfo . Capture ( ex ); 50 51public void clear () 52{ 53errorText = null ; 54dispatchInfo = null ; 55} 56 57public void Deconstruct ( out string ? text , out ExceptionDispatchInfo ? edi ) 58{ 59text = errorText ; 60edi = dispatchInfo ; 61errorText = null ; 62dispatchInfo = null ; 63} 64} 65 66[ ThreadStatic ] 67static ThreadState state = new ThreadState (); 68 69internal static void captureException ( Exception ex ) => 70state . capture ( ex ); 71 72static pfnLogMessage ? logMessage = null ; 73 74/// <summary>Called internally by ComLight runtime</summary> 75[ MethodImpl ( MethodImplOptions . AggressiveInlining )] 76public static void prologue () 77{ 78// https://stackoverflow.com/a/2043505/126995 79if ( null != state ) 80state . clear (); 81else 82createState (); 83} 84 85[ MethodImpl ( MethodImplOptions . NoInlining )] 86static void createState () 87{ 88state = new ThreadState (); 89} 90 91/// <summary>Epilogue implementation for unsuccessful status codes</summary> 92[ MethodImpl ( MethodImplOptions . NoInlining )] 93static void throwException ( int hr ) 94{ 95// Move state from the thread local object into local variables, and clear that object 96( string ? text , ExceptionDispatchInfo ? edi ) = state ; 97 98if ( null != edi && edi . SourceException . HResult == hr ) 99{ 100// The error comes from a callback, and we have original context of that exception. 101// Re-throw the original exception. 102// This uses the original error message, and even correctly deals with the stack trace. 103edi . Throw (); 104} 105 106if ( null != text ) 107{ 108// C++ code has printed an error on the current thread, between prologue and epilogue. 109// Use that text for the exception message. 110Exception ? ex = Marshal . GetExceptionForHR ( hr ); 111throw new ApplicationException ( text , ex ); 112} 113 114// We don’t have any additional info about the exception. 115// Throw an exception from just the HRESULT code. 116Marshal . ThrowExceptionForHR ( hr ); 117} 118 119/// <summary>Called internally by ComLight runtime</summary> 120[ MethodImpl ( MethodImplOptions . AggressiveInlining )] 121public static void throwForHR ( int hr ) 122{ 123if ( hr >= 0 ) 124return ; // SUCCEEDED 125throwException ( hr ); 126} 127 128/// <summary>Called internally by ComLight runtime</summary> 129[ MethodImpl ( MethodImplOptions . AggressiveInlining )] 130public static bool throwAndReturnBool ( int hr ) 131{ 132if ( hr >= 0 ) 133return 0 == hr ; 134throwException ( hr ); 135return false ; 136} 137} 138}