From a87fe99d65ca53ddb21636f9a204598eaa64377c Mon Sep 17 00:00:00 2001 From: Yan Xia Date: Fri, 24 Jul 2026 14:51:20 +0800 Subject: [PATCH] Fix Windows/MinGW build and inference Three portability issues prevented building and running on Windows with MinGW GCC: - clock_gettime/CLOCK_MONOTONIC/struct timespec are POSIX-only and absent under MinGW. Add include/time_compat.h, a std::chrono-based shim that is a no-op on platforms that already provide clock_gettime. - llama.cpp aborts model load with "PrefetchVirtualMemory unavailable" on MinGW builds. Disable mmap (use_mmap = false) for LM loading on _WIN32. - The VAE compute context reserves 128 GB, which relies on Linux memory overcommit and fails outright on Windows. Cap the reservation at 6 GB on _WIN32, which is ample for the intermediate tensors. Verified end-to-end: builds with MinGW GCC 13.2 (Ninja) and transcribes correctly on CPU. Co-Authored-By: Claude --- demo/asr_infer.cpp | 5 +++++ include/time_compat.h | 30 ++++++++++++++++++++++++++++++ src/asr_server.cpp | 5 +++++ src/vae.cpp | 11 ++++++++++- 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 include/time_compat.h diff --git a/demo/asr_infer.cpp b/demo/asr_infer.cpp index 8285e56..3f4dcdc 100644 --- a/demo/asr_infer.cpp +++ b/demo/asr_infer.cpp @@ -15,6 +15,8 @@ #include "../utils/audio_io.h" #include "../utils/prompt_builder.h" +#include "time_compat.h" + #include #include #include @@ -220,6 +222,9 @@ int main(int argc, char ** argv) { llama_model_params lm_mparams = llama_model_default_params(); lm_mparams.n_gpu_layers = 0; // CPU only +#ifdef _WIN32 + lm_mparams.use_mmap = false; // MinGW/Windows lacks PrefetchVirtualMemory; mmap load fails +#endif llama_model * lm_model = llama_load_model_from_file(params.lm_model_path.c_str(), lm_mparams); if (!lm_model) { diff --git a/include/time_compat.h b/include/time_compat.h new file mode 100644 index 0000000..6a87617 --- /dev/null +++ b/include/time_compat.h @@ -0,0 +1,30 @@ +// Portability shim: provide clock_gettime(CLOCK_MONOTONIC, ...) on platforms +// (e.g. MinGW/Windows) where it is not available. No-op on POSIX systems that +// already provide it. +#ifndef VIBEASR_TIME_COMPAT_H +#define VIBEASR_TIME_COMPAT_H + +#include + +#if defined(_WIN32) && !defined(CLOCK_MONOTONIC) + +#include + +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC 1 +#endif + +static inline int vibeasr_clock_gettime(int /*clk_id*/, struct timespec *ts) { + const auto now = std::chrono::steady_clock::now().time_since_epoch(); + const auto secs = std::chrono::duration_cast(now); + const auto nsecs = std::chrono::duration_cast(now - secs); + ts->tv_sec = static_cast(secs.count()); + ts->tv_nsec = static_cast(nsecs.count()); + return 0; +} + +#define clock_gettime(clk, ts) vibeasr_clock_gettime((clk), (ts)) + +#endif // _WIN32 && !CLOCK_MONOTONIC + +#endif // VIBEASR_TIME_COMPAT_H diff --git a/src/asr_server.cpp b/src/asr_server.cpp index 1b7cf86..0e19ae6 100644 --- a/src/asr_server.cpp +++ b/src/asr_server.cpp @@ -17,6 +17,8 @@ #include "../utils/audio_io.h" #include "../utils/prompt_builder.h" +#include "time_compat.h" + #include #include #include @@ -363,6 +365,9 @@ int main(int argc, char ** argv) { llama_model_params lm_mparams = llama_model_default_params(); lm_mparams.n_gpu_layers = 0; +#ifdef _WIN32 + lm_mparams.use_mmap = false; // MinGW/Windows lacks PrefetchVirtualMemory; mmap load fails +#endif llama_model * lm_model = llama_load_model_from_file(params.lm_model_path.c_str(), lm_mparams); if (!lm_model) { diff --git a/src/vae.cpp b/src/vae.cpp index 91d7373..a89307b 100644 --- a/src/vae.cpp +++ b/src/vae.cpp @@ -5,6 +5,8 @@ #include "ggml-backend.h" #include "ggml-vae-i8_s-mad.h" +#include "time_compat.h" + #include #include #include @@ -646,8 +648,15 @@ static int32_t vae_encode_impl( // Create computation context with sufficient memory // F32 models need more memory than I8_S due to 4x larger intermediate tensors +#ifdef _WIN32 + // Windows has no memory overcommit: a 128 GB reservation fails outright. + // 6 GB is ample for the VAE intermediate tensors at typical audio lengths. + const size_t vae_ctx_mem_size = (size_t)6 * 1024 * 1024 * 1024; +#else + const size_t vae_ctx_mem_size = (size_t)128 * 1024 * 1024 * 1024; +#endif struct ggml_init_params ctx_params = { - /*.mem_size =*/ (size_t)128 * 1024 * 1024 * 1024, + /*.mem_size =*/ vae_ctx_mem_size, /*.mem_buffer =*/ nullptr, /*.no_alloc =*/ false, // Let ggml allocate tensors };