#include <stdio.h>
#include <math.h>
#include <cuda_runtime.h>
#define BLOCK_SIZE 32
#define HEAD_DIM 64
__global__ void standard_attention(
const float* Q, const float* K, const float* V,
float* O, int seq_len, int head_dim
) {
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if (row < seq_len && col < seq_len) {
float sum = 0.0f;
for (int i = 0; i < head_dim; i++) {
sum += Q[row * head_dim + i] * K[col * head_dim + i];
}
sum /= sqrt(head_dim);
float score = expf(sum);
float out = 0.0f;
for (int i = 0; i < head_dim; i++) {
out += score * V[row * head_dim + i];
}
O[row * head_dim + col] = out;
}
}
__global__ void flash_attention_kernel(
const float* Q, const float* K, const float* V,
float* O, int seq_len, int head_dim
) {
extern __shared__ float smem[];
float* q_tile = smem;
float* k_tile = q_tile + BLOCK_SIZE * head_dim;
float* v_tile = k_tile + BLOCK_SIZE * head_dim;
int row = blockIdx.y * blockDim.y + threadIdx.y;
float m_prev = -INFINITY;
float l_prev = 0.0f;
float o_acc[HEAD_DIM] = {0};
for (int t = 0; t < seq_len; t += BLOCK_SIZE) {
float s_local = 0.0f;
for (int i = 0; i < head_dim; i++) {
s_local += q_tile[threadIdx.x * head_dim + i] *
k_tile[threadIdx.y * head_dim + i];
}
s_local /= sqrt(head_dim);
float m_new = fmaxf(m_prev, s_local);
float l_new = l_prev * expf(m_prev - m_new) + expf(s_local - m_new);
for (int i = 0; i < head_dim; i++) {
o_acc[i] = o_acc[i] * (l_prev * expf(m_prev - m_new) / l_new) +
expf(s_local - m_new) * v_tile[threadIdx.y * head_dim + i] / l_new;
}
m_prev = m_new;
l_prev = l_new;
}
for (int i = 0; i < head_dim; i++) {
O[row * head_dim + i] = o_acc[i];
}
}
int main() {
const int seq_len = 4096;
const int head_dim = 64;
printf("FlashAttention演示: seq_len=%d, head_dim=%d\n", seq_len, head_dim);
printf("标准Attention内存: %.2f MB\n",
4.0 * seq_len * seq_len * head_dim / 1024 / 1024);
printf("FlashAttention内存: %.2f MB\n",
4.0 * seq_len * head_dim * 4 / 1024 / 1024);
return 0;
}