Xenobd/whisper.cpp
0
1#include "whisper.h"2 3#include <emscripten.h>4#include <emscripten/bind.h>5 6#include <cmath>7#include <string>8#include <thread>9#include <vector>10 11constexpr int N_THREAD = 8;12 13// TODO: get rid of this vector of contexts - bad idea in the first place14std::vector<struct whisper_context *> g_contexts(4, nullptr);15 16std::thread g_worker;17 18void bench_main(size_t index) {19 const int n_threads = std::min(N_THREAD, (int) std::thread::hardware_concurrency());20 21 // whisper context22 auto & ctx = g_contexts[index];23 24 fprintf(stderr, "%s: running benchmark with %d threads - please wait...\n", __func__, n_threads);25 26 const int n_mels = whisper_model_n_mels(ctx);27 28 if (int ret = whisper_set_mel(ctx, nullptr, 0, n_mels)) {29 fprintf(stderr, "error: failed to set mel: %d\n", ret);30 return;31 }32 33 {34 fprintf(stderr, "\n");35 fprintf(stderr, "system_info: n_threads = %d / %d | %s\n", n_threads, std::thread::hardware_concurrency(), whisper_print_system_info());36 }37 38 if (int ret = whisper_encode(ctx, 0, n_threads) != 0) {39 fprintf(stderr, "error: failed to encode model: %d\n", ret);40 return;41 }42 43 whisper_print_timings(ctx);44 45 fprintf(stderr, "\n");46 fprintf(stderr, "If you wish, you can submit these results here:\n");47 fprintf(stderr, "\n");48 fprintf(stderr, " https://github.com/ggerganov/whisper.cpp/issues/89\n");49 fprintf(stderr, "\n");50 fprintf(stderr, "Please include the following information:\n");51 fprintf(stderr, "\n");52 fprintf(stderr, " - CPU model\n");53 fprintf(stderr, " - Operating system\n");54 fprintf(stderr, " - Browser\n");55 fprintf(stderr, "\n");56}57 58EMSCRIPTEN_BINDINGS(bench) {59 emscripten::function("init", emscripten::optional_override([](const std::string & path_model) {60 for (size_t i = 0; i < g_contexts.size(); ++i) {61 if (g_contexts[i] == nullptr) {62 g_contexts[i] = whisper_init_from_file_with_params(path_model.c_str(), whisper_context_default_params());63 if (g_contexts[i] != nullptr) {64 if (g_worker.joinable()) {65 g_worker.join();66 }67 g_worker = std::thread([i]() {68 bench_main(i);69 });70 71 return i + 1;72 } else {73 return (size_t) 0;74 }75 }76 }77 78 return (size_t) 0;79 }));80 81 emscripten::function("free", emscripten::optional_override([](size_t index) {82 if (index < g_contexts.size()) {83 whisper_free(g_contexts[index]);84 g_contexts[index] = nullptr;85 }86 }));87}88 