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
27dfc34
master
1// Dispatch [ nr, 1, 1 ] thread groups of this shader 2RWBuffer < float > result :register ( u0 ); 3 4cbuffer Constants :register ( b0 ) 5{ 6uint4 elements :packoffset ( c0 ); 7uint4 strides :packoffset ( c1 ); 8uint nr :packoffset ( c2 . x ); 9float inputScale :packoffset ( c2 . y ); 10} 11 12#ifndef THREADS 13static const uint THREADS = 32 ; 14#endif 15 16groupsharedfloat sharedAccumulators [ THREADS ]; 17 18// Compute horizontal maximum of the numbers, and broadcast to all threads of the group. 19void horizontalMaxBroadcast ( const uint thread , inout float ax ) 20{ 21sharedAccumulators [ thread ] = ax ; 22for ( uint i = THREADS / 2 ; i > 0 ; i /= 2 ) 23{ 24GroupMemoryBarrierWithGroupSync (); 25if ( thread < i ) 26{ 27ax = max ( ax , sharedAccumulators [ thread + i ] ); 28sharedAccumulators [ thread ] = ax ; 29} 30} 31GroupMemoryBarrierWithGroupSync (); 32ax = sharedAccumulators [ 0 ]; 33} 34 35// Compute horisontal sum of the numbers. The result is only correct on the thread #0 of the group. 36void horizontalSum ( const uint thread , inout float sum ) 37{ 38sharedAccumulators [ thread ] = sum ; 39for ( uint i = THREADS / 2 ; i > 1 ; i /= 2 ) 40{ 41GroupMemoryBarrierWithGroupSync (); 42if ( thread < i ) 43{ 44sum += sharedAccumulators [ thread + i ]; 45sharedAccumulators [ thread ] = sum ; 46} 47} 48GroupMemoryBarrierWithGroupSync (); 49if ( 0 == thread ) 50sum += sharedAccumulators [ 1 ]; 51} 52 53static const float negativeInfinity = asfloat ( 0xff800000 ); 54 55[ numthreads ( THREADS , 1 , 1 )] 56void main ( uint3 group : SV_GroupID , uint thread : SV_GroupIndex ) 57{ 58const uint p = group . x * strides [ 1 ]; 59const uint nc = elements [ 0 ]; 60const uint pEnd = p + nc ; 61uint i ; 62 63float m = negativeInfinity ; 64for ( i = p + thread ; i < pEnd ; i += THREADS ) 65m = max ( m , result [ i ] ); 66horizontalMaxBroadcast ( thread , m ); 67 68float sum = 0 ; 69for ( i = p + thread ; i < pEnd ; i += THREADS ) 70{ 71float f = result [ i ]; 72 73[ branch ] 74if ( f != negativeInfinity ) 75{ 76f = ( f - m ) * inputScale ; 77// On both Radeon Graphics and nVidia 1080Ti, computing the exponent is slightly faster than loading from the lookup table 78f = exp ( f ); 79sum += f ; 80} 81else 82f = 0 ; 83 84result [ i ] = f ; 85} 86 87horizontalSum ( thread , sum ); 88if ( 0 == thread ) 89sharedAccumulators [ 0 ] = 1.0 / sum ; 90GroupMemoryBarrierWithGroupSync (); 91const float scale = sharedAccumulators [ 0 ]; 92 93// ggml_vec_scale_f32 94for ( i = p + thread ; i < pEnd ; i += THREADS ) 95{ 96float f = result [ i ]; 97f *= scale ; 98result [ i ] = f ; 99} 100}