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// Ported from ggml_compute_forward_norm_f32 2// Dispatch [ ne01, ne02, ne03 ] thread groups of this shader 3Buffer < float > arg0 :register ( t0 ); 4RWBuffer < float > result :register ( u0 ); 5 6cbuffer Constants :register ( b0 ) 7{ 8uint4 src0_elements :packoffset ( c0 ); 9uint4 src0_strides :packoffset ( c1 ); 10uint4 result_strides :packoffset ( c3 ); 11} 12 13static const float eps = 1e-5f ; // TODO: make this a parameter 14 15// #include "groupReduce.hlsli" 16 17#ifndef THREADS 18static const uint THREADS = 32 ; 19#endif 20static const uint ROW_LENGTH = 1024 ; 21groupsharedfloat rowBuffer [ ROW_LENGTH ]; 22 23static const uint REDUCTION_BUFFER = 32 ; 24groupsharedfloat sharedAccumulators [ REDUCTION_BUFFER ]; 25 26// Compute horisontal sum of the numbers. The result is only correct on the thread #0 of the group. 27void horizontalSum ( const uint thread , inout float sum ) 28{ 29if ( THREADS > REDUCTION_BUFFER ) 30{ 31for ( uint t = REDUCTION_BUFFER ; t < THREADS ; t += REDUCTION_BUFFER ) 32{ 33// Threads [ t .. t + REDUCTION_BUFFER ] store into the buffer 34if ( thread >= t && thread < t + REDUCTION_BUFFER ) 35sharedAccumulators [ thread - t ] = sum ; 36 37GroupMemoryBarrierWithGroupSync (); 38 39// Threads [ 0 .. REDUCTION_BUFFER ] increment their local sum with the value loaded from the buffer 40if ( thread < REDUCTION_BUFFER ) 41sum += sharedAccumulators [ thread ]; 42} 43} 44 45if ( thread < REDUCTION_BUFFER ) 46sharedAccumulators [ thread ] = sum ; 47 48for ( uint i = REDUCTION_BUFFER / 2 ; i > 1 ; i /= 2 ) 49{ 50GroupMemoryBarrierWithGroupSync (); 51if ( thread < i ) 52{ 53sum += sharedAccumulators [ thread + i ]; 54sharedAccumulators [ thread ] = sum ; 55} 56} 57 58GroupMemoryBarrierWithGroupSync (); 59if ( 0 == thread ) 60sum += sharedAccumulators [ 1 ]; 61} 62 63[ numthreads ( THREADS , 1 , 1 ) ] 64void main ( uint3 group : SV_GroupID , uint thread : SV_GroupIndex ) 65{ 66const uint i03 = group . z ; 67const uint i02 = group . y ; 68const uint i01 = group . x ; 69const uint ne00 = ROW_LENGTH ; 70 71// First pass: copy the data to local buffer, and compute sum 72{ 73const uint nb01 = src0_strides [ 1 ]; 74const uint nb02 = src0_strides [ 2 ]; 75const uint nb03 = src0_strides [ 3 ]; 76const uint p = i01 * nb01 + i02 * nb02 + i03 * nb03 ; 77 78float sum = 0 ; 79for ( uint i = thread ; i < ne00 ; i += THREADS ) 80{ 81float f = arg0 [ p + i ]; 82rowBuffer [ i ] = f ; 83sum += f ; 84} 85horizontalSum ( thread , sum ); 86if ( 0 == thread ) 87sharedAccumulators [ 0 ] = sum / ( float )( int ) ne00 ; 88GroupMemoryBarrierWithGroupSync (); 89} 90 91// Second pass: offset and compute sum of squares 92{ 93const float mean = sharedAccumulators [ 0 ]; 94float sum2 = 0 ; 95for ( uint i = thread ; i < ne00 ; i += THREADS ) 96{ 97float v = rowBuffer [ i ]; 98v -= mean ; 99rowBuffer [ i ] = v ; 100sum2 = mad ( v , v , sum2 ); 101} 102horizontalSum ( thread , sum2 ); 103if ( 0 == thread ) 104sharedAccumulators [ 0 ] = 1.0 / sqrt ( sum2 / ( float )( int ) ne00 + eps ); 105GroupMemoryBarrierWithGroupSync (); 106} 107 108// Final pass: apply the scale, and copy from group shared buffer to the destination 109{ 110const float scale = sharedAccumulators [ 0 ]; 111 112const uint nb1 = result_strides [ 1 ]; 113const uint nb2 = result_strides [ 2 ]; 114const uint nb3 = result_strides [ 3 ]; 115const uint y = i01 * nb1 + i02 * nb2 + i03 * nb3 ; 116 117for ( uint i = thread ; i < ne00 ; i += THREADS ) 118{ 119float v = rowBuffer [ i ]; 120v *= scale ; 121result [ y + i ] = v ; 122} 123} 124}