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
2.6 KiB104 linesraw
1#include "stdafx.h"
2#include "shaders.h"
3#include "startup.h"
4#include "device.h"
5#include <compressapi.h>
6#pragma comment( lib, "Cabinet.lib" )
7
8namespace
9{
10#ifdef _DEBUG
11#include "shaderData-Debug.inl"
12#else
13#include "shaderData-Release.inl"
14#endif
15
16	constexpr DWORD compressionAlgorithm = COMPRESS_ALGORITHM_MSZIP;
17
18	class Decompressor
19	{
20		DECOMPRESSOR_HANDLE handle = nullptr;
21
22	public:
23
24		HRESULT create()
25		{
26			if( CreateDecompressor( compressionAlgorithm, nullptr, &handle ) )
27				return S_OK;
28			return HRESULT_FROM_WIN32( GetLastError() );
29		}
30
31		HRESULT decompress( const uint8_t* src, size_t compressedLength, void* dest, size_t origLength ) const
32		{
33			if( Decompress( handle, src, compressedLength, dest, origLength, nullptr ) )
34				return S_OK;
35			return HRESULT_FROM_WIN32( GetLastError() );
36		}
37
38		~Decompressor()
39		{
40			if( nullptr != handle )
41			{
42				CloseDecompressor( handle );
43				handle = nullptr;
44			}
45		}
46	};
47
48	static std::vector<CComPtr<ID3D11ComputeShader>> s_shaders;
49}
50
51HRESULT DirectCompute::createComputeShaders()
52{
53	constexpr size_t countBinaries = s_shaderOffsets.size() - 1;
54	const size_t cbDecompressedLength = s_shaderOffsets[ countBinaries ];
55	constexpr size_t countShaders = s_shaderBlobs32.size();
56
57	std::vector<uint8_t> dxbc;
58	try
59	{
60		s_shaders.resize( countShaders );
61		dxbc.resize( cbDecompressedLength );
62	}
63	catch( const std::bad_alloc& )
64	{
65		return E_OUTOFMEMORY;
66	}
67
68	Decompressor decomp;
69	CHECK( decomp.create() );
70
71	decomp.decompress( s_compressedShaders.data(), s_compressedShaders.size(), dxbc.data(), cbDecompressedLength );
72	ID3D11Device* const dev = device();
73
74	const auto& blobs = gpuInfo.wave64() ? s_shaderBlobs64 : s_shaderBlobs32;
75
76	for( size_t i = 0; i < countShaders; i++ )
77	{
78		const size_t idxBinary = blobs[ i ];
79		const uint32_t offThis = s_shaderOffsets[ idxBinary ];
80		const uint8_t* rsi = &dxbc[ offThis ];
81		const size_t len = s_shaderOffsets[ idxBinary + 1 ] - offThis;
82		const HRESULT hr = dev->CreateComputeShader( rsi, len, nullptr, &s_shaders[ i ] );
83		if( SUCCEEDED( hr ) )
84			continue;
85
86		const uint64_t binaryBit = ( 1ull << idxBinary );
87		if( 0 != ( binaryBit & fp64ShadersBitmap ) )
88			continue;	// This shader uses FP64 math, the support for that is optional. When not supported, CreateComputeShader method is expected to fail.
89		// TODO [low]: ideally, query for the support when creating the device, and don't even try creating these compute shaders
90		return hr;
91	}
92
93	return S_OK;
94}
95
96void DirectCompute::destroyComputeShaders()
97{
98	s_shaders.clear();
99}
100
101void DirectCompute::bindShader( eComputeShader shader )
102{
103	context()->CSSetShader( s_shaders[ (uint16_t)shader ], nullptr, 0 );
104}