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.8 KiB97 linesraw
1#include "stdafx.h"
2#include "TensorEx.h"
3#include "../D3D/createBuffer.h"
4#include "../source/ggml.h"
5#include "../D3D/MappedResource.h"
6using namespace DirectCompute;
7
8HRESULT TensorEx::create( const ggml_tensor& ggml, eBufferUse usage, bool uploadData )
9{
10	TensorGpuViews::clear();
11	buffer = nullptr;
12	stagingBuffer = nullptr;
13
14	CHECK( TensorShape::create( ggml ) );
15	const ggml_type dataType = ggml.type;
16	const uint32_t cbElement = (uint32_t)ggml_type_size( dataType );
17
18	const size_t totalBytes = ggml_nbytes( &ggml );
19	if( totalBytes > INT_MAX )
20		return DISP_E_OVERFLOW;
21	const uint32_t countElements = (uint32_t)( totalBytes / cbElement );
22
23	{
24		const void* const rsi = uploadData ? ggml.data : nullptr;
25		ID3D11Buffer** ppStagingBuffer = ( usage == eBufferUse::ReadWriteDownload ) ? &stagingBuffer : nullptr;
26		CHECK( createBuffer( usage, totalBytes, &buffer, rsi, ppStagingBuffer ) );
27	}
28
29	DXGI_FORMAT format;
30	switch( dataType )
31	{
32	case GGML_TYPE_F16:
33		format = DXGI_FORMAT_R16_FLOAT;
34		break;
35	case GGML_TYPE_F32:
36		format = DXGI_FORMAT_R32_FLOAT;
37		break;
38	default:
39		return E_NOTIMPL;
40	}
41
42	const bool makeUav = usage == eBufferUse::ReadWrite || usage == eBufferUse::ReadWriteDownload;
43	return TensorGpuViews::create( buffer, format, totalBytes / cbElement, makeUav );
44}
45
46HRESULT TensorEx::create( eDataType type, eBufferUse usage, const std::array<uint32_t, 4>& sizeElements )
47{
48	TensorGpuViews::clear();
49	buffer = nullptr;
50	stagingBuffer = nullptr;
51	std::initializer_list<uint32_t> il( sizeElements.data(), sizeElements.data() + 4 );
52
53	ID3D11Buffer** ppStaging = ( usage == eBufferUse::ReadWriteDownload ) ? &stagingBuffer : nullptr;
54	return Tensor::create( type, il, usage, buffer, nullptr, ppStaging );
55}
56
57HRESULT TensorEx::getViewSize( uint32_t& cbElement, uint32_t& countElements ) const
58{
59	ID3D11ShaderResourceView* const srv = *this;
60	if( nullptr == srv )
61		return OLE_E_BLANK;
62
63	D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
64	srv->GetDesc( &viewDesc );
65
66	cbElement = dxgiSizeof( viewDesc.Format );
67
68	assert( viewDesc.ViewDimension == D3D_SRV_DIMENSION_BUFFER );
69	assert( viewDesc.Buffer.FirstElement == 0 );
70	countElements = viewDesc.Buffer.NumElements;
71
72	return S_OK;
73}
74
75HRESULT TensorEx::download( void* rdi, size_t cb ) const
76{
77	if( nullptr == stagingBuffer )
78		return HRESULT_FROM_WIN32( ERROR_GPIO_OPERATION_DENIED );	// The requested operation is not supported for the specified handle.
79
80	ID3D11DeviceContext* const ctx = context();
81	ctx->CopyResource( stagingBuffer, buffer );
82
83	MappedResource mapped;
84	CHECK( mapped.map( stagingBuffer, true ) );
85	memcpy( rdi, mapped.data(), cb );
86
87	return S_OK;
88}
89
90HRESULT TensorEx::download( void* rdi ) const
91{
92	uint32_t cbElement, numElements;
93	CHECK( getViewSize( cbElement, numElements ) );
94
95	size_t cb = (size_t)cbElement * numElements;
96	return download( rdi, cb );
97}