#pragma once
#include <vector>
struct ggml_context;
struct ggml_tensor;
namespace transcribe::sanm {
constexpr float kLayerNormEps = 1e-12f;
struct SanmBlockView {
ggml_tensor * norm_attn_w = nullptr;
ggml_tensor * norm_attn_b = nullptr;
ggml_tensor * attn_qkv_w = nullptr;
ggml_tensor * attn_qkv_b = nullptr;
ggml_tensor * attn_out_w = nullptr;
ggml_tensor * attn_out_b = nullptr;
ggml_tensor * attn_fsmn_w = nullptr;
ggml_tensor * norm_ffn_w = nullptr;
ggml_tensor * norm_ffn_b = nullptr;
ggml_tensor * ffn_fc1_w = nullptr;
ggml_tensor * ffn_fc1_b = nullptr;
ggml_tensor * ffn_fc2_w = nullptr;
ggml_tensor * ffn_fc2_b = nullptr;
};
struct SanmBlockParams {
int n_heads = 0;
int d_model = 0;
int kernel = 0;
ggml_tensor * attn_pad_mask = nullptr;
ggml_tensor * conv_pad_mask = nullptr;
bool use_flash = true;
};
ggml_tensor * sv_layer_norm(ggml_context * ctx, ggml_tensor * x, ggml_tensor * gamma, ggml_tensor * beta);
ggml_tensor * fsmn_branch(ggml_context * ctx,
ggml_tensor * v_pre,
ggml_tensor * fsmn_w,
int kernel,
ggml_tensor * conv_pad_mask = nullptr);
ggml_tensor * sanm_attention(ggml_context * ctx, ggml_tensor * x, const SanmBlockView & b, const SanmBlockParams & p);
ggml_tensor * sanm_ffn(ggml_context * ctx, ggml_tensor * x, const SanmBlockView & b);
ggml_tensor * sanm_block_residual(ggml_context * ctx,
ggml_tensor * x,
const SanmBlockView & b,
const SanmBlockParams & p);
ggml_tensor * sanm_block_projection(ggml_context * ctx,
ggml_tensor * x,
const SanmBlockView & b,
const SanmBlockParams & p);
void build_sinusoidal_pe(std::vector<float> & out, int depth, int T);
}