#pragma once
#include "ggml.h"
#include "weights.h"
#include <vector>
struct ggml_context;
struct ggml_cgraph;
struct ggml_tensor;
namespace transcribe::qwen3_asr {
struct EncoderTiming {
int32_t n_mel_frames = 0; int32_t mel_per_chunk = 0; int32_t n_chunks = 0; int32_t last_chunk_real_mel = 0; int32_t per_chunk_aftercnn = 0; int32_t last_chunk_aftercnn = 0; int32_t T_enc_padded = 0; int32_t T_enc = 0; int32_t aftercnn_lens_total = 0; };
int32_t aftercnn_len(int32_t mel_len);
EncoderTiming compute_encoder_timing(int32_t n_mel_frames, const QwenAsrHParams & hp);
std::vector<float> build_sinusoid_pe(int32_t d_model, int32_t length, double max_timescale = 10000.0);
constexpr int kConvChunkGroup = 16;
constexpr int kConvPassChunks = 512;
struct SubsampleBuild {
ggml_tensor * mel_in = nullptr; ggml_tensor * out = nullptr; ggml_cgraph * graph = nullptr;
};
SubsampleBuild build_subsample_graph(ggml_context * ctx,
const QwenAsrWeights & weights,
const QwenAsrHParams & hp,
int n_chunks);
struct EncoderDumps {
ggml_tensor * subsample_out = nullptr; ggml_tensor * pos_add_out = nullptr; ggml_tensor * block_0_out = nullptr;
ggml_tensor * block_last_out = nullptr;
ggml_tensor * ln_post_out = nullptr;
ggml_tensor * proj_out = nullptr;
};
struct EncoderBuild {
ggml_tensor * subsample_in = nullptr; ggml_tensor * pos_emb_in = nullptr; ggml_tensor * out = nullptr; EncoderDumps dumps{};
ggml_cgraph * graph = nullptr;
EncoderTiming timing{};
};
EncoderBuild build_encoder_graph(ggml_context * ctx,
const QwenAsrWeights & weights,
const QwenAsrHParams & hp,
const EncoderTiming & timing,
bool use_flash = false);
struct EncoderBuildBatched {
ggml_tensor * subsample_in = nullptr; ggml_tensor * pos_emb_in = nullptr; ggml_tensor * mask_in = nullptr; ggml_tensor * out = nullptr; ggml_cgraph * graph = nullptr;
int n_batch = 0;
int n_chunks_max = 0;
int T_per_chunk = 0;
int T_pad_max = 0; };
EncoderBuildBatched build_encoder_graph_batched(ggml_context * ctx,
const QwenAsrWeights & weights,
const QwenAsrHParams & hp,
int n_chunks_max,
int n_batch,
bool use_flash = false);
}