diff --git a/CMakeLists.txt b/CMakeLists.txt index a2e2c91d..dfbfa2b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,8 +38,13 @@ if (EMSCRIPTEN) # TODO: without these, we get the following error: # wasm-ld: error: --shared-memory is disallowed by whisper.cpp.o because it was not compiled with 'atomics' or 'bulk-memory' features. - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -s TOTAL_STACK=5242880") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -s TOTAL_STACK=5242880") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_STACK=5242880") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s TOTAL_STACK=5242880") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated") else() if (MINGW) set(BUILD_SHARED_LIBS_DEFAULT OFF) diff --git a/examples/command.wasm/README.md b/examples/command.wasm/README.md index d317f3a9..fb83c93b 100644 --- a/examples/command.wasm/README.md +++ b/examples/command.wasm/README.md @@ -15,9 +15,18 @@ git clone https://github.com/ggerganov/whisper.cpp cd whisper.cpp mkdir build-em && cd build-em emcmake cmake .. -make -j +make -j libcommand +``` +The example can then be started by running a local HTTP server: +```console +python3 examples/server.py +``` +And then opening a browser to the following URL: +http://localhost:8000/command.wasm/ -# copy the produced page to your HTTP path +To run the example in a different server, you need to copy the following files +to the server's HTTP path: +``` cp bin/command.wasm/* /path/to/html/ cp bin/libcommand.worker.js /path/to/html/ ``` diff --git a/examples/common.cpp b/examples/common.cpp index f40bcf6d..d23709d2 100644 --- a/examples/common.cpp +++ b/examples/common.cpp @@ -247,17 +247,6 @@ std::map json_parse(const std::string & fname) { return result; } -std::string convert_to_utf8(const std::wstring & input) { - std::wstring_convert> converter; - return converter.to_bytes(input); -} - - -std::wstring convert_to_wstring(const std::string & input) { - std::wstring_convert> converter; - return converter.from_bytes(input); -} - void gpt_split_words(std::string str, std::vector& words) { const std::string pattern = R"('s|'t|'re|'ve|'m|'ll|'d| ?[[:alpha:]]+| ?[[:digit:]]+| ?[^\s[:alpha:][:digit:]]+|\s+(?!\S)|\s+)"; const std::regex re(pattern); diff --git a/examples/server.py b/examples/server.py new file mode 100644 index 00000000..537e2946 --- /dev/null +++ b/examples/server.py @@ -0,0 +1,27 @@ +import http.server +import socketserver +import os +from pathlib import Path + +SCRIPT_DIR = Path(__file__).parent.absolute() +DIRECTORY = os.path.join(SCRIPT_DIR, "../build-em/bin") +DIRECTORY = os.path.abspath(DIRECTORY) + +class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=DIRECTORY, **kwargs) + + def end_headers(self): + # Add required headers for SharedArrayBuffer + self.send_header("Cross-Origin-Opener-Policy", "same-origin") + self.send_header("Cross-Origin-Embedder-Policy", "require-corp") + super().end_headers() + +PORT = 8000 + +with socketserver.TCPServer(("", PORT), CustomHTTPRequestHandler) as httpd: + print(f"Serving directory '{DIRECTORY}' at http://localhost:{PORT}") + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\nServer stopped.") diff --git a/ggml/src/ggml-cpu/ggml-cpu.c b/ggml/src/ggml-cpu/ggml-cpu.c index f2ab4c5d..6fc5d42f 100644 --- a/ggml/src/ggml-cpu/ggml-cpu.c +++ b/ggml/src/ggml-cpu/ggml-cpu.c @@ -901,24 +901,24 @@ inline static void __wasm_f16x4_store(ggml_fp16_t * p, v128_t x) { #define GGML_F16x4_FMA GGML_F32x4_FMA #define GGML_F16x4_ADD wasm_f32x4_add #define GGML_F16x4_MUL wasm_f32x4_mul -#define GGML_F16x4_REDUCE(res, x) \ -{ \ - int offset = GGML_F16_ARR >> 1; \ - for (int i = 0; i < offset; ++i) { \ - x[i] = wasm_f32x4_add(x[i], x[offset+i]); \ - } \ - offset >>= 1; \ - for (int i = 0; i < offset; ++i) { \ - x[i] = wasm_f32x4_add(x[i], x[offset+i]); \ - } \ - offset >>= 1; \ - for (int i = 0; i < offset; ++i) { \ - x[i] = wasm_f32x4_add(x[i], x[offset+i]); \ - } \ - res = wasm_f32x4_extract_lane(x[0], 0) + \ - wasm_f32x4_extract_lane(x[0], 1) + \ - wasm_f32x4_extract_lane(x[0], 2) + \ - wasm_f32x4_extract_lane(x[0], 3); \ +#define GGML_F16x4_REDUCE(res, x) \ +{ \ + int offset = GGML_F16_ARR >> 1; \ + for (int i = 0; i < offset; ++i) { \ + x[i] = wasm_f32x4_add(x[i], x[offset+i]); \ + } \ + offset >>= 1; \ + for (int i = 0; i < offset; ++i) { \ + x[i] = wasm_f32x4_add(x[i], x[offset+i]); \ + } \ + offset >>= 1; \ + for (int i = 0; i < offset; ++i) { \ + x[i] = wasm_f32x4_add(x[i], x[offset+i]); \ + } \ + res = (ggml_float) (wasm_f32x4_extract_lane(x[0], 0) + \ + wasm_f32x4_extract_lane(x[0], 1) + \ + wasm_f32x4_extract_lane(x[0], 2) + \ + wasm_f32x4_extract_lane(x[0], 3)); \ } #define GGML_F16_VEC GGML_F16x4