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

KonstantinSource codes8c4603c

master
5.6 KiB240 linesraw
1#include "stdafx.h"
2#include "Logger.h"
3#include "../API/iContext.cl.h"
4#include <cstdarg>
5#include <atlstr.h>
6
7namespace
8{
9	wchar_t* formatMessage( HRESULT hr )
10	{
11		wchar_t* err;
12		if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
13			NULL,
14			hr,
15			MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
16			(LPTSTR)&err,
17			0,
18			nullptr ) )
19			return err;
20		return nullptr;
21	}
22
23	class Utf
24	{
25		CStringA utf8;
26		CStringW utf16;
27
28		void appendError( HRESULT hr )
29		{
30			const wchar_t* err = formatMessage( hr );
31			if( nullptr != err )
32			{
33				utf16 += err;
34				LocalFree( (HLOCAL)err );
35				utf16.TrimRight();
36			}
37			else
38				utf16.AppendFormat( L"error code %i (0x%08X)", hr, hr );
39		}
40
41	public:
42		const char* print( const char* pszFormat, std::va_list va )
43		{
44			utf8.FormatV( pszFormat, va );
45			return utf8;
46		}
47		const wchar_t* print( const wchar_t* pszFormat, std::va_list va )
48		{
49			utf16.FormatV( pszFormat, va );
50			return utf16;
51		}
52		const wchar_t* upcast( const char* message, int len )
53		{
54			int count = MultiByteToWideChar( CP_UTF8, 0, message, len, nullptr, 0 );
55			if( count == 0 )
56				return nullptr;
57			wchar_t* b = utf16.GetBufferSetLength( len + 1 );
58			count = MultiByteToWideChar( CP_UTF8, 0, message, len, b, len );
59			utf16.ReleaseBuffer( count );
60			return utf16;
61		}
62		int utf8Length() const
63		{
64			return utf8.GetLength();
65		}
66		const wchar_t* printError( HRESULT hr, const char* pszFormat, std::va_list va )
67		{
68			print( pszFormat, va );
69			upcast( utf8, utf8.GetLength() );
70			utf16 += L": ";
71			appendError( hr );
72			return utf16;
73		}
74		const char* downcast()
75		{
76			int count = WideCharToMultiByte( CP_UTF8, 0, utf16, utf16.GetLength(), nullptr, 0, nullptr, nullptr );
77			char* s = utf8.GetBufferSetLength( count + 1 );
78			count = WideCharToMultiByte( CP_UTF8, 0, utf16, utf16.GetLength(), s, count, nullptr, nullptr );
79			utf8.ReleaseBufferSetLength( count );
80			return utf8;
81		}
82	};
83	thread_local Utf ts_utf;
84	using Whisper::eLoggerFlags;
85
86	class Logger : Whisper::sLoggerSetup
87	{
88		inline bool hasFlag( eLoggerFlags bit ) const
89		{
90			return 0 != ( (uint8_t)flags & (uint8_t)bit );
91		}
92
93		bool useStdError() const
94		{
95			return hasFlag( eLoggerFlags::UseStandardError );
96		}
97
98		static void writeStdError( Whisper::eLogLevel lvl, const char* message, int len )
99		{
100			const wchar_t* w = ts_utf.upcast( message, len );
101			if( nullptr != w )
102				fwprintf( stderr, L"%s\n", w );
103		}
104
105	public:
106		Logger()
107		{
108			memset( this, 0, sizeof( Logger ) );
109		}
110
111		bool willLog( Whisper::eLogLevel lvl ) const
112		{
113			if( (uint8_t)lvl > (uint8_t)level )
114				return false;
115			if( useStdError() )
116				return true;
117			return nullptr != sink;
118		}
119
120		void message( Whisper::eLogLevel lvl, const char8_t* pszFormat, std::va_list va ) const
121		{
122			const char* s = ts_utf.print( (const char*)pszFormat, va );
123			auto pfn = sink;
124			if( nullptr != pfn )
125				pfn( context, lvl, s );
126			if( useStdError() )
127				writeStdError( lvl, s, ts_utf.utf8Length() );
128		}
129		void message( Whisper::eLogLevel lvl, const wchar_t* pszFormat, std::va_list va ) const
130		{
131			Utf& u = ts_utf;
132			const wchar_t* w = u.print( pszFormat, va );
133			auto pfn = sink;
134			if( nullptr != pfn )
135				pfn( context, lvl, u.downcast() );
136			if( useStdError() )
137				fwprintf( stderr, L"%s\n", w );
138		}
139		void message( Whisper::eLogLevel lvl, HRESULT hr, const char* pszFormat, std::va_list va ) const
140		{
141			if( hasFlag( eLoggerFlags::SkipFormatMessage ) )
142			{
143				message( lvl, (const char8_t*)pszFormat, va );
144				return;
145			}
146			Utf& u = ts_utf;
147			const wchar_t* w = ts_utf.printError( hr, (const char*)pszFormat, va );
148			auto pfn = sink;
149			if( nullptr != pfn )
150				pfn( context, lvl, u.downcast() );
151			if( useStdError() )
152				fwprintf( stderr, L"%s\n", w );
153		}
154
155		void operator=( const sLoggerSetup& rsi )
156		{
157			sink = rsi.sink;
158			context = rsi.context;
159			level = rsi.level;
160			flags = rsi.flags;
161		}
162	};
163
164	static Logger s_logger;
165}
166
167bool willLogMessage( Whisper::eLogLevel lvl )
168{
169	return s_logger.willLog( lvl );
170}
171
172using Whisper::eLogLevel;
173
174#define LOG_MESSAGE_IMPL( lvl )                \
175	if( !s_logger.willLog( lvl ) )             \
176		return;                                \
177	std::va_list args;                         \
178	va_start( args, pszFormat );               \
179	s_logger.message( lvl, pszFormat, args );  \
180	va_end( args );
181
182void logError( const char8_t* pszFormat, ... )
183{
184	LOG_MESSAGE_IMPL( eLogLevel::Error );
185}
186void logError16( const wchar_t* pszFormat, ... )
187{
188	LOG_MESSAGE_IMPL( eLogLevel::Error );
189}
190void logWarning( const char8_t* pszFormat, ... )
191{
192	LOG_MESSAGE_IMPL( eLogLevel::Warning );
193}
194void logWarning16( const wchar_t* pszFormat, ... )
195{
196	LOG_MESSAGE_IMPL( eLogLevel::Warning );
197}
198void logInfo( const char8_t* pszFormat, ... )
199{
200	LOG_MESSAGE_IMPL( eLogLevel::Info );
201}
202void logInfo16( const wchar_t* pszFormat, ... )
203{
204	LOG_MESSAGE_IMPL( eLogLevel::Info );
205}
206void logDebug( const char8_t* pszFormat, ... )
207{
208	LOG_MESSAGE_IMPL( eLogLevel::Debug );
209}
210void logDebug16( const wchar_t* pszFormat, ... )
211{
212	LOG_MESSAGE_IMPL( eLogLevel::Debug );
213}
214#undef LOG_MESSAGE_IMPL
215
216#define LOG_MESSAGE_IMPL( lvl )                \
217	if( !s_logger.willLog( lvl ) )             \
218		return;                                \
219	std::va_list args;                         \
220	va_start( args, pszFormat );               \
221	s_logger.message( lvl, hr, (const char*)pszFormat, args );  \
222	va_end( args );
223
224void logErrorHr( long hr, const char8_t* pszFormat, ... )
225{
226	LOG_MESSAGE_IMPL( eLogLevel::Error );
227}
228void logWarningHr( long hr, const char8_t* pszFormat, ... )
229{
230	LOG_MESSAGE_IMPL( eLogLevel::Warning );
231}
232
233#undef LOG_MESSAGE_IMPL
234
235// DLL entry point
236HRESULT COMLIGHTCALL Whisper::setupLogger( const sLoggerSetup& setup )
237{
238	s_logger = setup;
239	return S_OK;
240}