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

KonstantinMinor, documentation8a1b4ec

master
2.7 KiB61 linesraw
1using System.ComponentModel;
2using System.Runtime.InteropServices;
3
4namespace CompressShaders
5{
6	/// <summary>Lossless data compressor implemented by <c>Cabinet.dll</c> Windows component</summary>
7	/// <remarks>
8	/// <para>That compression API was introduced in Windows 8.0, and is the only reason why the library won’t build for Windows 7 OS.</para>
9	/// <para>Whisper.dll consumes that component in runtime, to decompress these shader binaries</para>
10	/// <para>If you wonder why not gzip — because the OS doesn’t include an API for that, at least not an API usable from C or C++.<br/>
11	/// .NET standard library includes gzip algorithm, but we don't want Whisper.dll to depend on .NET.</para>
12	/// </remarks>
13	static class Cabinet
14	{
15		/// <summary>Compression algorithm</summary>
16		/// <seealso href="https://learn.microsoft.com/en-us/windows/win32/cmpapi/using-the-compression-api#selecting-the-compression-algorithm" />
17		enum eCompressionAlgorithm: uint
18		{
19			MSZIP = 2,
20			XPRESS = 3,
21			XPRESS_HUFF = 4,
22			LZMS = 5,
23		}
24		/// <summary>The value should match <c>constexpr DWORD compressionAlgorithm</c> constant,<br/>in <c>Whisper/D3D/shaders.cpp</c> source file</summary>
25		const eCompressionAlgorithm algo = eCompressionAlgorithm.MSZIP;
26
27		[DllImport( "Cabinet.dll", SetLastError = true )]
28		static extern bool CreateCompressor( eCompressionAlgorithm Algorithm, IntPtr AllocationRoutines, out IntPtr CompressorHandle );
29
30		[DllImport( "Cabinet.dll", SetLastError = true )]
31		static extern bool CloseCompressor( IntPtr CompressorHandle );
32
33		[DllImport( "Cabinet.dll", SetLastError = true )]
34		static extern bool Compress( IntPtr CompressorHandle, [In] byte[] UncompressedData, IntPtr UncompressedDataSize, [Out] byte[] CompressedBuffer, IntPtr CompressedBufferSize, out IntPtr CompressedDataSize );
35
36		/// <summary>Compress an array of bytes into another, smaller array of bytes</summary>
37		/// <remarks>In practice, the compression ratio is about 7.1 for the shader binaries in Release configuration.</remarks>
38		public static byte[] compressBuffer( byte[] src )
39		{
40			if( src.Length <= 0 )
41				throw new ArgumentException( "The source buffer is empty" );
42			IntPtr hCompressor;
43			if( !CreateCompressor( algo, IntPtr.Zero, out hCompressor ) )
44				throw new Win32Exception( "Unable to create the compressor" );
45			try
46			{
47				byte[] dest = new byte[ src.Length * 2 ];
48				IntPtr srcSize = new IntPtr( src.Length );
49				IntPtr destSize = new IntPtr( src.Length * 2 );
50				if( !Compress( hCompressor, src, srcSize, dest, destSize, out destSize ) )
51					throw new Win32Exception( "Compress failed" );
52				Array.Resize( ref dest, (int)destSize );
53				return dest;
54			}
55			finally
56			{
57				CloseCompressor( hCompressor );
58			}
59		}
60	}
61}