diff --git a/cortex-cpp/CMakeLists.txt b/cortex-cpp/CMakeLists.txt index c3f90525a..2c97baea5 100644 --- a/cortex-cpp/CMakeLists.txt +++ b/cortex-cpp/CMakeLists.txt @@ -1,6 +1,13 @@ cmake_minimum_required(VERSION 3.5) +cmake_policy(SET CMP0091 NEW) +cmake_policy(SET CMP0042 NEW) project(cortex-cpp C CXX) +# Build using CMAKE-JS +if(DEFINED CMAKE_JS_INC) + include_directories(${CMAKE_JS_INC}) +endif() + include(engines/cortex.llamacpp/engine.cmake) include(CheckIncludeFileCXX) @@ -54,6 +61,11 @@ if(APPLE) endif() endif() +if(DEFINED CMAKE_JS_INC) + # define NPI_VERSION + add_compile_definitions(NAPI_VERSION=8) +endif() + add_compile_definitions(CORTEX_CPP_VERSION="${CORTEX_CPP_VERSION}") if(LLAMA_CUDA) @@ -74,10 +86,22 @@ endif() add_subdirectory(test) -add_executable(${PROJECT_NAME} main.cc - ${CMAKE_CURRENT_SOURCE_DIR}/utils/cpuid/cpu_info.cc - ${CMAKE_CURRENT_SOURCE_DIR}/utils/cpuid/cpu_validation.cc -) +# Build using CMAKE-JS +if(DEFINED CMAKE_JS_INC) + if(("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + endif() + + add_library(${PROJECT_NAME} SHARED addon.cc + ${CMAKE_CURRENT_SOURCE_DIR}/utils/cpuid/cpu_info.cc + ${CMAKE_CURRENT_SOURCE_DIR}/utils/cpuid/cpu_validation.cc + ) +else() # Official build + add_executable(${PROJECT_NAME} main.cc + ${CMAKE_CURRENT_SOURCE_DIR}/utils/cpuid/cpu_info.cc + ${CMAKE_CURRENT_SOURCE_DIR}/utils/cpuid/cpu_validation.cc + ) +endif() # ############################################################################## # If you include the drogon source code locally in your project, use this method @@ -121,4 +145,16 @@ target_sources(${PROJECT_NAME} PRIVATE ${CTL_SRC} ${COMMON_SRC}) # ${FILTER_SRC} ${PLUGIN_SRC} ${MODEL_SRC}) # ############################################################################## # uncomment the following line for dynamically loading views set_property(TARGET -# ${PROJECT_NAME} PROPERTY ENABLE_EXPORTS ON) \ No newline at end of file +# ${PROJECT_NAME} PROPERTY ENABLE_EXPORTS ON) + +# Build using CMAKE-JS +if(DEFINED CMAKE_JS_INC) + set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node") + + target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB}) + + if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET) + # Generate node.lib + execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS}) + endif() +endif() \ No newline at end of file diff --git a/cortex-cpp/addon.cc b/cortex-cpp/addon.cc new file mode 100644 index 000000000..5a06e62c4 --- /dev/null +++ b/cortex-cpp/addon.cc @@ -0,0 +1,82 @@ +#include + +#include +#include +#include // for PATH_MAX +#include +#include "cortex-common/cortexpythoni.h" +#include "utils/cortex_utils.h" +#include "utils/dylib.h" + +#if defined(__APPLE__) && defined(__MACH__) +#include // for dirname() +#include +#elif defined(__linux__) +#include // for dirname() +#include // for readlink() +#elif defined(_WIN32) +#include +#undef max +#else +#error "Unsupported platform!" +#endif + +void start() { + int thread_num = 1; + std::string host = "127.0.0.1"; + int port = 3929; + std::string uploads_folder_path; + + int logical_cores = std::thread::hardware_concurrency(); + int drogon_thread_num = std::max(thread_num, logical_cores); + // cortex_utils::nitro_logo(); +#ifdef CORTEX_CPP_VERSION + LOG_INFO << "cortex-cpp version: " << CORTEX_CPP_VERSION; +#else + LOG_INFO << "cortex-cpp version: undefined"; +#endif +#ifdef CORTEX_LLAMACPP_VERSION + LOG_INFO << "cortex.llamacpp version: " << CORTEX_LLAMACPP_VERSION; +#endif + + LOG_INFO << "Server started, listening at: " << host << ":" << port; + LOG_INFO << "Please load your model"; + drogon::app().addListener(host, port); + drogon::app().setThreadNum(drogon_thread_num); + if (!uploads_folder_path.empty()) { + LOG_INFO << "Drogon uploads folder is at: " << uploads_folder_path; + drogon::app().setUploadPath(uploads_folder_path); + } + LOG_INFO << "Number of thread is:" << drogon::app().getThreadNum(); + + drogon::app().run(); +} + +void stop() { + drogon::app().quit(); +} + +Napi::Value Start(const Napi::CallbackInfo &info) +{ + Napi::Env env = info.Env(); + start(); + return Napi::String::New(env, "Server started successfully"); +} + +Napi::Value Stop(const Napi::CallbackInfo &info) +{ + Napi::Env env = info.Env(); + stop(); + return Napi::String::New(env, "Server stopped successfully"); +} + +Napi::Object Init(Napi::Env env, Napi::Object exports) +{ + exports.Set(Napi::String::New(env, "start"), + Napi::Function::New(env, Start)); + exports.Set(Napi::String::New(env, "stop"), + Napi::Function::New(env, Start)); + return exports; +} + +NODE_API_MODULE(cortex-cpp, Init) \ No newline at end of file diff --git a/cortex-cpp/index.js b/cortex-cpp/index.js new file mode 100644 index 000000000..ac3d61aaa --- /dev/null +++ b/cortex-cpp/index.js @@ -0,0 +1,7 @@ +const addon = require("./build/Release/cortex-cpp.node"); + +console.log(addon); + +console.log(addon.start()); + +console.log(addon.stop()); \ No newline at end of file diff --git a/cortex-cpp/package.json b/cortex-cpp/package.json new file mode 100644 index 000000000..4491df249 --- /dev/null +++ b/cortex-cpp/package.json @@ -0,0 +1,43 @@ +{ + "name": "cortex-cpp", + "version": "0.0.11", + "description": "Cortex-cpp is a streamlined, stateless C++ server engineered to be fully compatible with OpenAI's API, particularly its stateless functionalities", + "main": "./index.js", + "types": "./index.d.ts", + "repository": { + "type": "git", + "url": "git+https://github.com/janhq/cortex.git" + }, + "scripts": { + "install": "prebuild-install --runtime napi --backend cmake-js || cmake-js rebuild", + "build": "cmake-js configure && cmake-js build", + "rebuild": "cmake-js rebuild", + "prebuild": "prebuild --runtime napi --backend cmake-js --all --strip --verbose", + "upload": "prebuild --runtime napi --backend cmake-js --upload ${GITHUB_TOKEN}" + }, + "author": "louis", + "license": "Apache-2.0", + "gypfile": true, + "dependencies": { + "bindings": "^1.5.0", + "cmake-js": "^7.3.0", + "node-addon-api": "^7.0.0" + }, + "devDependencies": { + "@types/node": "^20.14.9", + "typescript": "^5.5.3" + }, + "binary": { + "napi_versions": [ + 8 + ] + }, + "files": [ + "binding.gyp", + "deps/", + "*.js", + "*.d.ts", + "src/", + "prebuilds/" + ] +}