#pragma once
#include "ggml.h"
#include "weights.h"
#include <cstdint>
#include <vector>
struct ggml_context;
struct ggml_tensor;
struct ggml_cgraph;
namespace transcribe {
class MelFrontend;
}
namespace transcribe::granite_nar {
transcribe_status compute_mel_encoder_input(const transcribe::MelFrontend & mel,
const float * pcm,
int n_samples,
int n_threads,
std::vector<float> & out_mel,
int & out_t_enc);
struct EncoderBuild {
ggml_tensor * mel_in = nullptr; ggml_tensor * pos_rows = nullptr; ggml_tensor * last_block_mask = nullptr; ggml_tensor * zero_pad = nullptr;
ggml_tensor * cat_out = nullptr; ggml_tensor * ctc_logits = nullptr; ggml_tensor * mid_blank_probs = nullptr; std::vector<ggml_tensor *> bpe_window_ids; ggml_tensor * bpe_window_mass = nullptr; int n_bpe_windows = 0;
ggml_cgraph * graph = nullptr;
struct Dumps {
ggml_tensor * input_linear_out = nullptr;
ggml_tensor * block_0_out = nullptr;
ggml_tensor * block_mid_pre = nullptr; ggml_tensor * block_mid_post = nullptr; ggml_tensor * block_last_out = nullptr; ggml_tensor * ctc_logits = nullptr; ggml_tensor * block_0_post_ff1 = nullptr;
ggml_tensor * block_0_post_attn = nullptr;
ggml_tensor * block_0_post_conv = nullptr;
ggml_tensor * block_0_post_ff2 = nullptr;
} dumps;
int n_blocks_local = 0;
int last_block_rem = 0;
};
EncoderBuild build_encoder_graph(ggml_context * ctx,
const GraniteNarWeights & weights,
const GraniteNarHParams & hp,
int T_enc,
bool use_flash);
std::vector<int32_t> precompute_pos_rows(int context_size, int max_pos_emb);
std::vector<float> precompute_last_block_mask(int context_size, int t_enc_remainder);
constexpr int kBpeTileWindows = 256;
bool collapse_bpe_window_ids(const std::vector<int32_t> & window_ids,
const std::vector<float> & window_mass,
int blank_id,
std::vector<int32_t> & out_token_ids);
void compute_bpe_ctc_initial_hypothesis(const std::vector<float> & importance_non_blank,
const std::vector<float> & ctc_bpe_logits,
int n_bpe_vocab,
int T_enc,
int pool_window,
int blank_id,
std::vector<int32_t> & out_token_ids);
}