char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
bfdc32183
char/aliceai-t5-moe
1#include "common.cuh" 2#include "cp-async.cuh" 3#include "mma.cuh" 4#include "fattn-common.cuh" 5#include "fattn-swizzle.cuh" 6 7using namespace ggml_cuda_mma; 8 9// Config options for the MMA kernel. 10// Should not affect results, only speed/register pressure/shared memory use. 11struct fattn_mma_config { 12 int nthreads; // Number of threads per CUDA block. 13 int occupancy; // Targeted occupancy for the MMA kernel. 14 int nbatch_fa; // Number of KV rows per softmax rescaling of KQ rowsums and VKQ accumulators. 15 int nbatch_K2; // Number of K half2 values in direction of DKQ to load in parallel. 16 int nbatch_V2; // Number of V half2 values in direction of DV to load in parallel. 17 int nbatch_combine; // Number of VKQ half2 values in direction of DV to combine in parallel. 18 int nstages_target; // Number of pipeline stages to use ideally, 1 == always load data synchronously, 2 == preload data if there is hardware support. 19 bool Q_in_reg; // Whether the Q values should be kept permanently in registers. 20 21 constexpr __host__ __device__ fattn_mma_config( 22 int nthreads, int occupancy, int nbatch_fa, int nbatch_K2, int nbatch_V2, int nbatch_combine, int nstages_target, bool Q_in_reg) : 23 nthreads(nthreads), occupancy(occupancy), nbatch_fa(nbatch_fa), nbatch_K2(nbatch_K2), nbatch_V2(nbatch_V2), nbatch_combine(nbatch_combine), 24 nstages_target(nstages_target), Q_in_reg(Q_in_reg) {} 25}; 26 27#define GGML_CUDA_FATTN_MMA_CONFIG_CASE(DKQ_, DV_, ncols_, nthreads_, occupancy_, nbatch_fa_, nbatch_K2_, nbatch_V2_, nbatch_combine_, nstages_target_, Q_in_reg_) \ 28 if (DKQ == (DKQ_) && DV == (DV_) && ncols == (ncols_)) { \ 29 static_assert((nthreads_) % 32 == 0 && (nthreads_) <= 512, "bad nthreads"); \ 30 static_assert( (occupancy_) <= 8, "bad occupancy"); \ 31 static_assert((nbatch_fa_) % 32 == 0 && (nbatch_fa_) <= 256, "bad nbatch_fa"); \ 32 static_assert((nbatch_K2_) % 4 == 0 && (nbatch_K2_) <= 512, "bad nbatch_K2"); \ 33 static_assert((nbatch_V2_) % 4 == 0 && (nbatch_V2_) <= 256, "bad nbatch_V2"); \ 34 static_assert((nbatch_combine_) % 4 == 0 && (nbatch_combine_) <= 128, "bad nbatch_combine"); \ 35 static_assert((nstages_target_) >= 1 && (nstages_target_) <= 2, "bad nstages_target"); \ 36 return fattn_mma_config{(nthreads_), (occupancy_), (nbatch_fa_), (nbatch_K2_), (nbatch_V2_), (nbatch_combine_), (nstages_target_), (Q_in_reg_)}; \ 37 } \ 38 39static constexpr __host__ __device__ fattn_mma_config ggml_cuda_fattn_mma_get_config_ampere(const int DKQ, const int DV, const int ncols) { 40 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 8, 128, 2, 128, 32, 32, 32, 2, true); 41 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 16, 128, 2, 64, 32, 32, 32, 2, true); 42 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 32, 128, 2, 64, 32, 32, 32, 2, true); 43 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 64, 128, 2, 64, 32, 32, 32, 2, true); 44 45 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 8, 128, 2, 128, 40, 40, 40, 2, true); 46 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 16, 128, 2, 64, 40, 40, 40, 2, true); 47 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 32, 128, 2, 64, 40, 40, 40, 2, true); 48 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 64, 128, 2, 64, 40, 40, 40, 2, true); 49 50 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 8, 128, 2, 128, 48, 48, 48, 2, true); 51 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 16, 128, 2, 64, 48, 48, 48, 2, true); 52 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 32, 128, 2, 64, 48, 48, 48, 2, true); 53 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 64, 128, 2, 64, 48, 48, 48, 2, true); 54 55 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 8, 128, 2, 128, 56, 56, 56, 2, true); 56 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 16, 128, 2, 64, 56, 56, 56, 2, true); 57 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 32, 128, 2, 64, 56, 56, 56, 2, true); 58 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 64, 128, 2, 64, 56, 56, 56, 2, true); 59 60 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 8, 128, 2, 128, 64, 64, 64, 2, true); 61 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 16, 128, 2, 64, 64, 64, 64, 2, true); 62 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 32, 128, 2, 64, 64, 64, 64, 2, true); 63 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 64, 128, 2, 64, 64, 64, 64, 2, true); 64 65 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 8, 64, 4, 64, 96, 64, 64, 2, true); 66 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 16, 64, 4, 32, 96, 64, 64, 2, true); 67 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 32, 128, 2, 32, 96, 64, 64, 2, true); 68 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 64, 128, 2, 32, 96, 64, 64, 2, true); 69 70 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 8, 128, 2, 64, 128, 128, 128, 2, true); 71 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 16, 64, 4, 32, 128, 128, 128, 2, true); 72 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 32, 128, 2, 32, 128, 128, 128, 2, true); 73 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 64, 128, 2, 32, 128, 128, 128, 2, true); 74 75 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 32, 128, 2, 32, 128, 128, 128, 1, false); 76 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 64, 256, 1, 32, 128, 128, 128, 1, false); 77 78 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 8, 64, 4, 32, 256, 256, 128, 1, false); 79 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 16, 64, 4, 32, 256, 256, 128, 1, false); 80 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 32, 128, 2, 32, 128, 128, 128, 1, false); 81 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 64, 256, 1, 32, 128, 128, 128, 1, false); 82 83 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 8, 64, 4, 32, 288, 256, 128, 1, false); 84 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 16, 64, 4, 32, 288, 256, 128, 1, false); 85 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 32, 128, 2, 32, 160, 128, 128, 1, false); 86 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 64, 256, 1, 32, 160, 128, 128, 1, false); 87 88 return fattn_mma_config(32, 1, 0, 0, 0, 0, 0, false); 89} 90 91static constexpr __host__ __device__ fattn_mma_config ggml_cuda_fattn_mma_get_config_turing(const int DKQ, const int DV, const int ncols) { 92 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 8, 128, 2, 64, 128, 128, 128, 2, true); 93 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 16, 128, 2, 64, 128, 128, 128, 2, true); 94 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 32, 128, 2, 64, 128, 128, 64, 2, true); 95 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 64, 128, 2, 64, 128, 128, 64, 2, true); 96 97 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 32, 128, 2, 32, 128, 128, 128, 1, false); 98 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 64, 256, 1, 32, 128, 128, 128, 1, false); 99 100 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 8, 64, 4, 32, 96, 64, 128, 1, false); 101 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 16, 64, 4, 32, 96, 64, 128, 1, false); 102 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 32, 128, 2, 32, 128, 128, 128, 1, false); 103 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 64, 256, 1, 32, 128, 128, 128, 1, false); 104 105 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 8, 64, 4, 32, 96, 64, 128, 1, false); 106 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 16, 64, 4, 32, 96, 64, 128, 1, false); 107 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 32, 128, 2, 32, 160, 128, 128, 1, false); 108 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 64, 256, 1, 32, 160, 128, 128, 1, false); 109 110 return ggml_cuda_fattn_mma_get_config_ampere(DKQ, DV, ncols); 111} 112 113static constexpr __host__ __device__ fattn_mma_config ggml_cuda_fattn_mma_get_config_volta(const int DKQ, const int DV, const int ncols) { 114 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 8, 64, 4, 32, 256, 256, 64, 1, false); 115 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 16, 64, 4, 32, 256, 256, 64, 1, false); 116 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 32, 128, 2, 32, 128, 128, 64, 1, false); 117 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 64, 256, 1, 32, 128, 128, 64, 1, false); 118 119 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 8, 64, 4, 32, 288, 256, 64, 1, false); 120 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 16, 64, 4, 32, 288, 256, 64, 1, false); 121 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 32, 128, 2, 32, 160, 128, 64, 1, false); 122 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 64, 256, 1, 32, 160, 128, 64, 1, false); 123 124 // TODO tune specifically for Volta 125 return ggml_cuda_fattn_mma_get_config_ampere(DKQ, DV, ncols); 126} 127 128static constexpr __host__ __device__ fattn_mma_config ggml_cuda_fattn_mma_get_config_rdna(const int DKQ, const int DV, const int ncols) { 129 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 8, 128, 2, 64, 32, 32, 32, 1, true); 130 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 16, 128, 2, 64, 32, 32, 32, 1, true); 131 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 32, 128, 2, 64, 32, 32, 32, 1, true); 132 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 64, 128, 2, 64, 32, 32, 32, 1, true); 133 134 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 8, 64, 2, 32, 40, 40, 40, 1, true); 135 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 16, 64, 2, 32, 40, 40, 40, 1, true); 136 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 32, 128, 2, 64, 40, 40, 40, 1, true); 137 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 64, 128, 2, 64, 40, 40, 40, 1, true); 138 139 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 8, 64, 2, 32, 48, 48, 48, 1, true); 140 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 16, 64, 2, 32, 48, 48, 48, 1, true); 141 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 32, 128, 2, 64, 48, 48, 48, 1, true); 142 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 64, 128, 2, 64, 48, 48, 48, 1, true); 143 144 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 8, 64, 2, 32, 56, 56, 56, 1, true); 145 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 16, 64, 2, 32, 56, 56, 56, 1, true); 146 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 32, 128, 2, 64, 56, 56, 56, 1, true); 147 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 64, 128, 2, 64, 56, 56, 56, 1, true); 148 149 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 8, 64, 2, 32, 64, 64, 64, 1, true); 150 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 16, 64, 2, 32, 64, 64, 64, 1, true); 151 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 32, 128, 2, 64, 64, 64, 64, 1, true); 152 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 64, 128, 2, 64, 64, 64, 64, 1, true); 153 154 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 8, 64, 2, 32, 96, 64, 64, 1, true); 155 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 16, 64, 2, 32, 96, 64, 64, 1, true); 156 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 32, 128, 2, 64, 96, 64, 64, 1, true); 157 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 64, 128, 2, 64, 96, 64, 64, 1, true); 158 159 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 8, 64, 2, 32, 128, 128, 128, 1, true); 160 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 16, 64, 2, 32, 128, 128, 128, 1, true); 161 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 32, 256, 2, 64, 128, 128, 64, 1, true); 162 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 64, 256, 2, 64, 128, 128, 64, 1, true); 163 164 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 32, 128, 2, 32, 160, 128, 128, 1, true); 165 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 64, 128, 2, 32, 160, 128, 128, 1, true); 166 167 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 8, 128, 3, 64, 96, 64, 128, 1, true); 168 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 16, 128, 3, 64, 96, 64, 128, 1, true); 169 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 32, 128, 2, 32, 128, 128, 128, 1, true); 170 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 64, 128, 2, 32, 128, 128, 128, 1, true); 171 172 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 8, 128, 3, 64, 96, 64, 128, 1, true); 173 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 16, 128, 3, 64, 96, 64, 128, 1, true); 174 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 32, 128, 2, 32, 160, 128, 128, 1, true); 175 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 64, 128, 2, 32, 160, 128, 128, 1, true); 176 177 return fattn_mma_config(32, 1, 0, 0, 0, 0, 0, false); 178} 179 180static constexpr __host__ __device__ fattn_mma_config ggml_cuda_fattn_mma_get_config_cdna(const int DKQ, const int DV, const int ncols) { 181 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 8, 128, 1, 64, 32, 32, 32, 1, true); 182 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 16, 256, 2, 64, 32, 32, 32, 1, true); 183 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 32, 256, 2, 64, 32, 32, 32, 1, true); 184 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 64, 64, 64, 256, 3, 64, 32, 32, 32, 1, true); 185 186 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 8, 256, 2, 64, 40, 40, 40, 1, true); 187 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 16, 256, 2, 64, 40, 40, 40, 1, true); 188 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 32, 256, 2, 64, 40, 40, 40, 1, true); 189 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 80, 80, 64, 256, 2, 64, 40, 40, 40, 1, true); 190 191 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 8, 256, 2, 64, 48, 48, 48, 1, true); 192 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 16, 256, 2, 64, 48, 48, 48, 1, true); 193 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 32, 256, 2, 64, 48, 48, 48, 1, true); 194 GGML_CUDA_FATTN_MMA_CONFIG_CASE( 96, 96, 64, 256, 2, 64, 48, 48, 48, 1, true); 195 196 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 8, 256, 2, 64, 56, 56, 56, 1, true); 197 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 16, 256, 2, 64, 56, 56, 56, 1, true); 198 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 32, 256, 2, 64, 56, 56, 56, 1, true); 199 GGML_CUDA_FATTN_MMA_CONFIG_CASE(112, 112, 64, 256, 2, 64, 56, 56, 56, 1, true); 200 201 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 8, 256, 2, 64, 64, 64, 64, 1, true); 202 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 16, 256, 2, 64, 64, 64, 64, 1, true); 203 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 32, 256, 2, 64, 64, 64, 64, 1, true); 204 GGML_CUDA_FATTN_MMA_CONFIG_CASE(128, 128, 64, 256, 2, 64, 64, 64, 64, 1, true); 205 206 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 8, 256, 1, 64, 64, 64, 64, 1, true); 207 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 16, 256, 1, 64, 64, 64, 64, 1, true); 208 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 32, 256, 1, 64, 64, 64, 64, 1, true); 209 GGML_CUDA_FATTN_MMA_CONFIG_CASE(192, 128, 64, 512, 1, 64, 64, 64, 64, 1, true); 210 211 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 8, 256, 1, 64, 128, 128, 128, 1, true); 212 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 16, 256, 1, 64, 128, 128, 128, 1, true); 213 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 32, 256, 1, 64, 128, 128, 128, 1, true); 214 GGML_CUDA_FATTN_MMA_CONFIG_CASE(256, 256, 64, 512, 1, 64, 128, 128, 64, 1, true); 215 216 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 32, 256, 1, 64, 160, 128, 128, 1, true); 217 GGML_CUDA_FATTN_MMA_CONFIG_CASE(320, 256, 64, 256, 1, 64, 160, 128, 128, 1, true); 218 219 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 8, 256, 1, 64, 128, 128, 128, 1, true); 220 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 16, 256, 1, 64, 128, 128, 128, 1, true); 221 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 32, 256, 1, 64, 128, 128, 128, 1, true); 222 GGML_CUDA_FATTN_MMA_CONFIG_CASE(512, 512, 64, 256, 1, 64, 128, 128, 128, 1, true); 223 224 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 8, 256, 1, 64, 128, 128, 128, 1, true); 225 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 16, 256, 1, 64, 128, 128, 128, 1, true); 226 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 32, 256, 1, 64, 160, 128, 128, 1, true); 227 GGML_CUDA_FATTN_MMA_CONFIG_CASE(576, 512, 64, 256, 1, 64, 160, 128, 128, 1, true); 228 229 return fattn_mma_config(32, 1, 0, 0, 0, 0, 0, false); 230} 231 232static __host__ fattn_mma_config ggml_cuda_fattn_mma_get_config(const int DKQ, const int DV, const int ncols, const int cc) { 233 if (ampere_mma_available(cc)) { 234 return ggml_cuda_fattn_mma_get_config_ampere(DKQ, DV, ncols); 235 } 236 if (turing_mma_available(cc)) { 237 return ggml_cuda_fattn_mma_get_config_turing(DKQ, DV, ncols); 238 } 239 if (amd_mfma_available(cc)) { 240 return ggml_cuda_fattn_mma_get_config_cdna(DKQ, DV, ncols); 241 } 242 if (amd_wmma_available(cc)) { 243 return ggml_cuda_fattn_mma_get_config_rdna(DKQ, DV, ncols); 244 } 245 GGML_ASSERT(volta_mma_available(cc)); 246 return ggml_cuda_fattn_mma_get_config_volta(DKQ, DV, ncols); 247} 248 249static constexpr __device__ fattn_mma_config ggml_cuda_fattn_mma_get_config(const int DKQ, const int DV, const int ncols) { 250#if defined(AMPERE_MMA_AVAILABLE) 251 return ggml_cuda_fattn_mma_get_config_ampere(DKQ, DV, ncols); 252#elif defined(TURING_MMA_AVAILABLE) 253 return ggml_cuda_fattn_mma_get_config_turing(DKQ, DV, ncols); 254#elif defined(AMD_MFMA_AVAILABLE) 255 return ggml_cuda_fattn_mma_get_config_cdna(DKQ, DV, ncols); 256#elif defined(VOLTA_MMA_AVAILABLE) 257 return ggml_cuda_fattn_mma_get_config_volta(DKQ, DV, ncols); 258#elif defined(AMD_WMMA_AVAILABLE) 259 return ggml_cuda_fattn_mma_get_config_rdna(DKQ, DV, ncols); 260#else 261 GGML_UNUSED_VARS(DKQ, DV, ncols); 262 return fattn_mma_config(32, 1, 0, 0, 0, 0, 0, false); 263#endif // defined(AMPERE_MMA_AVAILABLE) 264} 265 266static __host__ int ggml_cuda_fattn_mma_get_nthreads(const int DKQ, const int DV, const int ncols, const int cc) { 267 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).nthreads; 268} 269 270static constexpr __device__ int ggml_cuda_fattn_mma_get_nthreads(const int DKQ, const int DV, const int ncols) { 271 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).nthreads; 272} 273 274static __host__ int ggml_cuda_fattn_mma_get_occupancy(const int DKQ, const int DV, const int ncols, const int cc) { 275 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).occupancy; 276} 277 278static constexpr __device__ int ggml_cuda_fattn_mma_get_occupancy(const int DKQ, const int DV, const int ncols) { 279 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).occupancy; 280} 281 282static __host__ int ggml_cuda_fattn_mma_get_nbatch_fa(const int DKQ, const int DV, const int ncols, const int cc) { 283 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).nbatch_fa; 284} 285 286static constexpr __device__ int ggml_cuda_fattn_mma_get_nbatch_fa(const int DKQ, const int DV, const int ncols) { 287 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).nbatch_fa; 288} 289 290static __host__ int ggml_cuda_fattn_mma_get_nbatch_K2(const int DKQ, const int DV, const int ncols, const int cc) { 291 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).nbatch_K2; 292} 293 294static constexpr __device__ int ggml_cuda_fattn_mma_get_nbatch_K2(const int DKQ, const int DV, const int ncols) { 295 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).nbatch_K2; 296} 297 298static __host__ int ggml_cuda_fattn_mma_get_nbatch_V2(const int DKQ, const int DV, const int ncols, const int cc) { 299 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).nbatch_V2; 300} 301 302static constexpr __device__ int ggml_cuda_fattn_mma_get_nbatch_V2(const int DKQ, const int DV, const int ncols) { 303 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).nbatch_V2; 304} 305 306static __host__ int ggml_cuda_fattn_mma_get_nbatch_combine(const int DKQ, const int DV, const int ncols, const int cc) { 307 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).nbatch_combine; 308} 309 310static constexpr __device__ int ggml_cuda_fattn_mma_get_nbatch_combine(const int DKQ, const int DV, const int ncols) { 311 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).nbatch_combine; 312} 313 314static __host__ int ggml_cuda_fattn_mma_get_nstages_target(const int DKQ, const int DV, const int ncols, const int cc) { 315 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).nstages_target; 316} 317 318static constexpr __device__ int ggml_cuda_fattn_mma_get_nstages_target(const int DKQ, const int DV, const int ncols) { 319 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).nstages_target; 320} 321 322static __host__ bool ggml_cuda_fattn_mma_get_Q_in_reg(const int DKQ, const int DV, const int ncols, const int cc) { 323 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols, cc).Q_in_reg; 324} 325 326static constexpr __device__ bool ggml_cuda_fattn_mma_get_Q_in_reg(const int DKQ, const int DV, const int ncols) { 327 return ggml_cuda_fattn_mma_get_config(DKQ, DV, ncols).Q_in_reg; 328} 329 330static constexpr __device__ int get_cols_per_thread() { 331#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 332 return 1; // AMD has a single column per thread. 333#else 334 return 2; // This is specifically KQ columns, Volta only has a single VKQ column. 335#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 336} 337 338static __host__ int get_cols_per_warp(const int cc) { 339 if (turing_mma_available(cc) || amd_wmma_available(cc) || amd_mfma_available(cc)) { 340 return 16; 341 } else { 342 // Volta 343 return 32; 344 } 345} 346 347// ------------------------------------------------------------------------------------------------------------------ 348 349static __host__ int ggml_cuda_fattn_mma_get_nstages(const int DKQ, const int DV, const int ncols1, const int ncols2, const int cc) { 350 return cp_async_available(cc) && ncols2 >= 2 ? ggml_cuda_fattn_mma_get_nstages_target(DKQ, DV, ncols1*ncols2, cc) : 0; 351} 352 353static constexpr __device__ int ggml_cuda_fattn_mma_get_nstages( 354 const int DKQ, const int DV, const int ncols1, const int ncols2, const bool use_sparse) { 355#ifdef CP_ASYNC_AVAILABLE 356 const int nstages_target = ncols2 >= 2 ? ggml_cuda_fattn_mma_get_nstages_target(DKQ, DV, ncols1*ncols2) : 0; 357 // sparse gather is not implemented for multi-stage loading 358 return use_sparse && nstages_target > 1 ? 1 : nstages_target; 359#else 360 GGML_UNUSED_VARS(DKQ, DV, ncols1, ncols2, use_sparse); 361 return 0; 362#endif // CP_ASYNC_AVAILABLE 363} 364 365// ------------------------------------------------------------------------------------------------------------------ 366 367template<int stride_tile, bool swz, int nwarps, int nbatch_fa, bool use_cp_async, bool oob_check, bool use_sparse> 368static __device__ __forceinline__ void flash_attn_ext_f16_load_tile( 369 const half2 * const __restrict__ KV, half2 * const __restrict__ tile_KV, const int D2, const int stride_KV, 370 const int k_VKQ_0, const int i_sup, const int32_t * const __restrict__ indices) { 371 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 372 // K/V data is loaded with decreasing granularity for D for better memory bandwidth. 373 // The minimum granularity is 16 bytes. 374 constexpr int h2_per_chunk = 16/sizeof(half2); 375 const int chunks_per_row = D2 / h2_per_chunk; 376 if constexpr (use_cp_async) { 377 static_assert(warp_size == 32, "bad warp_size"); 378 static_assert(!oob_check || use_sparse, "OOB check not compatible with cp_async"); 379 constexpr int preload = 64; 380 381 const unsigned int tile_KV_32 = ggml_cuda_cvta_generic_to_shared(tile_KV); 382 383 auto load = [&] __device__ (auto n) { 384 const int stride_k = warp_size >> n; 385 const int k0_start = stride_k == warp_size ? 0 : chunks_per_row - chunks_per_row % (2*stride_k); 386 const int k0_stop = chunks_per_row - chunks_per_row % (1*stride_k); 387 const int stride_i = warp_size / stride_k; 388 389 if (k0_start == k0_stop) { 390 return; 391 } 392 393#pragma unroll 394 for (int i0 = 0; i0 < nbatch_fa; i0 += nwarps*stride_i) { 395 const int i = i0 + threadIdx.y*stride_i + (stride_k == warp_size ? 0 : threadIdx.x / stride_k); 396 397 if (i0 + nwarps*stride_i > nbatch_fa && i >= nbatch_fa) { 398 break; 399 } 400 401 int64_t i_KV; 402 if constexpr (use_sparse) { 403 // padded slots gather row 0, the -inf mask removes their contribution 404 const int32_t index = i < i_sup ? indices[k_VKQ_0 + i] : 0; 405 i_KV = index >= 0 ? index : 0; 406 } else { 407 i_KV = k_VKQ_0 + i; 408 } 409 410#pragma unroll 411 for (int k0 = k0_start; k0 < k0_stop; k0 += stride_k) { 412 const int k = k0 + (stride_k == warp_size ? threadIdx.x : threadIdx.x % stride_k); 413 414 if constexpr (swz) { 415 const int smem_offs_b = ggml_cuda_fattn_smem_swizzle::bytes_rc<stride_tile>(i, k*h2_per_chunk); 416 cp_async_cg_16<preload>(tile_KV_32 + smem_offs_b, KV + i_KV*stride_KV + k*h2_per_chunk); 417 } else { 418 cp_async_cg_16<preload>(tile_KV_32 + i*(stride_tile*sizeof(half2)) + k*16, KV + i_KV*stride_KV + k*h2_per_chunk); 419 } 420 } 421 } 422 }; 423 // 1: max 32*16=512 bytes, 256 half 424 // 2: max 16*16=256 bytes, 128 half 425 // 3: max 8*16=128 bytes, 64 half 426 // 4: max 4*16= 64 bytes, 32 half 427 // 5: max 2*16= 32 bytes, 16 half 428 // 6: max 1*16= 16 bytes, 8 half 429 ggml_cuda_unroll<6>{}(load); 430 } else { 431 const half2 zero[4] = {{0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}}; 432 auto load = [&] __device__ (const int n) { 433 const int stride_k = 32 >> n; 434 const int k0_start = stride_k == 32 ? 0 : chunks_per_row - chunks_per_row % (2*stride_k); 435 const int k0_stop = chunks_per_row - chunks_per_row % (1*stride_k); 436 const int stride_i = warp_size / stride_k; 437 438 if (k0_start == k0_stop) { 439 return; 440 } 441 442#pragma unroll 443 for (int i0 = 0; i0 < nbatch_fa; i0 += nwarps*stride_i) { 444 const int i = i0 + threadIdx.y*stride_i + (stride_k == warp_size ? 0 : threadIdx.x / stride_k); 445 446 if (i0 + nwarps*stride_i > nbatch_fa && i >= nbatch_fa) { 447 break; 448 } 449 450#pragma unroll 451 for (int k0 = k0_start; k0 < k0_stop; k0 += stride_k) { 452 const int k = k0 + (stride_k == warp_size ? threadIdx.x : threadIdx.x % stride_k); 453 454 const half2 * src; 455 if constexpr (use_sparse) { 456 const int32_t index = i < i_sup ? indices[k_VKQ_0 + i] : -1; 457 src = index >= 0 ? KV + int64_t(index)*stride_KV + k*h2_per_chunk : zero; 458 } else { 459 src = !oob_check || i < i_sup ? KV + int64_t(k_VKQ_0 + i)*stride_KV + k*h2_per_chunk : zero; 460 } 461 if constexpr (swz) { 462 ggml_cuda_memcpy_1<16>((char *) tile_KV + ggml_cuda_fattn_smem_swizzle::bytes_rc<stride_tile>(i, k*h2_per_chunk), src); 463 } else { 464 ggml_cuda_memcpy_1<16>(tile_KV + i*stride_tile + k*4, src); 465 } 466 } 467 } 468 }; 469 // 1: max 32*16=512 bytes, 256 half 470 // 2: max 16*16=256 bytes, 128 half 471 // 3: max 8*16=128 bytes, 64 half 472 // 4: max 4*16= 64 bytes, 32 half 473 // 5: max 2*16= 32 bytes, 16 half 474 // 6: max 1*16= 16 bytes, 8 half 475 ggml_cuda_unroll<6>{}(load); 476 } 477} 478 479template<int ncols1, int nwarps, int nbatch_fa, bool use_cp_async, bool oob_check, bool use_sparse> 480static __device__ __forceinline__ void flash_attn_ext_f16_load_mask( 481 const half * const __restrict__ mask_h, half * const __restrict__ tile_mask, 482 const int stride_mask, const int k_VKQ_0, const int i_sup, const int j0, const uint3 ne01, 483 const int32_t * const __restrict__ indices) { 484 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 485 if constexpr (use_cp_async) { 486 static_assert(nbatch_fa <= 8*warp_size && nbatch_fa % 8 == 0, "bad nbatch_fa"); 487 static_assert(!oob_check, "OOB check incompatible with cp_async"); 488 static_assert(!use_sparse, "sparse gather incompatible with cp_async"); 489 constexpr int preload = nbatch_fa >= 32 ? nbatch_fa * sizeof(half) : 64; 490 constexpr int cols_per_warp = 8*warp_size/nbatch_fa; 491 constexpr int stride_j = nwarps * cols_per_warp; 492 493 const unsigned int tile_mask_32 = ggml_cuda_cvta_generic_to_shared(tile_mask); 494 495#pragma unroll 496 for (int j1 = 0; j1 < ncols1; j1 += stride_j) { 497 const int j_sram = j1 + threadIdx.y*cols_per_warp + threadIdx.x / (warp_size/cols_per_warp); 498 const int j_vram = fastmodulo(j0 + j_sram, ne01); 499 500 if (j1 + stride_j > ncols1 && j_sram >= ncols1) { 501 break; 502 } 503 504 const int i = 8 * (threadIdx.x % (nbatch_fa/8)); 505 506 cp_async_cg_16<preload>(tile_mask_32 + j_sram*(nbatch_fa*sizeof(half) + 16) + i*sizeof(half), mask_h + int64_t(j_vram)*stride_mask + k_VKQ_0 + i); 507 } 508 } else if constexpr (oob_check || use_sparse) { 509#pragma unroll 510 for (int j1 = 0; j1 < ncols1; j1 += nwarps) { 511 const int j_sram = j1 + threadIdx.y; 512 const int j_vram = fastmodulo(j0 + j_sram, ne01); 513 514 if (j1 + nwarps > ncols1 && j_sram >= ncols1) { 515 break; 516 } 517 518#pragma unroll 519 for (int i0 = 0; i0 < nbatch_fa; i0 += warp_size) { 520 const int i = i0 + threadIdx.x; 521 522 if constexpr (use_sparse) { 523 const int32_t index = i < i_sup ? indices[k_VKQ_0 + i] : -1; 524 tile_mask[j_sram*(nbatch_fa + 8) + i] = index >= 0 ? mask_h[int64_t(j_vram)*stride_mask + index] : half(-INFINITY); 525 } else { 526 tile_mask[j_sram*(nbatch_fa + 8) + i] = i < i_sup ? mask_h[int64_t(j_vram)*stride_mask + k_VKQ_0 + i] : half(0.0f); 527 } 528 } 529 } 530 } else if constexpr (nbatch_fa < 2*warp_size) { 531 constexpr int cols_per_warp = 2*warp_size/nbatch_fa; 532 constexpr int stride_j = nwarps * cols_per_warp; 533#pragma unroll 534 for (int j1 = 0; j1 < ncols1; j1 += stride_j) { 535 const int j_sram = j1 + threadIdx.y*cols_per_warp + threadIdx.x / (warp_size/cols_per_warp); 536 const int j_vram = fastmodulo(j0 + j_sram, ne01); 537 538 if (j1 + stride_j > ncols1 && j_sram >= ncols1) { 539 break; 540 } 541 542 const int i = threadIdx.x % (warp_size/cols_per_warp); 543 544 ggml_cuda_memcpy_1<sizeof(half2)>(tile_mask + j_sram*(nbatch_fa + 8) + 2*i, mask_h + int64_t(j_vram)*stride_mask + k_VKQ_0 + 2*i); 545 } 546 } else { 547#pragma unroll 548 for (int j1 = 0; j1 < ncols1; j1 += nwarps) { 549 const int j_sram = j1 + threadIdx.y; 550 const int j_vram = fastmodulo(j0 + j_sram, ne01); 551 552 if (j1 + nwarps > ncols1 && j_sram >= ncols1) { 553 break; 554 } 555 556#pragma unroll 557 for (int i0 = 0; i0 < nbatch_fa; i0 += 2*warp_size) { 558 const int i = i0 + 2*threadIdx.x; 559 560 ggml_cuda_memcpy_1<sizeof(half2)>(tile_mask + j_sram*(nbatch_fa + 8) + i, mask_h + int64_t(j_vram)*stride_mask + k_VKQ_0 + i); 561 } 562 } 563 } 564} 565 566template<int DKQ, int DV, int ncols1, int ncols2, int nwarps, 567 bool use_logit_softcap, bool V_is_K_view, bool use_sparse, bool needs_fixup, bool is_fixup, bool last_iter, bool oob_check, 568 typename T_A_KQ, typename T_B_KQ, typename T_C_KQ, typename T_A_VKQ, typename T_B_VKQ, typename T_C_VKQ> 569static __device__ __forceinline__ void flash_attn_ext_f16_iter( 570 const float2 * const __restrict__ Q_f2, 571 const half2 * const __restrict__ K_h2, 572 const half2 * const __restrict__ V_h2, 573 const half * const __restrict__ mask_h, 574 const int32_t * const __restrict__ indices, 575 float2 * const __restrict__ dstk, 576 float2 * const __restrict__ dstk_fixup, 577 const float scale, 578 const float slope, 579 const float logit_softcap, 580 const uint3 ne01, 581 const int ne02, 582 const int stride_K, 583 const int stride_V, 584 const int stride_mask, 585 half2 * const __restrict__ tile_Q, 586 half2 * const __restrict__ tile_K, 587 half2 * const __restrict__ tile_V, 588 half * const __restrict__ tile_mask, 589 T_B_KQ * const __restrict__ Q_B, 590 T_C_VKQ * const __restrict__ VKQ_C, 591 float * const __restrict__ KQ_max, 592 float * const __restrict__ KQ_rowsum, 593 const int jt, 594 const int kb0, 595 const int k_VKQ_sup) { 596#if defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 597 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 598 constexpr int ncols = ncols1 * ncols2; 599 constexpr int cols_per_warp = T_B_KQ::I; 600 constexpr int cols_per_thread = get_cols_per_thread(); 601 constexpr int np = cols_per_warp > ncols ? nwarps : nwarps * cols_per_warp/ncols; // Number of parallel CUDA warps per Q column. 602 constexpr int nbatch_fa = ggml_cuda_fattn_mma_get_nbatch_fa(DKQ, DV, ncols); 603 constexpr int nbatch_K2 = ggml_cuda_fattn_mma_get_nbatch_K2(DKQ, DV, ncols); 604 constexpr int nbatch_V2 = ggml_cuda_fattn_mma_get_nbatch_V2(DKQ, DV, ncols); 605 constexpr bool Q_in_reg = ggml_cuda_fattn_mma_get_Q_in_reg (DKQ, DV, ncols); 606 constexpr int nstages = ggml_cuda_fattn_mma_get_nstages (DKQ, DV, ncols1, ncols2, use_sparse); 607 608 // swizzle the tile stride for K and V based on the batch size. 609 constexpr int stride_tile_K = ggml_cuda_fattn_smem_swizzle::tile_stride(nbatch_K2); 610 constexpr int stride_tile_V = V_is_K_view ? stride_tile_K : ggml_cuda_fattn_smem_swizzle::tile_stride(nbatch_V2); 611 constexpr bool swz_K = ggml_cuda_fattn_smem_swizzle::enabled(nbatch_K2); 612 constexpr bool swz_V = V_is_K_view ? swz_K : ggml_cuda_fattn_smem_swizzle::enabled(nbatch_V2); 613 614 const int k_VKQ_0 = kb0 * nbatch_fa; 615#if defined(TURING_MMA_AVAILABLE) 616 T_C_KQ KQ_C[nbatch_fa/(np*(cols_per_warp == 8 ? T_C_KQ::I : T_C_KQ::J))]; 617#elif defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 618 T_C_KQ KQ_C[nbatch_fa/(np*T_C_KQ::J)]; 619#else // Volta 620 T_C_KQ KQ_C[nbatch_fa/(np*T_C_KQ::J)]; 621#endif // defined(TURING_MMA_AVAILABLE) 622 623 if constexpr (nstages > 1) { 624 static_assert(!oob_check, "OOB check incompatible with multi-stage pipeline"); 625 static_assert(!V_is_K_view, "K data reuse not implemented multi-stage loading"); 626 static_assert(nbatch_K2 == DKQ/2, "batching not implemented for multi stage loading"); 627 constexpr bool use_cp_async = true; 628 cp_async_wait_all(); 629 __syncthreads(); 630 flash_attn_ext_f16_load_tile<stride_tile_V, swz_V, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 631 (V_h2, tile_V, nbatch_V2, stride_V, k_VKQ_0, k_VKQ_sup, nullptr); 632 } else { 633 // the sparse mask values are gathered per element, always load them synchronously 634 constexpr bool use_cp_async = nstages == 1 && !use_sparse; 635 if (ncols2 > 1 || mask_h) { 636 flash_attn_ext_f16_load_mask<ncols1, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 637 (mask_h, tile_mask, stride_mask, k_VKQ_0, k_VKQ_sup, jt*ncols1, ne01, indices); 638 } 639 } 640 641 // For MLA K and V have the same data. 642 // Therefore, iterate over K in reverse and later re-use the data if possible. 643#pragma unroll 644 for (int k0_start = (DKQ/2-1) - (DKQ/2-1) % nbatch_K2; k0_start >= 0; k0_start -= nbatch_K2) { 645 const int k0_stop = k0_start + nbatch_K2 < DKQ/2 ? k0_start + nbatch_K2 : DKQ/2; 646 647 if constexpr (nstages <= 1) { 648 const int k0_diff = k0_stop - k0_start; 649 constexpr bool use_cp_async = nstages == 1; 650 flash_attn_ext_f16_load_tile<stride_tile_K, swz_K, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 651 (K_h2 + k0_start, tile_K, k0_diff, stride_K, k_VKQ_0, k_VKQ_sup, indices); 652 if (use_cp_async) { 653 cp_async_wait_all(); 654 } 655 __syncthreads(); 656 } 657 658 // Calculate tile of KQ: 659 if constexpr (Q_in_reg) { 660#pragma unroll 661 for (int i_KQ_00 = 0; i_KQ_00 < nbatch_fa; i_KQ_00 += np*T_A_KQ::I) { 662 const int i_KQ_0 = i_KQ_00 + (threadIdx.y % np)*T_A_KQ::I; 663#pragma unroll 664 for (int k_KQ_0 = k0_start; k_KQ_0 < k0_stop; k_KQ_0 += T_A_KQ::J) { 665 T_A_KQ K_A; 666 ggml_cuda_fattn_smem_swizzle::load_ldmatrix<stride_tile_K, swz_K>(K_A, tile_K, i_KQ_0, k_KQ_0 - k0_start); 667 if constexpr (cols_per_warp == 8) { 668 mma(KQ_C[i_KQ_00/(np*T_A_KQ::I)], K_A, Q_B[k_KQ_0/T_A_KQ::J]); 669 } else { 670 // Wide version of KQ_C is column-major 671#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 672 // AMD matrix C is column-major. 673 mma(KQ_C[i_KQ_00/(np*T_A_KQ::I)], K_A, Q_B[k_KQ_0/T_A_KQ::J]); 674#else 675 // swap A and B for CUDA. 676 mma(KQ_C[i_KQ_00/(np*T_A_KQ::I)], Q_B[k_KQ_0/T_A_KQ::J], K_A); 677#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 678 } 679 } 680 } 681 } else { 682 constexpr int stride_tile_Q = DKQ/2 + 4; 683#pragma unroll 684 for (int k_KQ_0 = k0_start; k_KQ_0 < k0_stop; k_KQ_0 += T_A_KQ::J) { 685 load_ldmatrix(Q_B[0], tile_Q + (threadIdx.y / np)*(T_B_KQ::I*stride_tile_Q) + k_KQ_0, stride_tile_Q); 686 687#pragma unroll 688 for (int i_KQ_00 = 0; i_KQ_00 < nbatch_fa; i_KQ_00 += np*T_A_KQ::I) { 689 const int i_KQ_0 = i_KQ_00 + (threadIdx.y % np)*T_A_KQ::I; 690 691 T_A_KQ K_A; 692 ggml_cuda_fattn_smem_swizzle::load_ldmatrix<stride_tile_K, swz_K>(K_A, tile_K, i_KQ_0, k_KQ_0 - k0_start); 693 694 if constexpr (cols_per_warp == 8) { 695 mma(KQ_C[i_KQ_00/(np*T_A_KQ::I)], K_A, Q_B[0]); 696 } else { 697 // Wide version of KQ_C is column-major 698#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 699 // AMD matrix C is column-major. 700 mma(KQ_C[i_KQ_00/(np*T_A_KQ::I)], K_A, Q_B[0]); 701#else 702 // swap A and B for CUDA. 703 mma(KQ_C[i_KQ_00/(np*T_A_KQ::I)], Q_B[0], K_A); 704#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 705 } 706 } 707 } 708 } 709 710 if constexpr (nstages <= 1) { 711 __syncthreads(); // Only needed if tile_K == tile_V. 712 } 713 } 714 715 if (use_logit_softcap) { 716 constexpr int stride = cols_per_warp == 8 ? np*T_C_KQ::I : np*T_C_KQ::J; 717 static_assert(nbatch_fa % stride == 0, "bad loop size"); 718#pragma unroll 719 for (int i = 0; i < nbatch_fa/stride; ++i) { 720#pragma unroll 721 for (int l = 0; l < T_C_KQ::ne; ++l) { 722 KQ_C[i].x[l] = logit_softcap*tanhf(KQ_C[i].x[l]); 723 } 724 } 725 } 726 727 float KQ_max_new[cols_per_thread]; 728#pragma unroll 729 for (int col = 0; col < cols_per_thread; ++col) { 730 KQ_max_new[col] = KQ_max[col]; 731 } 732 float KQ_rowsum_add[cols_per_thread] = {0.0f}; 733 734 if constexpr (cols_per_warp == 8) { 735 if (ncols2 > 1 || mask_h) { 736#pragma unroll 737 for (int i00 = 0; i00 < nbatch_fa; i00 += np*T_C_KQ::I) { 738 const int i0 = i00 + (threadIdx.y % np)*T_C_KQ::I; 739#pragma unroll 740 for (int l = 0; l < T_C_KQ::ne; ++l) { 741 const int i = i0 + T_C_KQ::get_i(l); 742 const int j = ((threadIdx.y / np)*T_C_KQ::J + T_C_KQ::get_j(l)) / ncols2; 743 744 KQ_C[i00/(np*T_C_KQ::I)].x[l] += slope * __half2float(tile_mask[j*(nbatch_fa + 8) + i]); 745 } 746 } 747 } 748 749 // Calculate softmax for each KQ column using the current max. value. 750 // The divisor is stored in KQ_rowsum and will be applied at the end. 751 static_assert(nbatch_fa % (np*T_C_KQ::I) == 0, "bad loop size"); 752#pragma unroll 753 for (int k0 = 0; k0 < nbatch_fa; k0 += np*T_C_KQ::I) { 754#pragma unroll 755 for (int l = 0; l < T_C_KQ::ne; ++l) { 756 if (!oob_check || k0 + (threadIdx.y % np)*T_C_KQ::I + T_C_KQ::get_i(l) < k_VKQ_sup) { 757#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 758 constexpr int KQ_idx = 0; 759#else 760 // Turing + Volta: 761 const int KQ_idx = l % 2; 762#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 763 KQ_max_new[KQ_idx] = fmaxf(KQ_max_new[KQ_idx], KQ_C[k0/(np*T_C_KQ::I)].x[l] + FATTN_KQ_MAX_OFFSET); 764 } 765 } 766 } 767 768 // Values per KQ column are spread across 8 threads: 769#pragma unroll 770 for (int col = 0; col < cols_per_thread; ++col) { 771#pragma unroll 772 for (int offset = 16; offset >= 4; offset >>= 1) { 773 KQ_max_new[col] = fmaxf(KQ_max_new[col], __shfl_xor_sync(0xFFFFFFFF, KQ_max_new[col], offset, warp_size)); 774 } 775 } 776 777 static_assert(nbatch_fa % (np*T_C_KQ::I) == 0, "bad loop size"); 778#pragma unroll 779 for (int k0 = 0; k0 < nbatch_fa; k0 += np*T_C_KQ::I) { 780#pragma unroll 781 for (int l = 0; l < T_C_KQ::ne; ++l) { 782 if (!oob_check || k0 + (threadIdx.y % np)*T_C_KQ::I + T_C_KQ::get_i(l) < k_VKQ_sup) { 783#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 784 constexpr int KQ_idx = 0; 785#else 786 // Turing + Volta: 787 const int KQ_idx = l % 2; 788#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 789 KQ_C[k0/(np*T_C_KQ::I)].x[l] = expf(KQ_C[k0/(np*T_C_KQ::I)].x[l] - KQ_max_new[KQ_idx]); 790 KQ_rowsum_add[KQ_idx] += KQ_C[k0/(np*T_C_KQ::I)].x[l]; 791 } else { 792 KQ_C[k0/(np*T_C_KQ::I)].x[l] = 0.0f; 793 } 794 } 795 } 796 } else { // not Turing mma or T_B_KQ::I > 8 797 if (ncols2 > 1 || mask_h) { 798#pragma unroll 799 for (int i00 = 0; i00 < nbatch_fa; i00 += np*T_C_KQ::J) { 800 const int i0 = i00 + (threadIdx.y % np)*T_C_KQ::J; 801 802 // The mask is stored as 16 bit half values, loading them as 32 bit half2 values is preferred in terms of speed. 803 // However, this is not possible for RDNA3 where 2 consecutive l indices are not consecutive in the mask memory layout. 804#ifdef RDNA3 805#pragma unroll 806 for (int l = 0; l < T_C_KQ::ne; ++l) { 807 const int i = i0 + T_C_KQ::get_j(l); 808 const int j = ((threadIdx.y / np)*cols_per_warp + T_C_KQ::get_i(l)) / ncols2; 809 810 KQ_C[i00/(np*T_C_KQ::J)].x[l] += __half2float(tile_mask[j*(nbatch_fa + 8) + i]); 811 } 812#else 813#pragma unroll 814 for (int l0 = 0; l0 < T_C_KQ::ne; l0 += 2) { 815 const int i = (i0 + T_C_KQ::get_j(l0)) / 2; 816 const int j = ((threadIdx.y / np)*cols_per_warp + T_C_KQ::get_i(l0)) / ncols2; 817 818 const float2 tmp = __half22float2(((const half2 *)tile_mask)[j*(nbatch_fa/2 + 4) + i]); 819 KQ_C[i00/(np*T_C_KQ::J)].x[l0 + 0] += slope*tmp.x; 820 KQ_C[i00/(np*T_C_KQ::J)].x[l0 + 1] += slope*tmp.y; 821 } 822#endif // RDNA3 823 } 824 } 825 826 // Calculate softmax for each KQ column using the current max. value. 827 // The divisor is stored in KQ_rowsum and will be applied at the end. 828 static_assert(nbatch_fa % (np*T_C_KQ::J) == 0, "bad loop size"); 829#pragma unroll 830 for (int k0 = 0; k0 < nbatch_fa; k0 += np*T_C_KQ::J) { 831#pragma unroll 832 for (int l = 0; l < T_C_KQ::ne; ++l) { 833 if (!oob_check || k0 + (threadIdx.y % np)*T_C_KQ::J + T_C_KQ::get_j(l) < k_VKQ_sup) { 834#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 835 constexpr int KQ_idx = 0; 836#else 837 // Turing + Volta: 838 const int KQ_idx = (l/2) % 2; 839#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 840 KQ_max_new[KQ_idx] = fmaxf(KQ_max_new[KQ_idx], KQ_C[(k0/(np*T_C_KQ::J))].x[l] + FATTN_KQ_MAX_OFFSET); 841 } 842 } 843 } 844 845#pragma unroll 846 for (int col = 0; col < cols_per_thread; ++col) { 847#if defined(TURING_MMA_AVAILABLE) 848 // Values per KQ column are spread across 4 threads: 849 constexpr int offset_first = 2; 850 constexpr int offset_last = 1; 851#elif defined(AMD_MFMA_AVAILABLE) 852 // MFMA: 4 threads per Q column (threadIdx.x % 16 == col, spaced by 16). 853 constexpr int offset_first = 32; 854 constexpr int offset_last = 16; 855#elif defined(AMD_WMMA_AVAILABLE) 856 // Values per KQ column are spread across 2 threads: 857 constexpr int offset_first = 16; 858 constexpr int offset_last = 16; 859#else // Volta 860 // Values per KQ column are spread across 2 threads: 861 constexpr int offset_first = 2; 862 constexpr int offset_last = 2; 863#endif // defined(TURING_MMA_AVAILABLE) 864#pragma unroll 865 for (int offset = offset_first; offset >= offset_last; offset >>= 1) { 866 KQ_max_new[col] = fmaxf(KQ_max_new[col], __shfl_xor_sync(0xFFFFFFFF, KQ_max_new[col], offset, warp_size)); 867 } 868 } 869 870 static_assert(nbatch_fa % (np*T_C_KQ::J) == 0, "bad loop size"); 871#pragma unroll 872 for (int k0 = 0; k0 < nbatch_fa; k0 += np*T_C_KQ::J) { 873#pragma unroll 874 for (int l = 0; l < T_C_KQ::ne; ++l) { 875 if (!oob_check || k0 + (threadIdx.y % np)*T_C_KQ::J + T_C_KQ::get_j(l) < k_VKQ_sup) { 876#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 877 constexpr int KQ_idx = 0; 878#else 879 // Turing + Volta: 880 const int KQ_idx = (l/2) % 2; 881#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 882 KQ_C[(k0/(np*T_C_KQ::J))].x[l] = expf(KQ_C[(k0/(np*T_C_KQ::J))].x[l] - KQ_max_new[KQ_idx]); 883 KQ_rowsum_add[KQ_idx] += KQ_C[(k0/(np*T_C_KQ::J))].x[l]; 884 } else { 885 KQ_C[(k0/(np*T_C_KQ::J))].x[l] = 0.0f; 886 } 887 } 888 } 889 } 890 891 { 892 float KQ_max_scale[cols_per_thread]; 893#pragma unroll 894 for (int col = 0; col < cols_per_thread; ++col) { 895 const float KQ_max_diff = KQ_max[col] - KQ_max_new[col]; 896 KQ_max_scale[col] = expf(KQ_max_diff); 897 KQ_max[col] = KQ_max_new[col]; 898 899 *((uint32_t *) &KQ_max_scale[col]) *= KQ_max_diff >= SOFTMAX_FTZ_THRESHOLD; 900 901 // Scale previous KQ_rowsum to account for a potential increase in KQ_max: 902 KQ_rowsum[col] = KQ_max_scale[col]*KQ_rowsum[col] + KQ_rowsum_add[col]; 903 } 904 905#if defined(TURING_MMA_AVAILABLE) 906 if constexpr (cols_per_warp == 8) { 907 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[0], KQ_max_scale[cols_per_thread - 1]); 908#pragma unroll 909 for (int i = 0; i < DV/T_C_VKQ::I; ++i) { 910#pragma unroll 911 for (int l = 0; l < T_C_VKQ::ne; ++l) { 912 VKQ_C[i].x[l] *= KQ_max_scale_h2; 913 } 914 } 915 } else { 916#pragma unroll 917 for (int col = 0; col < cols_per_thread; ++col) { 918 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[col], KQ_max_scale[col]); 919#pragma unroll 920 for (int i = 0; i < (DV/2)/T_C_VKQ::J; ++i) { 921#pragma unroll 922 for (int l0 = 0; l0 < T_C_VKQ::ne; l0 += 2) { 923 VKQ_C[i].x[l0 + col] *= KQ_max_scale_h2; 924 } 925 } 926 } 927 } 928#elif defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 929 if constexpr (std::is_same_v<decltype(T_C_VKQ::x), half2[T_C_VKQ::ne]>) { 930 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[0], KQ_max_scale[0]); 931#pragma unroll 932 for (int i = 0; i < (DV/2)/T_C_VKQ::J; ++i) { 933#pragma unroll 934 for (int l = 0; l < T_C_VKQ::ne; ++l) { 935 VKQ_C[i].x[l] *= KQ_max_scale_h2; 936 } 937 } 938 } else { 939 static_assert(std::is_same_v<decltype(T_C_VKQ::x), float[T_C_VKQ::ne]>, "bad VKQ type"); 940#pragma unroll 941 for (int i = 0; i < DV/T_C_VKQ::J; ++i) { 942#pragma unroll 943 for (int l = 0; l < T_C_VKQ::ne; ++l) { 944 VKQ_C[i].x[l] *= KQ_max_scale[0]; 945 } 946 } 947 } 948#else // Volta 949 const half2 KQ_max_scale_h2 = make_half2( 950 KQ_max_scale[(threadIdx.x / 2) % 2], KQ_max_scale[(threadIdx.x / 2) % 2]); 951#pragma unroll 952 for (int i = 0; i < (DV/2)/T_C_VKQ::J; ++i) { 953#pragma unroll 954 for (int l = 0; l < T_C_VKQ::ne; ++l) { 955 VKQ_C[i].x[l] *= KQ_max_scale_h2; 956 } 957 } 958#endif // defined(TURING_MMA_AVAILABLE) 959 } 960 961 // Convert KQ C tiles into B tiles for VKQ calculation: 962 T_B_VKQ B[nbatch_fa/(np*2*T_B_VKQ::J)]; 963 static_assert(nbatch_fa % (np*2*T_B_VKQ::J) == 0, "bad loop size"); 964 if constexpr (cols_per_warp == 8) { 965#pragma unroll 966 for (int k = 0; k < nbatch_fa/(np*2*T_B_VKQ::J); ++k) { 967 B[k] = get_transposed(get_half2(KQ_C[k])); 968 } 969 } else { 970 for (int k = 0; k < nbatch_fa/(np*2*T_B_VKQ::J); ++k) { 971 B[k] = get_half2(KQ_C[k]); 972 } 973 } 974 975 if constexpr (nstages > 1) { 976 static_assert(!use_sparse, "sparse gather not implemented for multi-stage loading"); 977 static_assert(!V_is_K_view, "K data reuse not implemented multi-stage loading"); 978 // Preload K tile for next iteration: 979 constexpr bool use_cp_async = true; 980 cp_async_wait_all(); 981 __syncthreads(); 982 if (!last_iter) { 983 if (ncols2 > 1 || mask_h) { 984 flash_attn_ext_f16_load_mask<ncols1, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 985 (mask_h, tile_mask, stride_mask, k_VKQ_0 + nbatch_fa, k_VKQ_sup, jt*ncols1, ne01, nullptr); 986 } 987 flash_attn_ext_f16_load_tile<stride_tile_K, swz_K, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 988 (K_h2, tile_K, nbatch_K2, stride_K, k_VKQ_0 + nbatch_fa, k_VKQ_sup, nullptr); 989 } 990 } 991 992 993 // Calculate VKQ tile, need to use logical rather than physical elements for i0 due to transposition of V: 994#pragma unroll 995 for (int i0_start = 0; i0_start < DV; i0_start += 2*nbatch_V2) { 996 static_assert(DV % (2*nbatch_V2) == 0, "bad loop size"); 997 const int i0_stop = i0_start + 2*nbatch_V2; 998 999 if constexpr (nstages <= 1) { 1000 const int i0_diff = i0_stop - i0_start; 1001 if (!V_is_K_view || i0_stop > 2*nbatch_K2) { 1002 constexpr bool use_cp_async = nstages == 1; 1003 flash_attn_ext_f16_load_tile<stride_tile_V, swz_V, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 1004 (V_h2 + i0_start/2, tile_V, i0_diff/2, stride_V, k_VKQ_0, k_VKQ_sup, indices); 1005 if (use_cp_async) { 1006 cp_async_wait_all(); 1007 } 1008 __syncthreads(); 1009 } 1010 } 1011 const half2 * tile_V_i = !V_is_K_view || i0_stop > 2*nbatch_K2 ? tile_V : tile_V + i0_start/2; 1012 1013#if defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1014#pragma unroll 1015 for (int i_VKQ_0 = i0_start; i_VKQ_0 < i0_stop; i_VKQ_0 += T_A_VKQ::I) { 1016 static_assert((nbatch_fa/2) % (np*T_A_VKQ::J) == 0, "bad loop size"); 1017#pragma unroll 1018 for (int k00 = 0; k00 < nbatch_fa/2; k00 += np*T_A_VKQ::J) { 1019 const int k0 = k00 + (threadIdx.y % np)*T_A_VKQ::J; 1020 1021 T_A_VKQ A; // Transposed in SRAM but not in registers, gets transposed on load. 1022 ggml_cuda_fattn_smem_swizzle::load_ldmatrix_trans<stride_tile_V, swz_V>(A, tile_V, (int)(tile_V_i - tile_V) + 2*k0*stride_tile_V + (i_VKQ_0 - i0_start)/2); 1023 if constexpr (T_B_KQ::I == 8) { 1024 mma(VKQ_C[i_VKQ_0/T_A_VKQ::I], A, B[k00/(np*T_A_VKQ::J)]); 1025 } else { 1026 // Wide version of VKQ_C is column-major. 1027#if defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1028 // AMD matrix C is column-major. 1029 mma(VKQ_C[i_VKQ_0/T_A_VKQ::I], A, B[k00/(np*T_A_VKQ::J)]); 1030#else 1031 // swap A and B for CUDA. 1032 mma(VKQ_C[i_VKQ_0/T_A_VKQ::I], B[k00/(np*T_A_VKQ::J)], A); 1033#endif // defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1034 } 1035 } 1036 } 1037#else // Volta 1038 constexpr int i0_stride = 2*T_C_VKQ::J; 1039#pragma unroll 1040 for (int i_VKQ_0 = i0_start; i_VKQ_0 < i0_stop; i_VKQ_0 += i0_stride) { 1041 static_assert(nbatch_fa % (np*T_A_VKQ::I) == 0, "bad loop size"); 1042 static_assert(2*T_B_VKQ::J == T_A_VKQ::I, "bad tile sizes"); 1043#pragma unroll 1044 for (int k00 = 0; k00 < nbatch_fa; k00 += np*T_A_VKQ::I) { 1045 const int k0 = k00 + (threadIdx.y % np)*T_A_VKQ::I; 1046 1047 T_A_VKQ A; // Transposed in both SRAM and registers, load normally. 1048 ggml_cuda_fattn_smem_swizzle::load_ldmatrix<stride_tile_V, swz_V>(A, tile_V, (int)(tile_V_i - tile_V) + k0*stride_tile_V + (i_VKQ_0 - i0_start)/2); 1049 mma(VKQ_C[i_VKQ_0/i0_stride], B[k00/(np*T_A_VKQ::I)], A); 1050 } 1051 } 1052#endif // defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1053 1054 if constexpr (nstages <= 1) { 1055 __syncthreads(); // Only needed if tile_K == tile_V. 1056 } 1057 } 1058#else 1059 GGML_UNUSED_VARS(Q_f2, K_h2, V_h2, mask_h, indices, dstk, dstk_fixup, 1060 scale, slope, logit_softcap, ne01, ne02, 1061 stride_K, stride_V, stride_mask, 1062 tile_Q, tile_K, tile_V, tile_mask, 1063 Q_B, VKQ_C, KQ_max, KQ_rowsum, kb0); 1064 NO_DEVICE_CODE; 1065#endif // defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1066} 1067 1068#if defined(TURING_MMA_AVAILABLE) 1069template<int DV, int ncols> struct mma_tile_sizes { 1070 using T_A_KQ = tile<16, 8, half2>; // row-major 1071 using T_B_KQ = tile<16, 8, half2>; // column-major 1072 using T_C_KQ = tile<16, 16, float>; // column-major 1073 using T_A_VKQ = tile<16, 8, half2>; // row-major 1074 using T_B_VKQ = tile<16, 8, half2>; // column-major 1075 using T_C_VKQ = tile<16, 8, half2>; // column-major 1076}; 1077template<int DV> struct mma_tile_sizes<DV, 8> { 1078 using T_A_KQ = tile<16, 8, half2>; // row-major 1079 using T_B_KQ = tile< 8, 8, half2>; // column-major 1080 using T_C_KQ = tile<16, 8, float>; // row-major 1081 using T_A_VKQ = tile<16, 8, half2>; // row-major 1082 using T_B_VKQ = tile< 8, 8, half2>; // column-major 1083 using T_C_VKQ = tile<16, 4, half2>; // row-major 1084}; 1085#elif defined(AMD_WMMA_AVAILABLE) 1086#ifdef RDNA3 1087template<int DV, int ncols> struct mma_tile_sizes { 1088 using T_A_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1089 using T_B_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // column-major 1090 using T_C_KQ = tile<16, 16, float, DATA_LAYOUT_I_MAJOR>; // column-major 1091 using T_A_VKQ = tile<32, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1092 using T_B_VKQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // column-major 1093 using T_C_VKQ = tile<16, 16, half2, DATA_LAYOUT_I_MAJOR>; // column-major 1094}; 1095template<int ncols> struct mma_tile_sizes<80, ncols> { 1096 using T_A_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1097 using T_B_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // column-major 1098 using T_C_KQ = tile<16, 16, float, DATA_LAYOUT_I_MAJOR>; // column-major 1099 using T_A_VKQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1100 using T_B_VKQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // column-major 1101 using T_C_VKQ = tile<16, 16, float, DATA_LAYOUT_I_MAJOR>; // column-major 1102}; 1103template<int ncols> struct mma_tile_sizes<112, ncols> { 1104 using T_A_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1105 using T_B_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // column-major 1106 using T_C_KQ = tile<16, 16, float, DATA_LAYOUT_I_MAJOR>; // column-major 1107 using T_A_VKQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1108 using T_B_VKQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // column-major 1109 using T_C_VKQ = tile<16, 16, float, DATA_LAYOUT_I_MAJOR>; // column-major 1110}; 1111#else 1112template<int DV, int ncols> struct mma_tile_sizes { 1113 using T_A_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR>; // row-major 1114 using T_B_KQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR>; // column-major 1115 using T_C_KQ = tile<16, 16, float, DATA_LAYOUT_I_MAJOR>; // column-major 1116 using T_A_VKQ = tile<32, 8, half2, DATA_LAYOUT_I_MAJOR>; // row-major 1117 using T_B_VKQ = tile<16, 8, half2, DATA_LAYOUT_I_MAJOR>; // column-major 1118 using T_C_VKQ = tile<16, 16, half2, DATA_LAYOUT_I_MAJOR_SCRAMBLED>; // column-major 1119}; 1120template<int ncols> struct mma_tile_sizes<80, ncols> { 1121 using T_A_KQ = tile<16, 8, half2>; // row-major 1122 using T_B_KQ = tile<16, 8, half2>; // column-major 1123 using T_C_KQ = tile<16, 16, float>; // column-major 1124 using T_A_VKQ = tile<16, 8, half2>; // row-major 1125 using T_B_VKQ = tile<16, 8, half2>; // column-major 1126 using T_C_VKQ = tile<16, 8, half2>; // column-major 1127}; 1128template<int ncols> struct mma_tile_sizes<112, ncols> { 1129 using T_A_KQ = tile<16, 8, half2>; // row-major 1130 using T_B_KQ = tile<16, 8, half2>; // column-major 1131 using T_C_KQ = tile<16, 16, float>; // column-major 1132 using T_A_VKQ = tile<16, 8, half2>; // row-major 1133 using T_B_VKQ = tile<16, 8, half2>; // column-major 1134 using T_C_VKQ = tile<16, 8, half2>; // column-major 1135}; 1136#endif // RDNA3 1137#elif defined(AMD_MFMA_AVAILABLE) 1138template<int DV, int ncols> struct mma_tile_sizes { 1139 using T_A_KQ = tile<16, 8, half2>; // row-major 1140 using T_B_KQ = tile<16, 8, half2>; // column-major 1141 using T_C_KQ = tile<16, 16, float>; // column-major 1142 using T_A_VKQ = tile<16, 8, half2>; // row-major 1143 using T_B_VKQ = tile<16, 8, half2>; // column-major 1144 using T_C_VKQ = tile<16, 16, float>; // column-major 1145}; 1146#else // Volta 1147template<int DV, int ncols> struct mma_tile_sizes { 1148 using T_A_KQ = tile< 8, 4, half2, DATA_LAYOUT_I_MAJOR_MIRRORED>; // row-major 1149 using T_B_KQ = tile<32, 4, half2, DATA_LAYOUT_I_MAJOR>; // column-major 1150 using T_C_KQ = tile<32, 8, float, DATA_LAYOUT_I_MAJOR>; // column-major 1151 using T_A_VKQ = tile< 8, 4, half2, DATA_LAYOUT_J_MAJOR_MIRRORED>; // column-major 1152 using T_B_VKQ = tile<32, 4, half2, DATA_LAYOUT_I_MAJOR>; // column-major 1153 using T_C_VKQ = tile<32, 4, half2, DATA_LAYOUT_I_MAJOR>; // column-major 1154}; 1155#endif // defined(TURING_MMA_AVAILABLE) 1156 1157template<int DKQ, int DV, int ncols1, int ncols2, int nwarps, bool use_logit_softcap, bool V_is_K_view, bool use_sparse, bool needs_fixup, bool is_fixup> 1158static __device__ __forceinline__ void flash_attn_ext_f16_process_tile( 1159 const float2 * const __restrict__ Q_f2, 1160 const half2 * const __restrict__ K_h2, 1161 const half2 * const __restrict__ V_h2, 1162 const half * const __restrict__ mask_h, 1163 const int32_t * const __restrict__ indices, 1164 const float * const __restrict__ sinks_f, 1165 float2 * const __restrict__ dstk, 1166 float2 * const __restrict__ dstk_fixup, 1167 const float scale, 1168 const float slope, 1169 const float logit_softcap, 1170 const uint3 ne01, 1171 const int ne02, 1172 const int gqa_ratio, 1173 const int ne11, 1174 const int stride_Q1, 1175 const int stride_Q2, 1176 const int stride_K, 1177 const int stride_V, 1178 const int stride_mask, 1179 const int jt, 1180 const int zt_gqa, 1181 const int kb0_start, 1182 const int kb0_stop) { 1183#if defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1184 //In this kernel Q, K, V are matrices while i, j, k are matrix indices. 1185 1186 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 1187 constexpr int ncols = ncols1 * ncols2; 1188 using T_A_KQ = typename mma_tile_sizes<DV, ncols>::T_A_KQ; 1189 using T_B_KQ = typename mma_tile_sizes<DV, ncols>::T_B_KQ; 1190 using T_C_KQ = typename mma_tile_sizes<DV, ncols>::T_C_KQ; 1191 using T_A_VKQ = typename mma_tile_sizes<DV, ncols>::T_A_VKQ; 1192 using T_B_VKQ = typename mma_tile_sizes<DV, ncols>::T_B_VKQ; 1193 using T_C_VKQ = typename mma_tile_sizes<DV, ncols>::T_C_VKQ; 1194 1195 constexpr int cols_per_warp = T_B_KQ::I; 1196 constexpr int cols_per_thread = get_cols_per_thread(); 1197 constexpr int np = cols_per_warp > ncols ? nwarps : nwarps * cols_per_warp/ncols; // Number of parallel CUDA warps per Q column. 1198 constexpr int nbatch_fa = ggml_cuda_fattn_mma_get_nbatch_fa (DKQ, DV, ncols); 1199 constexpr int nbatch_K2 = ggml_cuda_fattn_mma_get_nbatch_K2 (DKQ, DV, ncols); 1200 constexpr int nbatch_V2 = ggml_cuda_fattn_mma_get_nbatch_V2 (DKQ, DV, ncols); 1201 constexpr int nbatch_combine = ggml_cuda_fattn_mma_get_nbatch_combine(DKQ, DV, ncols); 1202 constexpr bool Q_in_reg = ggml_cuda_fattn_mma_get_Q_in_reg (DKQ, DV, ncols); 1203 constexpr int nstages = ggml_cuda_fattn_mma_get_nstages (DKQ, DV, ncols1, ncols2, use_sparse); 1204 1205 if (cols_per_warp > ncols) { 1206 NO_DEVICE_CODE; 1207 return; 1208 } 1209 1210 static_assert(nwarps * (cols_per_warp/ncols2) % ncols1 == 0, "bad nwarps"); 1211 1212 constexpr int stride_tile_Q = DKQ/2 + 4; 1213 // swizzle the tile stride for K and V based on the batch size. 1214 constexpr int stride_tile_K = ggml_cuda_fattn_smem_swizzle::tile_stride(nbatch_K2); 1215 constexpr int stride_tile_V = V_is_K_view ? stride_tile_K : ggml_cuda_fattn_smem_swizzle::tile_stride(nbatch_V2); 1216 constexpr int stride_tile_KV_max = stride_tile_K > stride_tile_V ? stride_tile_K : stride_tile_V; 1217 constexpr bool swz_K = ggml_cuda_fattn_smem_swizzle::enabled(nbatch_K2); 1218 constexpr bool swz_V = V_is_K_view ? swz_K : ggml_cuda_fattn_smem_swizzle::enabled(nbatch_V2); 1219 1220 extern __shared__ half2 tile_Q[]; 1221 half2 * tile_K = Q_in_reg ? tile_Q : tile_Q + ncols * stride_tile_Q; 1222 half2 * tile_V = nstages > 1 ? tile_K + nbatch_fa * stride_tile_K : tile_K; 1223 half * tile_mask = (half *) (nstages > 1 ? tile_V + nbatch_fa * stride_tile_V : tile_V + nbatch_fa * stride_tile_KV_max); 1224 1225 T_B_KQ Q_B[(Q_in_reg ? DKQ/(2*T_B_KQ::J) : 1)]; 1226#if defined(TURING_MMA_AVAILABLE) 1227 T_C_VKQ VKQ_C[cols_per_warp == 8 ? DV/T_C_VKQ::I : DV/(2*T_C_VKQ::J)]; 1228#elif defined(AMD_WMMA_AVAILABLE) && defined(RDNA3) 1229 T_C_VKQ VKQ_C[DV % 32 != 0 ? DV/T_C_VKQ::J : DV/(2*T_C_VKQ::J)]; 1230#elif defined(AMD_MFMA_AVAILABLE) 1231 T_C_VKQ VKQ_C[ DV/T_C_VKQ::J]; 1232#elif defined(AMD_WMMA_AVAILABLE) 1233 T_C_VKQ VKQ_C[ DV/(2*T_C_VKQ::J)]; 1234#else // Volta 1235 T_C_VKQ VKQ_C[ DV/(2*T_C_VKQ::J)]; 1236#endif // defined(TURING_MMA_AVAILABLE) 1237 1238 float KQ_rowsum[cols_per_thread] = {0.0f}; 1239 float KQ_max[cols_per_thread]; 1240#pragma unroll 1241 for (int col = 0; col < cols_per_thread; ++col) { 1242 KQ_max[col] = -FLT_MAX/2.0f; 1243 } 1244 1245 // Load Q data into tile_Q, either temporarily or permanently. 1246 // Q in registers is faster, but register pressure is the biggest bottleneck. 1247 // The loading is done with decreasing granularity for D for better memory bandwidth. 1248 const half2 scale_h2 = make_half2(scale, scale); 1249#pragma unroll 1250 for (int stride_k : {warp_size, warp_size/2, warp_size/4, warp_size/8}) { 1251 const int k0_start = stride_k == warp_size ? 0 : DKQ/2 - (DKQ/2) % (2*stride_k); 1252 const int k0_stop = DKQ/2 - (DKQ/2) % (1*stride_k); 1253 const int stride_jc = warp_size / stride_k; 1254 1255 if (k0_start == k0_stop) { 1256 continue; 1257 } 1258 1259#pragma unroll 1260 for (int jc0 = 0; jc0 < ncols; jc0 += nwarps*stride_jc) { 1261 const int jc = jc0 + threadIdx.y*stride_jc + (stride_k == warp_size ? 0 : threadIdx.x / stride_k); 1262 1263 if (jc0 + nwarps*stride_jc > ncols && jc >= ncols) { 1264 break; 1265 } 1266 1267 const int j = jc / ncols2; 1268 const int c = jc % ncols2; 1269 1270 if ((ncols1 == 1 || jt*ncols1 + j < int(ne01.z)) && (ncols2 == 1 || zt_gqa*ncols2 + c < gqa_ratio)) { 1271#pragma unroll 1272 for (int k0 = k0_start; k0 < k0_stop; k0 += stride_k) { 1273 const int k = k0 + (stride_k == warp_size ? threadIdx.x : threadIdx.x % stride_k); 1274 1275 const float2 tmp = Q_f2[(jt*ncols1 + j)*stride_Q1 + c*stride_Q2 + k]; 1276 tile_Q[jc*stride_tile_Q + k] = scale_h2 * make_half2(tmp.x, tmp.y); 1277 } 1278 } else { 1279#pragma unroll 1280 for (int k0 = k0_start; k0 < k0_stop; k0 += stride_k) { 1281 const int k = k0 + (stride_k == warp_size ? threadIdx.x : threadIdx.x % stride_k); 1282 1283 tile_Q[jc*stride_tile_Q + k] = make_half2(0.0f, 0.0f); 1284 } 1285 } 1286 } 1287 } 1288 1289 __syncthreads(); 1290 1291 if (Q_in_reg) { 1292 const int j0 = (threadIdx.y / np) * cols_per_warp; 1293 1294#pragma unroll 1295 for (int k0 = 0; k0 < DKQ/2; k0 += T_B_KQ::J) { 1296 load_ldmatrix(Q_B[k0/T_B_KQ::J], tile_Q + j0*stride_tile_Q + k0, stride_tile_Q); 1297 } 1298 } 1299 1300 __syncthreads(); 1301 1302 int kb0 = kb0_start; 1303 1304 // Preload mask and K data for first iteration when using cp_async with multiple stages: 1305 if constexpr (nstages > 1) { 1306 static_assert(!use_sparse, "sparse gather not implemented for multi-stage loading"); 1307 static_assert(nbatch_K2 == DKQ/2, "batching not implemented for multi-stage pipeline"); 1308 constexpr bool use_cp_async = true; 1309 constexpr bool oob_check = false; 1310 constexpr int k_VKQ_sup = nbatch_fa; 1311 if (ncols2 > 1 || mask_h) { 1312 flash_attn_ext_f16_load_mask<ncols1, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 1313 (mask_h, tile_mask, stride_mask, kb0*nbatch_fa, k_VKQ_sup, jt*ncols1, ne01, nullptr); 1314 } 1315 flash_attn_ext_f16_load_tile<stride_tile_K, swz_K, nwarps, nbatch_fa, use_cp_async, oob_check, use_sparse> 1316 (K_h2, tile_K, nbatch_K2, stride_K, kb0*nbatch_fa, k_VKQ_sup, nullptr); 1317 } 1318 1319 // kb0_start is always < kb0_stop so the last iter can be executed unconditionally. 1320 if constexpr (ncols2 == 1 || use_sparse) { 1321 constexpr bool oob_check = true; 1322 for (; kb0 < kb0_stop-1; ++kb0) { 1323 constexpr bool last_iter = false; 1324 constexpr int k_VKQ_sup = nbatch_fa; 1325 flash_attn_ext_f16_iter 1326 <DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup, last_iter, oob_check, 1327 T_A_KQ, T_B_KQ, T_C_KQ, T_A_VKQ, T_B_VKQ, T_C_VKQ> 1328 (Q_f2, K_h2, V_h2, mask_h, indices, dstk, dstk_fixup, scale, slope, logit_softcap, 1329 ne01, ne02, stride_K, stride_V, stride_mask, tile_Q, tile_K, tile_V, tile_mask, Q_B, VKQ_C, 1330 KQ_max, KQ_rowsum, jt, kb0, k_VKQ_sup); 1331 } 1332 constexpr bool last_iter = true; 1333 const int k_VKQ_sup = ne11 - kb0*nbatch_fa; 1334 flash_attn_ext_f16_iter 1335 <DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup, last_iter, oob_check, 1336 T_A_KQ, T_B_KQ, T_C_KQ, T_A_VKQ, T_B_VKQ, T_C_VKQ> 1337 (Q_f2, K_h2, V_h2, mask_h, indices, dstk, dstk_fixup, scale, slope, logit_softcap, 1338 ne01, ne02, stride_K, stride_V, stride_mask, tile_Q, tile_K, tile_V, tile_mask, Q_B, VKQ_C, 1339 KQ_max, KQ_rowsum, jt, kb0, k_VKQ_sup); 1340 } else { 1341 constexpr bool oob_check = false; 1342 for (; kb0 < kb0_stop-1; ++kb0) { 1343 constexpr bool last_iter = false; 1344 constexpr int k_VKQ_sup = nbatch_fa; 1345 flash_attn_ext_f16_iter 1346 <DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup, last_iter, oob_check, 1347 T_A_KQ, T_B_KQ, T_C_KQ, T_A_VKQ, T_B_VKQ, T_C_VKQ> 1348 (Q_f2, K_h2, V_h2, mask_h, indices, dstk, dstk_fixup, scale, slope, logit_softcap, 1349 ne01, ne02, stride_K, stride_V, stride_mask, tile_Q, tile_K, tile_V, tile_mask, Q_B, VKQ_C, 1350 KQ_max, KQ_rowsum, jt, kb0, k_VKQ_sup); 1351 } 1352 constexpr bool last_iter = true; 1353 constexpr int k_VKQ_sup = nbatch_fa; 1354 flash_attn_ext_f16_iter 1355 <DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup, last_iter, oob_check, 1356 T_A_KQ, T_B_KQ, T_C_KQ, T_A_VKQ, T_B_VKQ, T_C_VKQ> 1357 (Q_f2, K_h2, V_h2, mask_h, indices, dstk, dstk_fixup, scale, slope, logit_softcap, 1358 ne01, ne02, stride_K, stride_V, stride_mask, tile_Q, tile_K, tile_V, tile_mask, Q_B, VKQ_C, 1359 KQ_max, KQ_rowsum, jt, kb0, k_VKQ_sup); 1360 } 1361 1362 // With multi-stage loading there is no __syncthreads at the end of the iter, 1363 // there can be a race condition on shared memory access for combining/writing back results. 1364 if constexpr (nstages > 1 && nwarps*cols_per_warp > nbatch_fa) { 1365 __syncthreads(); 1366 } 1367 1368 // Finally, sum up partial KQ rowsums. 1369 { 1370#if defined(TURING_MMA_AVAILABLE) 1371 // The partial sums are spread across 8/4 threads. 1372 constexpr int offset_first = cols_per_warp == 8 ? 16 : 2; 1373 constexpr int offset_last = cols_per_warp == 8 ? 4 : 1; 1374#elif defined(AMD_MFMA_AVAILABLE) 1375 // The partial sums are spread across 4 threads (wavefront64, 16 cols). 1376 constexpr int offset_first = 32; 1377 constexpr int offset_last = 16; 1378#elif defined(AMD_WMMA_AVAILABLE) 1379 // The partial sums are spread across 2 threads. 1380 constexpr int offset_first = 16; 1381 constexpr int offset_last = 16; 1382#else // Volta 1383 // The partial sums are spread across 2 threads. 1384 constexpr int offset_first = 2; 1385 constexpr int offset_last = 2; 1386#endif // defined(TURING_MMA_AVAILABLE) 1387#pragma unroll 1388 for (int col = 0; col < cols_per_thread; ++col) { 1389#pragma unroll 1390 for (int offset = offset_first; offset >= offset_last; offset >>= 1) { 1391 KQ_rowsum[col] += __shfl_xor_sync(0xFFFFFFFF, KQ_rowsum[col], offset, warp_size); 1392 } 1393 } 1394 } 1395 1396 // If attention sinks are used, potentially re-scale if KQ_max is small. 1397 // Also add the sink as a value to KQ_rowsum, this is done after synchronization of KQ_rowsum 1398 // so it's being done unconditionally for every thread. 1399 if (!is_fixup && (np == 1 || threadIdx.y % np == 0) && sinks_f) { 1400 float KQ_max_scale[cols_per_thread]; 1401#pragma unroll 1402 for (int col = 0; col < cols_per_thread; ++col) { 1403 const int jc = (threadIdx.y/np)*cols_per_warp + (cols_per_warp == 8 ? T_C_KQ::get_j(col) : T_C_KQ::get_i(2*col)); 1404 const float sink = sinks_f[jc % ncols2]; 1405 1406 const float KQ_max_new = fmaxf(KQ_max[col], sink); 1407 const float KQ_max_diff = KQ_max[col] - KQ_max_new; 1408 KQ_max_scale[col] = expf(KQ_max_diff); 1409 KQ_max[col] = KQ_max_new; 1410 1411 *((uint32_t *) &KQ_max_scale[col]) *= KQ_max_diff >= SOFTMAX_FTZ_THRESHOLD; 1412 1413 const float KQ_max_add = expf(sink - KQ_max_new); 1414 KQ_rowsum[col] = KQ_max_scale[col]*KQ_rowsum[col] + KQ_max_add; 1415 } 1416 1417#if defined(TURING_MMA_AVAILABLE) 1418 if constexpr (cols_per_warp == 8) { 1419 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[0], KQ_max_scale[cols_per_thread - 1]); 1420#pragma unroll 1421 for (int i = 0; i < DV/T_C_VKQ::I; ++i) { 1422#pragma unroll 1423 for (int l = 0; l < T_C_VKQ::ne; ++l) { 1424 VKQ_C[i].x[l] *= KQ_max_scale_h2; 1425 } 1426 } 1427 } else { 1428#pragma unroll 1429 for (int col = 0; col < cols_per_thread; ++col) { 1430 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[col], KQ_max_scale[col]); 1431#pragma unroll 1432 for (int i = 0; i < (DV/2)/T_C_VKQ::J; ++i) { 1433#pragma unroll 1434 for (int l0 = 0; l0 < T_C_VKQ::ne; l0 += 2) { 1435 VKQ_C[i].x[l0 + col] *= KQ_max_scale_h2; 1436 } 1437 } 1438 } 1439 } 1440#elif defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1441 if constexpr (std::is_same_v<decltype(T_C_VKQ::x), half2[T_C_VKQ::ne]>) { 1442 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[0], KQ_max_scale[0]); 1443#pragma unroll 1444 for (int i = 0; i < (DV/2)/T_C_VKQ::J; ++i) { 1445#pragma unroll 1446 for (int l = 0; l < T_C_VKQ::ne; ++l) { 1447 VKQ_C[i].x[l] *= KQ_max_scale_h2; 1448 } 1449 } 1450 } else { 1451 static_assert(std::is_same_v<decltype(T_C_VKQ::x), float[T_C_VKQ::ne]>, "bad VKQ type"); 1452#pragma unroll 1453 for (int i = 0; i < DV/T_C_VKQ::J; ++i) { 1454#pragma unroll 1455 for (int l = 0; l < T_C_VKQ::ne; ++l) { 1456 VKQ_C[i].x[l] *= KQ_max_scale[0]; 1457 } 1458 } 1459 } 1460#else // Volta 1461 const int col = (threadIdx.x / 2) % 2; 1462 const half2 KQ_max_scale_h2 = make_half2(KQ_max_scale[col], KQ_max_scale[col]); 1463#pragma unroll 1464 for (int i = 0; i < (DV/2)/T_C_VKQ::J; ++i) { 1465#pragma unroll 1466 for (int l = 0; l < T_C_VKQ::ne; ++l) { 1467 VKQ_C[i].x[l] *= KQ_max_scale_h2; 1468 } 1469 } 1470#endif // defined(TURING_MMA_AVAILABLE) 1471 } 1472 1473 // Combine VKQ accumulator values if np > 1. 1474 // It's also faster to do small writes to shared memory, then large write to VRAM than to do small writes to VRAM. 1475 // So also write VKQ accumulators to shared memory in column-major format if np == 1. 1476 1477 constexpr int tile_stride = nbatch_combine + 4; 1478 static_assert((DV/2) % nbatch_combine == 0, "bad nbatch_combine"); 1479 1480 constexpr bool combine_needs_sync = swz_K || swz_V; 1481 1482 if constexpr (cols_per_warp == 8) { 1483 const int jc_cwmo = (threadIdx.x % (2*T_C_VKQ::J)) / T_C_VKQ::J; // jc combine write meta offset 1484 const int jc_cwm = threadIdx.y*(2*T_C_VKQ::J) + 2*T_C_VKQ::get_j(-1) + jc_cwmo; // jc combine write meta 1485 const float2 KQ_cmr = make_float2(KQ_max[jc_cwmo], KQ_rowsum[jc_cwmo]); // KQ combine max rowsum 1486 1487 if constexpr (combine_needs_sync) { 1488 __syncthreads(); 1489 } 1490 1491 if (((!needs_fixup && !is_fixup) || np > 1) && threadIdx.x < 2*T_C_VKQ::J) { 1492 // Use the 16 bytes of padding in each row to store the meta data: KQ max, KQ rowsum, KQ max scale. 1493 ((float2 *) tile_Q)[jc_cwm*(tile_stride/2) + nbatch_combine/2] = KQ_cmr; 1494 } 1495 1496 __syncthreads(); 1497 1498 if (np == 1) { 1499 // No combination is needed, the meta data can be directly written from registers to VRAM. 1500 if (needs_fixup && threadIdx.x < T_B_KQ::I) { 1501 float2 * dstk_fixup_meta = dstk_fixup + blockIdx.x*ncols; 1502 dstk_fixup_meta[jc_cwm] = KQ_cmr; 1503 } 1504 if (is_fixup && threadIdx.x < T_B_KQ::I) { 1505 float2 * dstk_fixup_meta = dstk_fixup + (gridDim.x + blockIdx.x)*ncols; 1506 dstk_fixup_meta[jc_cwm] = KQ_cmr; 1507 } 1508 } 1509 } else { 1510 // jc_cwm = jc combine write meta 1511 // KQ_cmr = KQ combine max rowsum 1512 // Use the 16 bytes of padding in each Q column to store the meta data: KQ max, KQ rowsum, KQ max scale. 1513#if defined(TURING_MMA_AVAILABLE) 1514 const int jc_cwm = threadIdx.y*cols_per_warp + T_C_VKQ::get_i(threadIdx.x % 4); 1515 const float2 KQ_cmr = make_float2(KQ_max[threadIdx.x % cols_per_thread], KQ_rowsum[threadIdx.x % cols_per_thread]); 1516 const bool thread_should_write = threadIdx.x % 4 < cols_per_thread; 1517#elif defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1518 const int jc_cwm = threadIdx.y*cols_per_warp + T_C_VKQ::get_i(0); 1519 const float2 KQ_cmr = make_float2(KQ_max[0], KQ_rowsum[0]); 1520 const bool thread_should_write = threadIdx.x / 16 < cols_per_thread; 1521#else // Volta 1522 const int jc_cwm = threadIdx.y*cols_per_warp + T_C_KQ::get_i(threadIdx.x & 2); 1523 const float2 KQ_cmr = make_float2(KQ_max[(threadIdx.x & 2) / 2], KQ_rowsum[(threadIdx.x & 2) / 2]); 1524 const bool thread_should_write = T_C_KQ::J == 8 || T_C_KQ::get_j(threadIdx.x & 2) < 8; 1525#endif // defined(TURING_MMA_AVAILABLE) 1526 1527 if constexpr (combine_needs_sync) { 1528 __syncthreads(); 1529 } 1530 1531 if (((!needs_fixup && !is_fixup) || np > 1) && thread_should_write) { 1532 ((float2 *) tile_Q)[jc_cwm*(tile_stride/2) + nbatch_combine/2] = KQ_cmr; 1533 } 1534 1535 __syncthreads(); 1536 1537 if (np == 1) { 1538 // No combination is needed, the meta data can be directly written from registers to VRAM. 1539 if (needs_fixup && thread_should_write) { 1540 float2 * dstk_fixup_meta = dstk_fixup + blockIdx.x*ncols; 1541 dstk_fixup_meta[jc_cwm] = KQ_cmr; 1542 } 1543 if (is_fixup && thread_should_write) { 1544 float2 * dstk_fixup_meta = dstk_fixup + (gridDim.x + blockIdx.x)*ncols; 1545 dstk_fixup_meta[jc_cwm] = KQ_cmr; 1546 } 1547 } 1548 } 1549 1550 if (np > 1) { 1551 constexpr int nmeta = np*cols_per_warp >= warp_size ? np*cols_per_warp/warp_size : 1; 1552 1553 float KQ_cmn; 1554 float KQ_cms[nmeta]; 1555 float KQ_crs; 1556 1557 const int jc_meta = threadIdx.y*cols_per_warp + (np*cols_per_warp < warp_size ? threadIdx.x % (np*cols_per_warp) : threadIdx.x); 1558 float2 * const meta_ptr = ((float2 *) tile_Q) + jc_meta*(tile_stride/2) + nbatch_combine/2; 1559 1560 if (threadIdx.y % np == 0) { 1561 // Combine the meta data for parallel warps via shared memory. 1562 float2 meta[nmeta]; 1563#pragma unroll 1564 for (int imeta = 0; imeta < nmeta; ++imeta) { 1565 meta[imeta] = meta_ptr[imeta * warp_size * tile_stride/2]; 1566 } 1567 1568 KQ_cmn = meta[0].x; // KQ combine max new, max between all parallel warps. 1569#pragma unroll 1570 for (int imeta = 1; imeta < nmeta; ++imeta) { 1571 KQ_cmn = fmaxf(KQ_cmn, meta[imeta].x); 1572 } 1573#pragma unroll 1574 for (int offset = np*cols_per_warp/2; offset >= cols_per_warp; offset >>= 1) { 1575 if (offset < warp_size) { 1576 KQ_cmn = fmaxf(KQ_cmn, __shfl_xor_sync(0xFFFFFFFF, KQ_cmn, offset, warp_size)); 1577 } 1578 } 1579 1580#pragma unroll 1581 for (int imeta = 0; imeta < nmeta; ++imeta) { 1582 KQ_cms[imeta] = expf(meta[imeta].x - KQ_cmn); 1583 } 1584 1585 KQ_crs = KQ_cms[0]*meta[0].y; // KQ combine rowsum, scaled sum of all parallel warps. 1586#pragma unroll 1587 for (int imeta = 1; imeta < nmeta; ++imeta) { 1588 KQ_crs += KQ_cms[imeta]*meta[imeta].y; 1589 } 1590#pragma unroll 1591 for (int offset = np*cols_per_warp/2; offset >= cols_per_warp; offset >>= 1) { 1592 if (offset < warp_size) { 1593 KQ_crs += __shfl_xor_sync(0xFFFFFFFF, KQ_crs, offset, warp_size); 1594 } 1595 } 1596 } 1597 1598 __syncthreads(); 1599 1600 if (threadIdx.y % np == 0) { 1601 // Write back combined meta data: 1602#pragma unroll 1603 for (int imeta = 0; imeta < nmeta; ++imeta) { 1604 if (np*cols_per_warp >= warp_size || threadIdx.x < np*cols_per_warp) { 1605 // Combined KQ max scale + rowsum. 1606 meta_ptr[imeta * warp_size * tile_stride/2] = make_float2(KQ_cms[imeta], KQ_crs); 1607 } 1608 } 1609 1610 // Combined KQ max + rowsum. 1611 static_assert(cols_per_warp <= warp_size); 1612 if (needs_fixup && (cols_per_warp == warp_size || threadIdx.x < cols_per_warp)) { 1613 float2 * dstk_fixup_meta = dstk_fixup + blockIdx.x*ncols; 1614 dstk_fixup_meta[(threadIdx.y/np)*cols_per_warp + threadIdx.x] = make_float2(KQ_cmn, KQ_crs); 1615 } 1616 if (is_fixup && (cols_per_warp == warp_size || threadIdx.x < cols_per_warp)) { 1617 float2 * dstk_fixup_meta = dstk_fixup + (gridDim.x + blockIdx.x)*ncols; 1618 dstk_fixup_meta[(threadIdx.y/np)*cols_per_warp + threadIdx.x] = make_float2(KQ_cmn, KQ_crs); 1619 } 1620 } 1621 } 1622 1623#pragma unroll 1624 for (int k00 = 0; k00 < DV/2; k00 += nbatch_combine) { 1625 if constexpr (cols_per_warp == 8) { 1626 static_assert(std::is_same_v<decltype(T_C_VKQ::x), half2[T_C_VKQ::ne]>, "bad VKQ type"); 1627 const int jc_cwd = threadIdx.y*T_B_KQ::I + T_B_KQ::get_i(-1); // jc combine write data 1628#pragma unroll 1629 for (int k1 = 0; k1 < nbatch_combine; k1 += T_B_KQ::J) { 1630 const T_B_KQ B = get_transposed(VKQ_C[(k00 + k1)/T_B_KQ::J]); // Conversion of C to B matrix puts it in column-major format. 1631 1632#pragma unroll 1633 for (int l = 0; l < T_B_KQ::ne; ++l) { 1634 const int k = k1 + T_B_KQ::get_j(l); 1635 1636 tile_Q[jc_cwd*tile_stride + k] = B.x[l]; 1637 } 1638 } 1639 } else { 1640 const int j0 = threadIdx.y*cols_per_warp; 1641 if constexpr (std::is_same_v<decltype(T_C_VKQ::x), half2[T_C_VKQ::ne]>) { 1642 if constexpr (T_C_VKQ::dl == DATA_LAYOUT_I_MAJOR) { 1643#pragma unroll 1644 for (int k1 = 0; k1 < nbatch_combine; k1 += T_C_VKQ::J) { 1645#pragma unroll 1646 for (int l = 0; l < T_C_VKQ::ne; ++l) { 1647 const int j = j0 + T_C_VKQ::get_i(l); 1648 const int k = k1 + T_C_VKQ::get_j(l); 1649 1650 tile_Q[j*tile_stride + k] = VKQ_C[(k00 + k1)/T_C_VKQ::J].x[l]; 1651 } 1652 } 1653 } else { 1654 static_assert(T_C_VKQ::dl == DATA_LAYOUT_I_MAJOR_SCRAMBLED, "bad T_C_VKQ data layout"); 1655 using T_C_VKQ_us = tile<T_C_VKQ::I, T_C_VKQ::J, half2, DATA_LAYOUT_I_MAJOR>; // us == unscrambled 1656#pragma unroll 1657 for (int k1 = 0; k1 < nbatch_combine; k1 += T_C_VKQ::J) { 1658 const T_C_VKQ_us VKQ_C_us = unscramble(VKQ_C[(k00 + k1)/T_C_VKQ::J]); 1659#pragma unroll 1660 for (int l = 0; l < T_C_VKQ_us::ne; ++l) { 1661 const int j = j0 + T_C_VKQ_us::get_i(l); 1662 const int k = k1 + T_C_VKQ_us::get_j(l); 1663 1664 tile_Q[j*tile_stride + k] = VKQ_C_us.x[l]; 1665 } 1666 } 1667 } 1668 } else { 1669 static_assert(std::is_same_v<decltype(T_C_VKQ::x), float[T_C_VKQ::ne]>, "bad VKQ type"); 1670 half * tile_Q_h = (half *) tile_Q; 1671#pragma unroll 1672 for (int k1 = 0; k1 < nbatch_combine; k1 += T_C_VKQ::J/2) { 1673#pragma unroll 1674 for (int l = 0; l < T_C_VKQ::ne; ++l) { 1675 const int j = j0 + T_C_VKQ::get_i(l); 1676 const int k = 2*k1 + T_C_VKQ::get_j(l); 1677 1678 tile_Q_h[j*(2*tile_stride) + k] = VKQ_C[(k00 + k1)/(T_C_VKQ::J/2)].x[l]; 1679 } 1680 } 1681 } 1682 } 1683 1684 __syncthreads(); 1685 1686 if (np == 1 || threadIdx.y % np == 0) { 1687 // The first 2*2*gridDim.x*ncols floats in dstk_fixup are for storing max. values and row sums. 1688 // The values after that are for the partial results of the individual blocks. 1689 float2 * dstk_fixup_data = dstk_fixup + gridDim.x*(2*ncols) + blockIdx.x*(ncols*(DV/2)); 1690 1691#pragma unroll 1692 for (int stride_k : {warp_size, warp_size/2, warp_size/4, warp_size/8}) { 1693 const int k0_start = stride_k == warp_size ? 0 : nbatch_combine - nbatch_combine % (2*stride_k); 1694 const int k0_stop = nbatch_combine - nbatch_combine % (1*stride_k); 1695 const int stride_jc = warp_size / stride_k; 1696 1697 if (k0_start == k0_stop) { 1698 continue; 1699 } 1700 1701#pragma unroll 1702 for (int jc0_dst = 0; jc0_dst < ncols; jc0_dst += (nwarps/np)*stride_jc) { 1703 const int jc_dst = jc0_dst + (threadIdx.y/np)*stride_jc + (stride_k == warp_size ? 0 : threadIdx.x / stride_k); 1704 1705 if (jc0_dst + (nwarps/np)*stride_jc > ncols && jc_dst >= ncols) { 1706 break; 1707 } 1708 1709 const int jc_tile_K = (jc_dst/cols_per_warp)*(np*cols_per_warp) + jc_dst % cols_per_warp; 1710 1711 const int j_dst = jc_dst / ncols2; 1712 const int c_dst = jc_dst % ncols2; 1713 1714 if (!is_fixup && ((ncols1 > 1 && jt*ncols1 + j_dst >= int(ne01.z)) || (ncols2 > 1 && zt_gqa*ncols2 + c_dst >= gqa_ratio))) { 1715 continue; 1716 } 1717 1718 const float * meta_j = (const float *) tile_Q + jc_tile_K*tile_stride + nbatch_combine; 1719#pragma unroll 1720 for (int k0 = k0_start; k0 < k0_stop; k0 += stride_k) { 1721 const int k = k0 + (stride_k == warp_size ? threadIdx.x : threadIdx.x % stride_k); 1722 1723 float2 dstk_val = make_float2(0.0f, 0.0f); 1724#pragma unroll 1725 for (int ip = 0; ip < np; ++ip) { 1726 const float KQ_crs = np == 1 ? 1.0f : meta_j[ip*cols_per_warp * tile_stride + 0]; 1727 const float2 dstk_val_add = __half22float2(tile_Q[(jc_tile_K + ip*cols_per_warp) * tile_stride + k]); 1728 dstk_val.x += dstk_val_add.x*KQ_crs; 1729 dstk_val.y += dstk_val_add.y*KQ_crs; 1730 } 1731 1732 if (!needs_fixup && !is_fixup) { 1733 const float KQ_rowsum_j = meta_j[1]; 1734 dstk_val.x /= KQ_rowsum_j; 1735 dstk_val.y /= KQ_rowsum_j; 1736 } 1737 1738 if (is_fixup) { 1739 dstk_fixup_data[jc_dst*(DV/2) + k00 + k] = dstk_val; 1740 } else { 1741 dstk[((jt*ncols1 + j_dst)*ne02 + c_dst)*(DV/2) + k00 + k] = dstk_val; 1742 } 1743 } 1744 } 1745 } 1746 } 1747 if (np > 1) { 1748 __syncthreads(); 1749 } 1750 } 1751#else 1752 GGML_UNUSED_VARS(Q_f2, K_h2, V_h2, mask_h, indices, sinks_f, dstk, dstk_fixup, 1753 scale, slope, logit_softcap, ne01, ne02, gqa_ratio, 1754 stride_Q1, stride_Q2, stride_K, stride_V, stride_mask, 1755 jt, kb0_start, kb0_stop); 1756 NO_DEVICE_CODE; 1757#endif // defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 1758} 1759 1760static constexpr __host__ __device__ bool ggml_cuda_flash_attn_ext_mma_f16_may_use_sparse( 1761 const int DKQ, const int DV, const int ncols1, const int ncols2) { 1762 return (DKQ == 512 && DV == 512 && ncols1 == 1 && ncols2 == 8) || 1763 (DKQ == 576 && DV == 512 && ncols1 == 1 && ncols2 == 16); 1764} 1765 1766template<int DKQ, int DV, int ncols1, int ncols2, bool use_logit_softcap, bool V_is_K_view, bool use_sparse> 1767__launch_bounds__(ggml_cuda_fattn_mma_get_nthreads(DKQ, DV, ncols1*ncols2), ggml_cuda_fattn_mma_get_occupancy(DKQ, DV, ncols1*ncols2)) 1768static __global__ void flash_attn_ext_f16( 1769 const char * Q_ptr, 1770 const char * K_ptr, 1771 const char * V_ptr, 1772 const char * mask_ptr, 1773 const char * sinks_ptr, 1774 const int * KV_max_ptr, 1775 float * dst_ptr, 1776 float2 * dst_meta_ptr, 1777 const float scale, 1778 const float max_bias, 1779 const float m0, 1780 const float m1, 1781 const uint32_t n_head_log2, 1782 const float logit_softcap, 1783 const int32_t ne00, const uint3 ne01, const int32_t ne02, const int32_t ne03, 1784 const int32_t nb01, const int32_t nb02, const int32_t nb03, 1785 const int32_t ne10, const int32_t ne11, const int32_t ne12, const int32_t ne13, 1786 const int32_t nb11, const int32_t nb12, const int64_t nb13, 1787 const int32_t nb21, const int32_t nb22, const int64_t nb23, 1788 const int32_t ne31, const int32_t ne32, const int32_t ne33, 1789 const int32_t nb31, const int32_t nb32, const int64_t nb33) { 1790 ggml_cuda_pdl_sync(); // TODO optimize placement 1791#if defined(FLASH_ATTN_AVAILABLE) && (defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE)) 1792 const char * GGML_CUDA_RESTRICT Q = Q_ptr; 1793 const char * GGML_CUDA_RESTRICT K = K_ptr; 1794 const char * GGML_CUDA_RESTRICT V = V_ptr; 1795 const char * GGML_CUDA_RESTRICT mask = mask_ptr; 1796 const char * GGML_CUDA_RESTRICT sinks = sinks_ptr; 1797 const int * GGML_CUDA_RESTRICT KV_max = use_sparse ? nullptr : KV_max_ptr; 1798 const int * GGML_CUDA_RESTRICT sparse_indices = use_sparse ? KV_max_ptr : nullptr; 1799 float * GGML_CUDA_RESTRICT dst = dst_ptr; 1800 float2 * GGML_CUDA_RESTRICT dst_meta = dst_meta_ptr; 1801 1802 // Skip unused kernel variants for faster compilation: 1803 if (use_logit_softcap && !(DKQ == 128 || DKQ == 256 || DKQ == 512)) { 1804 NO_DEVICE_CODE; 1805 return; 1806 } 1807 if (DKQ == 192 && ncols2 != 8 && ncols2 != 16) { 1808 NO_DEVICE_CODE; 1809 return; 1810 } 1811 1812 if (!ggml_cuda_flash_attn_ext_mma_f16_may_use_sparse(DKQ, DV, ncols1, ncols2) && use_sparse) { 1813 NO_DEVICE_CODE; 1814 return; 1815 } 1816#ifdef VOLTA_MMA_AVAILABLE 1817 if (ncols1*ncols2 < 32) { 1818 NO_DEVICE_CODE; 1819 return; 1820 } 1821#endif // VOLTA_MMA_AVAILABLE 1822 1823#if __CUDA_ARCH__ == GGML_CUDA_CC_TURING 1824 if (ncols1*ncols2 > 32) { 1825 NO_DEVICE_CODE; 1826 return; 1827 } 1828#endif // __CUDA_ARCH__ == GGML_CUDA_CC_TURING 1829 1830#if defined(AMD_WMMA_AVAILABLE) 1831 if (ncols1*ncols2 < 16 || ncols2 == 1 || DKQ > 256) { 1832 NO_DEVICE_CODE; 1833 return; 1834 } 1835#endif // defined(AMD_WMMA_AVAILABLE) 1836 1837#if defined(AMD_MFMA_AVAILABLE) 1838 if (ncols1*ncols2 < 16 || DKQ > 256) { 1839 NO_DEVICE_CODE; 1840 return; 1841 } 1842#endif // defined(AMD_MFMA_AVAILABLE) 1843 1844 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 1845 constexpr int ncols = ncols1 * ncols2; 1846 constexpr int nbatch_fa = ggml_cuda_fattn_mma_get_nbatch_fa(DKQ, DV, ncols); 1847 constexpr int nthreads = ggml_cuda_fattn_mma_get_nthreads(DKQ, DV, ncols); 1848 constexpr int nwarps = nthreads / warp_size; 1849 1850 const int gqa_ratio = ne02 / ne12; // With grouped query attention there are > 1 Q matrices per K, V matrix. 1851 1852 const int stride_Q1 = nb01 / sizeof(float2); 1853 const int stride_Q2 = nb02 / sizeof(float2); 1854 const int stride_K = nb11 / sizeof(half2); 1855 const int stride_mask = nb31 / sizeof(half); 1856 1857 const int stride_V = V_is_K_view ? stride_K : nb21 / sizeof(half2); 1858 1859 const int iter_k = (ne11 + (nbatch_fa - 1)) / nbatch_fa; 1860 const int iter_j = (ne01.z + (ncols1 - 1)) / ncols1; 1861 const int iter_z_gqa = (gqa_ratio + (ncols2 - 1)) / ncols2; 1862 1863 // kbc == k block continuous, current index in continuous ijk space. 1864 int kbc = int64_t(blockIdx.x + 0)*(iter_k*iter_j*iter_z_gqa*ne12*ne03) / gridDim.x; 1865 const int kbc_stop = int64_t(blockIdx.x + 1)*(iter_k*iter_j*iter_z_gqa*ne12*ne03) / gridDim.x; 1866 1867 // If the seams of 2 CUDA blocks fall within an output tile their results need to be combined. 1868 // For this we need to track both the block that starts the tile (needs_fixup) and the block that finishes the tile (is_fixup). 1869 // In the most general case >2 seams can fall into the same tile. 1870 1871 // kb0 == k start index when in the output tile. 1872 int kb0_start = kbc % iter_k; 1873 int kb0_stop = min(iter_k, kb0_start + kbc_stop - kbc); 1874 1875 while (kbc < kbc_stop && kb0_stop == iter_k) { 1876 // z_KV == K/V head index, zt_gqa = Q head start index per K/V head, jt = token position start index 1877 const int sequence = kbc /(iter_k*iter_j*iter_z_gqa*ne12); 1878 const int z_KV = (kbc - iter_k*iter_j*iter_z_gqa*ne12 * sequence)/(iter_k*iter_j*iter_z_gqa); 1879 const int zt_gqa = (kbc - iter_k*iter_j*iter_z_gqa*ne12 * sequence - iter_k*iter_j*iter_z_gqa * z_KV)/(iter_k*iter_j); 1880 const int jt = (kbc - iter_k*iter_j*iter_z_gqa*ne12 * sequence - iter_k*iter_j*iter_z_gqa * z_KV - iter_k*iter_j * zt_gqa) / iter_k; 1881 1882 const int zt_Q = z_KV*gqa_ratio + zt_gqa*ncols2; // Global Q head start index. 1883 1884 const float2 * Q_f2 = (const float2 *) (Q + nb03*sequence + nb02*zt_Q); 1885 const half2 * K_h2 = (const half2 *) (K + nb13*sequence + nb12*z_KV); 1886 const half * mask_h = ncols2 == 1 && !mask ? nullptr : 1887 (const half *) (mask + nb33*(sequence % ne33)); 1888 float2 * dstk = ((float2 *) dst) + (sequence*ne01.z*ne02 + zt_Q) * (DV/2); 1889 1890 const half2 * V_h2 = V_is_K_view ? K_h2 : (const half2 *) (V + nb23*sequence + nb22*z_KV); 1891 const float * sinks_f = sinks ? (const float *) sinks + zt_Q : nullptr; 1892 const int32_t * indices = use_sparse ? sparse_indices + (int64_t(sequence % ne33)*ne31 + jt*ncols1)*ne11 : nullptr; 1893 1894 const float slope = ncols2 == 1 ? get_alibi_slope(max_bias, zt_Q, n_head_log2, m0, m1) : 1.0f; 1895 1896 if (KV_max) { 1897 kb0_stop = min(kb0_stop, KV_max[sequence*iter_j + jt] / nbatch_fa); 1898 } 1899 constexpr bool is_fixup = false; // All but (potentially) the last iterations write their data to dst rather than the fixup buffer. 1900 if (kb0_start == 0) { 1901 constexpr bool needs_fixup = false; // CUDA block is working on an entire tile. 1902 flash_attn_ext_f16_process_tile<DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup> 1903 (Q_f2, K_h2, V_h2, mask_h, indices, sinks_f, dstk, dst_meta, scale, slope, logit_softcap, 1904 ne01, ne02, gqa_ratio, ne11, stride_Q1, stride_Q2, stride_K, stride_V, stride_mask, jt, zt_gqa, kb0_start, kb0_stop); 1905 } else { 1906 constexpr bool needs_fixup = true; // CUDA block is missing the beginning of a tile. 1907 flash_attn_ext_f16_process_tile<DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup> 1908 (Q_f2, K_h2, V_h2, mask_h, indices, sinks_f, dstk, dst_meta, scale, slope, logit_softcap, 1909 ne01, ne02, gqa_ratio, ne11, stride_Q1, stride_Q2, stride_K, stride_V, stride_mask, jt, zt_gqa, kb0_start, kb0_stop); 1910 } 1911 1912 kbc += iter_k; 1913 kbc -= kbc % iter_k; 1914 1915 kb0_start = 0; 1916 kb0_stop = min(iter_k, kbc_stop - kbc); 1917 } 1918 1919 if (kbc >= kbc_stop) { 1920 return; 1921 } 1922 1923 // z_KV == K/V head index, zt_gqa = Q head start index per K/V head, jt = token position start index. 1924 const int sequence = kbc /(iter_k*iter_j*iter_z_gqa*ne12); 1925 const int z_KV = (kbc - iter_k*iter_j*iter_z_gqa*ne12 * sequence)/(iter_k*iter_j*iter_z_gqa); 1926 const int zt_gqa = (kbc - iter_k*iter_j*iter_z_gqa*ne12 * sequence - iter_k*iter_j*iter_z_gqa * z_KV)/(iter_k*iter_j); 1927 const int jt = (kbc - iter_k*iter_j*iter_z_gqa*ne12 * sequence - iter_k*iter_j*iter_z_gqa * z_KV - iter_k*iter_j * zt_gqa) / iter_k; 1928 1929 const int zt_Q = z_KV*gqa_ratio + zt_gqa*ncols2; // Global Q head start index. 1930 1931 const float2 * Q_f2 = (const float2 *) (Q + nb03*sequence + nb02*zt_Q); 1932 const half2 * K_h2 = (const half2 *) (K + nb13*sequence + nb12*z_KV); 1933 const half * mask_h = ncols2 == 1 && !mask ? nullptr : 1934 (const half *) (mask + nb33*(sequence % ne33)); 1935 float2 * dstk = ((float2 *) dst) + (sequence*ne01.z*ne02 + zt_Q) * (DV/2); 1936 1937 const half2 * V_h2 = V_is_K_view ? K_h2 : (const half2 *) (V + nb23*sequence + nb22*z_KV); 1938 const float * sinks_f = sinks ? (const float *) sinks + zt_Q : nullptr; 1939 const int32_t * indices = use_sparse ? sparse_indices + (int64_t(sequence % ne33)*ne31 + jt*ncols1)*ne11 : nullptr; 1940 1941 const float slope = ncols2 == 1 ? get_alibi_slope(max_bias, zt_Q, n_head_log2, m0, m1) : 1.0f; 1942 1943 if (KV_max) { 1944 kb0_stop = min(kb0_stop, KV_max[sequence*iter_j + jt] / nbatch_fa); 1945 } 1946 1947 constexpr bool is_fixup = true; // Last index writes its data to fixup buffer to avoid data races with other blocks. 1948 constexpr bool needs_fixup = false; 1949 flash_attn_ext_f16_process_tile<DKQ, DV, ncols1, ncols2, nwarps, use_logit_softcap, V_is_K_view, use_sparse, needs_fixup, is_fixup> 1950 (Q_f2, K_h2, V_h2, mask_h, indices, sinks_f, dstk, dst_meta, scale, slope, logit_softcap, 1951 ne01, ne02, gqa_ratio, ne11, stride_Q1, stride_Q2, stride_K, stride_V, stride_mask, jt, zt_gqa, kb0_start, kb0_stop); 1952#else 1953 GGML_UNUSED_VARS(Q_ptr, K_ptr, V_ptr, mask_ptr, sinks_ptr, KV_max_ptr, dst_ptr, dst_meta_ptr, scale, 1954 max_bias, m0, m1, n_head_log2, logit_softcap, 1955 ne00, ne01, ne02, ne03, 1956 nb01, nb02, nb03, 1957 ne10, ne11, ne12, ne13, 1958 nb11, nb12, nb13, 1959 nb21, nb22, nb23, 1960 ne31, ne32, ne33, 1961 nb31, nb32, nb33); 1962 NO_DEVICE_CODE; 1963#endif // defined(FLASH_ATTN_AVAILABLE) && (defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE)) 1964} 1965 1966bool ggml_cuda_flash_attn_ext_mma_f16_shall_use_sparse(ggml_backend_cuda_context & ctx, ggml_tensor * dst); 1967 1968template <int DKQ, int DV, int ncols1, int ncols2> 1969void ggml_cuda_flash_attn_ext_mma_f16_case(ggml_backend_cuda_context & ctx, ggml_tensor * dst) { 1970 const ggml_tensor * KQV = dst; 1971 const int id = ggml_cuda_get_device(); 1972 const int cc = ggml_cuda_info().devices[id].cc; 1973 1974 constexpr int ncols = ncols1 * ncols2; 1975 1976 const int nthreads = ggml_cuda_fattn_mma_get_nthreads (DKQ, DV, ncols, cc); 1977 const int nbatch_fa = ggml_cuda_fattn_mma_get_nbatch_fa (DKQ, DV, ncols, cc); 1978 const int nbatch_K2 = ggml_cuda_fattn_mma_get_nbatch_K2 (DKQ, DV, ncols, cc); 1979 const int nbatch_V2 = ggml_cuda_fattn_mma_get_nbatch_V2 (DKQ, DV, ncols, cc); 1980 const int nbatch_combine = ggml_cuda_fattn_mma_get_nbatch_combine(DKQ, DV, ncols, cc); 1981 const bool Q_in_reg = ggml_cuda_fattn_mma_get_Q_in_reg (DKQ, DV, ncols, cc); 1982 const int nstages = ggml_cuda_fattn_mma_get_nstages (DKQ, DV, ncols1, ncols2, cc); 1983 1984 const int cols_per_warp = std::min(ncols, get_cols_per_warp(cc)); 1985 const int warp_size_host = ggml_cuda_info().devices[ctx.device].warp_size; 1986 const int nwarps = nthreads / warp_size_host; 1987 1988 constexpr bool V_is_K_view = DKQ == 576; // Guaranteed by the kernel selection logic in fattn.cu 1989 1990 // KV tile strides must match flash_attn_ext_f16_iter / _process_tile. 1991 const int stride_tile_K = ggml_cuda_fattn_smem_swizzle::tile_stride(nbatch_K2, cc); 1992 const int stride_tile_V = V_is_K_view ? stride_tile_K : ggml_cuda_fattn_smem_swizzle::tile_stride(nbatch_V2, cc); 1993 const size_t nbytes_shared_KV_1stage = nbatch_fa * std::max(stride_tile_K, stride_tile_V) * sizeof(half2); 1994 const size_t nbytes_shared_KV_2stage = nbatch_fa * (stride_tile_K + stride_tile_V) * sizeof(half2); 1995 const size_t nbytes_shared_Q = ncols * (DKQ/2 + 4) * sizeof(half2); 1996 const size_t nbytes_shared_mask = ncols1 * (nbatch_fa/2 + 4) * sizeof(half2); 1997 const size_t nbytes_shared_combine = nwarps*cols_per_warp * (nbatch_combine + 4) * sizeof(half2); 1998 1999 const size_t nbytes_shared_KV = nstages <= 1 ? nbytes_shared_KV_1stage : nbytes_shared_KV_2stage; 2000 2001 const size_t nbytes_shared_total = std::max(nbytes_shared_combine, Q_in_reg ? 2002 std::max(nbytes_shared_Q, nbytes_shared_KV + nbytes_shared_mask) : 2003 nbytes_shared_Q + nbytes_shared_KV + nbytes_shared_mask); 2004 2005 float logit_softcap; 2006 memcpy(&logit_softcap, (const float *) KQV->op_params + 2, sizeof(float)); 2007 2008#if defined(GGML_USE_HIP) 2009 using fattn_kernel_ptr_t = const void*; 2010#else 2011 using fattn_kernel_ptr_t = fattn_kernel_t; 2012#endif // defined(GGML_USE_HIP) 2013 fattn_kernel_t fattn_kernel; 2014 bool use_sparse = false; 2015 if (logit_softcap == 0.0f) { 2016 constexpr bool use_logit_softcap = false; 2017#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 2018 if constexpr (ggml_cuda_flash_attn_ext_mma_f16_may_use_sparse(DKQ, DV, ncols1, ncols2)) { 2019 if (ggml_cuda_flash_attn_ext_mma_f16_shall_use_sparse(ctx, dst)) { 2020 constexpr bool use_sparse_kernel = true; 2021 fattn_kernel = flash_attn_ext_f16<DKQ, DV, ncols1, ncols2, use_logit_softcap, V_is_K_view, use_sparse_kernel>; 2022 use_sparse = true; 2023 2024 static bool shared_memory_limit_raised[GGML_CUDA_MAX_DEVICES] = {false}; 2025 if (!shared_memory_limit_raised[id]) { 2026 CUDA_CHECK(cudaFuncSetAttribute(reinterpret_cast<fattn_kernel_ptr_t>(fattn_kernel), cudaFuncAttributeMaxDynamicSharedMemorySize, nbytes_shared_total)); 2027 shared_memory_limit_raised[id] = true; 2028 } 2029 } else { 2030 constexpr bool use_sparse_kernel = false; 2031 fattn_kernel = flash_attn_ext_f16<DKQ, DV, ncols1, ncols2, use_logit_softcap, V_is_K_view, use_sparse_kernel>; 2032 2033 static bool shared_memory_limit_raised[GGML_CUDA_MAX_DEVICES] = {false}; 2034 if (!shared_memory_limit_raised[id]) { 2035 CUDA_CHECK(cudaFuncSetAttribute(reinterpret_cast<fattn_kernel_ptr_t>(fattn_kernel), cudaFuncAttributeMaxDynamicSharedMemorySize, nbytes_shared_total)); 2036 shared_memory_limit_raised[id] = true; 2037 } 2038 } 2039 } else 2040#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 2041 { 2042 constexpr bool use_sparse_kernel = false; 2043 fattn_kernel = flash_attn_ext_f16<DKQ, DV, ncols1, ncols2, use_logit_softcap, V_is_K_view, use_sparse_kernel>; 2044 2045#if !defined(GGML_USE_MUSA) 2046 static bool shared_memory_limit_raised[GGML_CUDA_MAX_DEVICES] = {false}; 2047 if (!shared_memory_limit_raised[id]) { 2048 CUDA_CHECK(cudaFuncSetAttribute(reinterpret_cast<fattn_kernel_ptr_t>(fattn_kernel), cudaFuncAttributeMaxDynamicSharedMemorySize, nbytes_shared_total)); 2049 shared_memory_limit_raised[id] = true; 2050 } 2051#endif // !defined(GGML_USE_MUSA) 2052 } 2053 } else { 2054 constexpr bool use_logit_softcap = true; 2055 constexpr bool use_sparse_kernel = false; 2056 fattn_kernel = flash_attn_ext_f16<DKQ, DV, ncols1, ncols2, use_logit_softcap, V_is_K_view, use_sparse_kernel>; 2057 2058#if !defined(GGML_USE_MUSA) 2059 static bool shared_memory_limit_raised[GGML_CUDA_MAX_DEVICES] = {false}; 2060 if (!shared_memory_limit_raised[id]) { 2061 CUDA_CHECK(cudaFuncSetAttribute(reinterpret_cast<fattn_kernel_ptr_t>(fattn_kernel), cudaFuncAttributeMaxDynamicSharedMemorySize, nbytes_shared_total)); 2062 shared_memory_limit_raised[id] = true; 2063 } 2064#endif // !defined(GGML_USE_MUSA) 2065 } 2066 2067 launch_fattn<DV, ncols1, ncols2> 2068 (ctx, dst, fattn_kernel, nwarps, nbytes_shared_total, nbatch_fa, true, true, true, use_sparse, warp_size_host); 2069} 2070 2071 2072#define DECL_FATTN_MMA_F16_CASE(DKQ, DV, ncols1, ncols2) \ 2073 template void ggml_cuda_flash_attn_ext_mma_f16_case \ 2074 <DKQ, DV, ncols1, ncols2>(ggml_backend_cuda_context & ctx, ggml_tensor * dst) \ 2075 2076#define DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(DKQ, DV, ncols) \ 2077 extern DECL_FATTN_MMA_F16_CASE(DKQ, DV, (ncols)/ 1, 1); \ 2078 extern DECL_FATTN_MMA_F16_CASE(DKQ, DV, (ncols)/ 2, 2); \ 2079 extern DECL_FATTN_MMA_F16_CASE(DKQ, DV, (ncols)/ 4, 4); \ 2080 extern DECL_FATTN_MMA_F16_CASE(DKQ, DV, (ncols)/ 8, 8); \ 2081 extern DECL_FATTN_MMA_F16_CASE(DKQ, DV, (ncols)/16, 16); \ 2082 2083DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 64, 64, 8) 2084DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 80, 80, 8) 2085DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 96, 96, 8) 2086DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(112, 112, 8) 2087DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(128, 128, 8) 2088DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(256, 256, 8) 2089 2090DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 64, 64, 16) 2091DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 80, 80, 16) 2092DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 96, 96, 16) 2093DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(112, 112, 16) 2094DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(128, 128, 16) 2095DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(256, 256, 16) 2096 2097DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 64, 64, 32) 2098DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 80, 80, 32) 2099DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 96, 96, 32) 2100DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(112, 112, 32) 2101DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(128, 128, 32) 2102DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(256, 256, 32) 2103 2104DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 64, 64, 64) 2105DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 80, 80, 64) 2106DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2( 96, 96, 64) 2107DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(112, 112, 64) 2108DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(128, 128, 64) 2109DECL_FATTN_MMA_F16_CASE_ALL_NCOLS2(256, 256, 64) 2110 2111extern DECL_FATTN_MMA_F16_CASE(512, 512, 4, 2); 2112extern DECL_FATTN_MMA_F16_CASE(512, 512, 8, 2); 2113extern DECL_FATTN_MMA_F16_CASE(512, 512, 16, 2); 2114extern DECL_FATTN_MMA_F16_CASE(512, 512, 32, 2); 2115extern DECL_FATTN_MMA_F16_CASE(512, 512, 2, 4); 2116extern DECL_FATTN_MMA_F16_CASE(512, 512, 4, 4); 2117extern DECL_FATTN_MMA_F16_CASE(512, 512, 8, 4); 2118extern DECL_FATTN_MMA_F16_CASE(512, 512, 16, 4); 2119extern DECL_FATTN_MMA_F16_CASE(512, 512, 1, 8); 2120extern DECL_FATTN_MMA_F16_CASE(512, 512, 2, 8); 2121extern DECL_FATTN_MMA_F16_CASE(512, 512, 4, 8); 2122extern DECL_FATTN_MMA_F16_CASE(512, 512, 8, 8); 2123 2124// The number of viable configurations for Deepseek is very limited: 2125extern DECL_FATTN_MMA_F16_CASE(576, 512, 1, 16); 2126extern DECL_FATTN_MMA_F16_CASE(576, 512, 2, 16); 2127extern DECL_FATTN_MMA_F16_CASE(576, 512, 4, 16); 2128 2129// Mistral Small 4 (DKQ=320, DV=256), GQA=32-only build: 2130extern DECL_FATTN_MMA_F16_CASE(320, 256, 1, 32); 2131extern DECL_FATTN_MMA_F16_CASE(320, 256, 2, 32); 2132 2133// For GLM 4.7 Flash 2134extern DECL_FATTN_MMA_F16_CASE(576, 512, 4, 4); 2135extern DECL_FATTN_MMA_F16_CASE(576, 512, 8, 4); 2136extern DECL_FATTN_MMA_F16_CASE(576, 512, 16, 4); 2137extern DECL_FATTN_MMA_F16_CASE(576, 512, 1, 32); 2138extern DECL_FATTN_MMA_F16_CASE(576, 512, 2, 32);