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
1// Matrix * row product, like [ E0, E1, E2, E3 ] * [ E0, 1, E2, E3 ] = [ E1, 1, E2, E3 ] 2// Dispatch [ E1, E2, E3 ] groups of this shader 3Buffer < float > arg0 :register ( t0 ); 4Buffer < float > arg1 :register ( t1 ); 5RWBuffer < float > result :register ( u0 ); 6 7cbuffer Constants :register ( b0 ) 8{ 9uint4 arg0Size :packoffset ( c0 ); 10uint4 arg0Strides :packoffset ( c1 ); 11uint4 arg1Size :packoffset ( c2 ); 12uint4 arg1Strides :packoffset ( c3 ); 13uint4 resultSize :packoffset ( c4 ); 14uint4 resultStrides :packoffset ( c5 ); 15} 16 17inline uint hadd ( uint3 vec ) 18{ 19return vec . x + vec . y + vec . z ; 20} 21inline uint hadd ( uint2 vec ) 22{ 23return vec . x + vec . y ; 24} 25 26// No idea why, but that particular configuration appears to be the fastest one on Ryzen 7 5700G iGPU 27// Not by much, though: when trying a few numbers I saw 1.30 - 1.42 seconds for this compute shader 28static const uint THREADS = 64 ; 29static const uint REDUCTION_BUFFER = 32 ; 30groupsharedfloat sharedAccumulators [ REDUCTION_BUFFER ]; 31 32// Compute horisontal sum of the numbers. The result is only correct on the thread #0 of the group. 33void horizontalSum ( const uint thread , inout float sum ) 34{ 35if ( THREADS > REDUCTION_BUFFER ) 36{ 37for ( uint t = REDUCTION_BUFFER ; t < THREADS ; t += REDUCTION_BUFFER ) 38{ 39// Threads [ t .. t + REDUCTION_BUFFER ] store into the buffer 40if ( thread >= t && thread < t + REDUCTION_BUFFER ) 41sharedAccumulators [ thread - t ] = sum ; 42 43GroupMemoryBarrierWithGroupSync (); 44 45// Threads [ 0 .. REDUCTION_BUFFER ] increment their local sum with the value loaded from the buffer 46if ( thread < REDUCTION_BUFFER ) 47sum += sharedAccumulators [ thread ]; 48} 49} 50 51if ( thread < REDUCTION_BUFFER ) 52sharedAccumulators [ thread ] = sum ; 53 54for ( uint i = REDUCTION_BUFFER / 2 ; i > 1 ; i /= 2 ) 55{ 56GroupMemoryBarrierWithGroupSync (); 57if ( thread < i ) 58{ 59sum += sharedAccumulators [ thread + i ]; 60sharedAccumulators [ thread ] = sum ; 61} 62} 63 64GroupMemoryBarrierWithGroupSync (); 65if ( 0 == thread ) 66sum += sharedAccumulators [ 1 ]; 67} 68 69[ numthreads ( THREADS , 1 , 1 ) ] 70void main ( uint3 group : SV_GroupID , uint thread : SV_GroupIndex ) 71{ 72uint s0 = hadd ( group * arg0Strides . yzw ); 73uint s1 = hadd ( group . yz * arg1Strides . zw ); 74const uint s0End = s0 + arg0Size . x * arg0Strides . x ; 75const uint s0Inc = THREADS * arg0Strides . x ; 76const uint s1Inc = THREADS * arg1Strides . x ; 77 78s0 += thread * arg0Strides . x ; 79s1 += thread * arg1Strides . x ; 80float dp = 0 ; 81for ( ; s0 < s0End ; s0 += s0Inc , s1 += s1Inc ) 82dp = mad ( arg0 [ s0 ], arg1 [ s1 ], dp ); 83 84horizontalSum ( thread , dp ); 85if ( 0 != thread ) 86return ; 87 88const uint rdi = group . x + hadd ( group . yz * resultStrides . zw ); 89result [ rdi ] = dp ; 90}