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// Dispatch with [ neq1*neq2*neq3, 1, 1 ] thread groups 2#include "flashAttentionCommon.hlsli" 3#include "groupReduce.hlsli" 4#include "miscUtils.hlsli" 5 6inline void roundTempVector ( uint i , const uint len , const uint thread ) 7{ 8const uint iEnd = i + len ; 9for ( i += thread ; i < iEnd ; i += 32 ) 10{ 11float f = temp [ i ]; 12f = roundToFp16 ( f ); 13temp [ i ] = f ; 14} 15} 16 17inline void computeDotProduct ( Buffer < float > buff0 , RWBuffer < float > buff1 , uint s0 , uint s1 , const uint len , const uint thread , inout float acc ) 18{ 19acc = 0 ; 20/* const uint s0End = s0 + len; 21s0 += thread; 22s1 += thread; 23for( ; s0 < s0End; s0 += 32, s1 += 32 ) 24acc = mad( buff0[ s0 ], buff1[ s1 ], acc ); 25 26horizontalSumCompatNew( thread, acc ); */ 27const uint completeVectors = len / 32 ; 28uint i ; 29for ( i = 0 ; i < completeVectors ; i ++ , s0 += 32 , s1 += 32 ) 30acc = mad ( buff0 [ s0 + thread ], buff1 [ s1 + thread ], acc ); 31 32horizontalSumCompatNew ( thread , acc ); 33 34if ( 0 == thread ) 35{ 36const uint rem = len % 32 ; 37if ( 0 != rem ) 38{ 39double f64 = acc ; 40for ( i = 0 ; i < rem ; i ++ ) 41{ 42 precisefloat a = buff0 [ s0 + i ]; 43 precisefloat b = buff1 [ s1 + i ]; 44 precisefloat prod = a * b ; 45f64 += prod ; 46} 47acc = ( float ) f64 ; 48} 49} 50} 51 52[ numthreads ( 32 , 1 , 1 ) ] 53void main ( uint3 group : SV_GroupID , uint thread : SV_GroupIndex ) 54{ 55const uint neq0 = q_elements [ 0 ]; 56const uint neq1 = q_elements [ 1 ]; 57const uint neq2 = q_elements [ 2 ]; 58const uint neq3 = q_elements [ 3 ]; 59 60const uint nek0 = k_elements [ 0 ]; 61const uint nek1 = k_elements [ 1 ]; 62 63const uint nev1 = v_elements [ 1 ]; 64 65const uint ne0 = res_elements [ 0 ]; 66const uint ne1 = res_elements [ 1 ]; 67 68const uint nbk0 = k_strides [ 0 ]; 69const uint nbk1 = k_strides [ 1 ]; 70const uint nbk2 = k_strides [ 2 ]; 71const uint nbk3 = k_strides [ 3 ]; 72 73const uint nbq0 = q_strides [ 0 ]; 74const uint nbq1 = q_strides [ 1 ]; 75const uint nbq2 = q_strides [ 2 ]; 76const uint nbq3 = q_strides [ 3 ]; 77 78const uint nbv0 = v_strides [ 0 ]; 79const uint nbv1 = v_strides [ 1 ]; 80const uint nbv2 = v_strides [ 2 ]; 81const uint nbv3 = v_strides [ 3 ]; 82 83const uint nb0 = res_strides [ 0 ]; 84const uint nb1 = res_strides [ 1 ]; 85const uint nb2 = res_strides [ 2 ]; 86const uint nb3 = res_strides [ 3 ]; 87 88const uint D = neq0 ; 89const uint N = neq1 ; 90const uint P = nek1 - N ; 91// const uint M = P + N; 92const uint M = nek1 ; 93 94const uint ir = group . x ; 95const uint iq3 = ir / ( neq2 * neq1 ); 96const uint iq2 = ( ir - iq3 * neq2 * neq1 ) / neq1 ; 97const uint iq1 = ( ir - iq3 * neq2 * neq1 - iq2 * neq1 ); 98 99const uint tempIndex = ir * tempBufferStride ; 100 101roundTempVector ( tempIndex , nek1 , thread ); 102AllMemoryBarrierWithGroupSync (); 103 104uint rdi = iq1 * nb1 + iq2 * nb2 + iq3 * nb3 ; 105for ( uint ic = 0 ; ic < nev1 ; ic ++ , rdi += nb0 ) 106{ 107// dst indices 108const uint i1 = iq1 ; 109const uint i2 = iq2 ; 110const uint i3 = iq3 ; 111 112const uint s0 = ic * nbv1 + i2 * nbv2 + i3 * nbv3 ; 113float dp ; 114computeDotProduct ( v , temp , s0 , tempIndex , nek1 , thread , dp ); 115if ( 0 == thread ) 116result [ rdi ] = dp ; 117} 118}