diff --git a/include/whisper.h b/include/whisper.h index 1e1375033ad..7d0fc6f15e8 100644 --- a/include/whisper.h +++ b/include/whisper.h @@ -668,6 +668,17 @@ extern "C" { // Get the no_speech probability for the specified segment WHISPER_API float whisper_full_get_segment_no_speech_prob (struct whisper_context * ctx, int i_segment); WHISPER_API float whisper_full_get_segment_no_speech_prob_from_state(struct whisper_state * state, int i_segment); + + // Return System Information formatted as a JSON string + WHISPER_API const char * whisper_get_system_info_json(void); + + // Returns whisper_state for a supplied whisper_context pointer + WHISPER_API struct whisper_state * whisper_get_state_from_context(struct whisper_context * ctx); + + // A version of whisper_get_timings that takes state as a parameter + WHISPER_API struct whisper_timings * whisper_get_timings_with_state(struct whisper_state * state); + + #ifdef __cplusplus } #endif diff --git a/src/openvino/whisper-openvino-encoder.cpp b/src/openvino/whisper-openvino-encoder.cpp index 4d9ce122858..12cfe1f5594 100644 --- a/src/openvino/whisper-openvino-encoder.cpp +++ b/src/openvino/whisper-openvino-encoder.cpp @@ -19,7 +19,7 @@ struct whisper_openvino_context * whisper_openvino_init(const char* path_model, fprintf(stderr, "%s: path_model = %s, device = %s, cache_dir = %s\n", __func__, path_model, device, cache_dir ? cache_dir : "(not set)"); - whisper_openvino_context *context = new whisper_openvino_context; + whisper_openvino_context *context = new whisper_openvino_context; try { ov::Core core; diff --git a/src/whisper.cpp b/src/whisper.cpp index 956d312dd3c..f2117de40e5 100644 --- a/src/whisper.cpp +++ b/src/whisper.cpp @@ -7548,3 +7548,79 @@ static void whisper_log_callback_default(ggml_log_level level, const char * text fputs(text, stderr); fflush(stderr); } + +// whisper_get_system_info_json +// Returns system info as json, useful for language bindings +// NOTE : While testing features->value always returned an int. +// Even though ints are invariably returned they may be +// some values that return other types. +// This function returns everything quoted (i.e. as a string) +// and leaves type-casting to the caller. +// This also removes the unlikely but plausible state of +// a string being returned unquoted (thus invalidating JSON) + +const char * whisper_get_system_info_json(void) { + static std::string s; + + whisper_load_backends(); + + s = "{"; + s += "\"WHISPER\":{"; + s += "\"COREML\":\"" + std::to_string(whisper_has_coreml()) + "\","; + s += "\"OPENVINO\":\"" + std::to_string(whisper_has_openvino()) + "\"}"; + + for (size_t i = 0; i < ggml_backend_reg_count(); i++) { + auto * reg = ggml_backend_reg_get(i); + auto * get_features_fn = (ggml_backend_get_features_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_get_features"); + if (get_features_fn) { + ggml_backend_feature * features = get_features_fn(reg); + s += ",\""; + s += ggml_backend_reg_name(reg); + s += "\":{"; + auto first = true; + for (; features->name; features++) { + if(first) { + first = false; + } else { + s += ","; + } + s += "\""; + s += features->name; + s += "\":\""; + s += features->value; + s += "\""; + } + s += "}"; + } + } + s += "}"; + + return s.c_str(); +} + +// whisper_get_state_from_context +// Returns state from supplied context pointer +// This is mainly a helper for non-C++ language bindings as whisper_context +// has embedded C++ specific types (e.g. maps and vectors) +struct whisper_state * whisper_get_state_from_context(struct whisper_context * ctx) { + if (!ctx->state) { + return nullptr; + } + + return ctx->state; +} + +// whisper_get_timings_with_state +// Just a version of whisper_get_timings that takes state as a parameter +struct whisper_timings * whisper_get_timings_with_state(struct whisper_state * state) { + if (state == nullptr) { + return nullptr; + } + whisper_timings * timings = new whisper_timings; + timings->sample_ms = 1e-3f * state->t_sample_us / std::max(1, state->n_sample); + timings->encode_ms = 1e-3f * state->t_encode_us / std::max(1, state->n_encode); + timings->decode_ms = 1e-3f * state->t_decode_us / std::max(1, state->n_decode); + timings->batchd_ms = 1e-3f * state->t_batchd_us / std::max(1, state->n_batchd); + timings->prompt_ms = 1e-3f * state->t_prompt_us / std::max(1, state->n_prompt); + return timings; +}