cmake_minimum_required(VERSION 3.26)
project(nemotron_browser LANGUAGES C CXX)
option(PAROLE_WEBGPU "Build the browser WebGPU variant" OFF)
set(EXCEPTION_FLAG -fexceptions)
if(PAROLE_WEBGPU)
  set(GGML_WEBGPU ON CACHE BOOL "" FORCE)
  set(GGML_WEBGPU_JSPI ON CACHE BOOL "" FORCE)
  set(EXCEPTION_FLAG -fwasm-exceptions)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -msimd128 -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -msimd128 -pthread ${EXCEPTION_FLAG}")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(GGML_NATIVE OFF CACHE BOOL "" FORCE)
set(GGML_OPENMP OFF CACHE BOOL "" FORCE)
set(GGML_CPU_AARCH64 OFF CACHE BOOL "" FORCE)
set(GGML_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GGML_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(SPM_ENABLE_SHARED OFF CACHE BOOL "" FORCE)
set(SPM_ENABLE_TCMALLOC OFF CACHE BOOL "" FORCE)
set(SPM_BUILD_TEST OFF CACHE BOOL "" FORCE)
add_subdirectory(sentencepiece-wasm EXCLUDE_FROM_ALL)
add_subdirectory(runtime/llama.cpp/ggml EXCLUDE_FROM_ALL)
add_subdirectory(runtime/src/common)
file(GLOB RUNTIME_SOURCES runtime/src/runtime/ggml/*.cpp)
file(GLOB ASR_SOURCES runtime/src/asr/*.cpp runtime/src/asr/features/*.cpp
  runtime/src/asr/encoder/*.cpp runtime/src/asr/decoders/*.cpp
  runtime/src/asr/vad/*.cpp runtime/src/asr/diar/*.cpp
  runtime/src/asr/postproc/*.cpp runtime/src/asr/pnc/*.cpp)
add_executable(nemotron ${RUNTIME_SOURCES} ${ASR_SOURCES} browser.cpp)
target_include_directories(nemotron PRIVATE runtime/include runtime/src/common
  runtime/src/runtime/ggml sentencepiece-wasm/src)
foreach(dir IN ITEMS "" features encoder decoders vad diar postproc pnc)
  target_include_directories(nemotron PRIVATE "runtime/src/asr/${dir}")
endforeach()
target_link_libraries(nemotron PRIVATE ggml nemo_speech_common sentencepiece-static)
set_target_properties(nemotron PROPERTIES SUFFIX ".js" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/web")
if(PAROLE_WEBGPU)
  set_target_properties(nemotron PROPERTIES OUTPUT_NAME "nemotron-webgpu")
  target_link_options(nemotron PRIVATE "-sJSPI=1" "-sJSPI_EXPORTS=['load_model','start_stream','push_audio','finish_stream','refine_audio']")
endif()
target_link_options(nemotron PRIVATE -O3 -pthread ${EXCEPTION_FLAG}
  "-sMODULARIZE=1" "-sEXPORT_NAME=createNemotron" "-sENVIRONMENT=web,worker"
  "-sINCOMING_MODULE_JS_API=['mainScriptUrlOrBlob','print','printErr','onAbort']"
  "-sALLOW_MEMORY_GROWTH=1" "-sMAXIMUM_MEMORY=4294967296" "-sINITIAL_MEMORY=1073741824"
  "-sPTHREAD_POOL_SIZE=16" "-sSTACK_SIZE=8388608" "-sFILESYSTEM=1" "-sFORCE_FILESYSTEM=1"
  "-sEXPORTED_RUNTIME_METHODS=['FS','ccall','UTF8ToString','HEAPF32']"
  "-sEXPORTED_FUNCTIONS=['_malloc','_free','_load_model','_configure_vocabulary','_start_stream','_push_audio','_finish_stream','_refine_audio','_refined_text','_last_error']")
if(PAROLE_WEBGPU)
  target_link_options(nemotron PRIVATE -O2)
endif()
