diff --git a/frameworks/native/BUILD.gn b/frameworks/native/BUILD.gn index ac8de4c83fc0beaf3d1e5ecc7f128a2593d3d84e..456fc9432ad7d118f99f58367b2c423635847d19 100644 --- a/frameworks/native/BUILD.gn +++ b/frameworks/native/BUILD.gn @@ -28,6 +28,7 @@ ohos_shared_library("qos_ndk") { "-Os", ] include_dirs = [ + "../../include/", "../../interfaces/", "../../interfaces/kits/c/", ] @@ -36,6 +37,10 @@ ohos_shared_library("qos_ndk") { deps = [ "../../qos:qos" ] + external_deps = [ + "hilog:libhilog" + ] + output_name = "qos" output_extension = "so" diff --git a/frameworks/native/qos_ndk.cpp b/frameworks/native/qos_ndk.cpp index 4523b002dace1d1bd274b662e0fb73b1793b3105..eaff4c248187160a130e84c7e3f366903f22d064 100644 --- a/frameworks/native/qos_ndk.cpp +++ b/frameworks/native/qos_ndk.cpp @@ -15,8 +15,10 @@ */ #include "qos.h" #include "inner_api/qos.h" +#include "concurrent_task_log.h" #include #include +#include #include static constexpr int ERROR_NUM = -1; @@ -53,4 +55,118 @@ int OH_QoS_GetThreadQoS(QoS_Level *level) } *level = static_cast(qosLevel); return 0; +} + +const char* const DYNAMIC_GEWU_CLIENT_PATH = "libgewu_client.z.so"; + +const char* const FUNC_CREATE_SESSION_NAME = "GewuCreateSession"; +const char* const FUNC_DESTROY_SESSION_NAME = "GewuDestroySession"; +const char* const FUNC_ABORT_REQUEST_NAME = "GewuAbortRequest"; +const char* const FUNC_SUBMIT_REQUEST_NAME = "GewuSubmitRequest"; + +using GewuCreateSessionFunc = OH_Gewu_CreateSessionResult(const char* attributes); +using GewuDestroySessionFunc = OH_Gewu_ErrorCode(OH_Gewu_Session session); +using GewuAbortRequestFunc = OH_Gewu_ErrorCode(OH_Gewu_Session session, OH_Gewu_Request request); +using GewuSubmitRequestFunc = OH_Gewu_SubmitRequestResult(OH_Gewu_Session session, const char* request, + OH_Gewu_OnResponse callback, void *context); + +void* g_GewuClientHandler = nullptr; + +GewuCreateSessionFunc* g_CreateSession = nullptr; +GewuDestroySessionFunc* g_DestroySession = nullptr; +GewuAbortRequestFunc* g_AbortRequest = nullptr; +GewuSubmitRequestFunc* g_SubmitRequest = nullptr; + +#define LOAD_DYNAMIC_LIB(handler, lib_path) { \ + (handler) = dlopen(lib_path, RTLD_LAZY | RTLD_LOCAL); \ + if ((handler) == nullptr) { + CONCUR_LOGE("load dynamic lib %s using dlopen: %s\n", lib_path, dlerror()); \ + } \ +} + +#define CLOSE_DYNAMIC_LIB(handler) { \ + if (handler) { \ + int ret = dlclose(handler); \ + if (ret) { \ + CONCUR_LOGE("falied to close dynamic lib %s using dlclose: %s\n", #handler, dlerror()); \ + } \ + (handler) = nullptr; \ + } \ +} + +#define LOAD_SYMBOL(handler, symbol_name, func_ptr) { \ + (func_ptr) = reinterpret_cast(dlsym(handler, symbol_name)); \ + if ((func_ptr) == nullptr) { \ + CONCUR_LOGE("falied to load symbol: %s\n", symbol_name); \ + CLOSE_DYNAMIC_LIB(handler); \ + } \ +} + +static bool prepare_symbols() +{ + if (g_GewuClientHandler != nullptr) { + return true; + } + LOAD_DYNAMIC_LIB(g_GewuClientHandler, DYNAMIC_GEWU_CLIENT_PATH); + if (g_GewuClientHandler == nullptr) { + return false; + } + LOAD_SYMBOL(g_GewuClientHandler, FUNC_CREATE_SESSION_NAME, g_CreateSession); + if (g_CreateSession == nullptr) { + return false; + } + LOAD_SYMBOL(g_GewuClientHandler, FUNC_DESTROY_SESSION_NAME, g_DestroySession); + if (g_DestroySession == nullptr) { + return false; + } + LOAD_SYMBOL(g_GewuClientHandler, FUNC_ABORT_REQUEST_NAME, g_AbortRequest); + if (g_AbortRequest == nullptr) { + return false; + } + LOAD_SYMBOL(g_GewuClientHandler, FUNC_SUBMIT_REQUEST_NAME, g_SubmitRequest); + if (g_SubmitRequest == nullptr) { + return false; + } + return true; +} + +OH_Gewu_CreateSessionResult OH_Gewu_CreateSession(const char* attributes) +{ + bool rc = prepare_symbols(); + if (rc != true) { + return {OH_GEWU_INVALID_SESSION_ID, OH_GEWU_FAULT}; + } + auto result = g_CreateSession(attributes); + return {result.session, static_cast(result.error)}; +} + +OH_Gewu_ErrorCode OH_Gewu_DestroySession(OH_Gewu_Session session) +{ + bool rc = prepare_symbols(); + if (rc != true) { + return OH_GEWU_FAULT; + } + auto result = g_DestroySession(session); + return static_cast(result); +} + +OH_Gewu_ErrorCode OH_Gewu_AbortRequest(OH_Gewu_Session session, OH_Gewu_Request request) +{ + bool rc = prepare_symbols(); + if (rc != true) { + return OH_GEWU_FAULT; + } + auto result = g_AbortRequest(session, request); + return static_cast(result); +} + +OH_Gewu_SubmitRequestResult OH_Gewu_SubmitRequest(OH_Gewu_Session session, const char* request, + OH_Gewu_OnResponse callback, void* context) +{ + bool rc = prepare_symbols(); + if (rc != true) { + return {OH_GEWU_INVALID_REQUEST_ID, OH_GEWU_FAULT}; + } + auto result = g_SubmitRequest(session, request, callback, context); + return {result.request, static_cast(result.error)}; } \ No newline at end of file diff --git a/interfaces/kits/c/qos.h b/interfaces/kits/c/qos.h index c92ab5b8622578b0b086fb042b15bda961c48c97..e9058cb044f95d938f0894f8ead11f9b6dedcc7a 100644 --- a/interfaces/kits/c/qos.h +++ b/interfaces/kits/c/qos.h @@ -108,6 +108,156 @@ int OH_QoS_ResetThreadQoS(); * @since 12 */ int OH_QoS_GetThreadQoS(QoS_Level *level); + +/** + * Session id and Request id + */ +typedef unsigned int OH_Gewu_Session; +#define OH_GEWU_INVALID_SESSION_ID (static_cast(0xffffffffU)) +typedef unsigned int OH_Gewu_Request +#define OH_GEWU_INVALID_REQUEST_ID (static_cast(0xffffffffU)) + +typedef enmu { + OH_GEWU_OK = 0; + OH_GEWU_INVAL = -1; + OH_GEWU_NOMEM = -2; + OH_GEWU_NOENT = -3; + OH_GEWU_FAULT = -4; + OH_GEWU_EXIST = -5; + OH_GEWU_NOPERM = -6; +} OH_Gewu_ErrorCode; + +/** + * json string of session attributes + * + * The json string of session attributes include the following parameters + * - modle: string. The directroy of the model of the session. + * + * An Example of json string of session attributes: + * { + * "model":"/data/storage/el2/base/files/qwen2/" + * } + */ + + /** + * @param session The create session id + * @param error Error code of CreateSession + * - OH_GEWU_OK will be returned if the session is create successfully. + * - OH_GEWU_NOMEM will be returned if the system does not have sufficient memory to + * create the session. + */ +typedef struct { + OH_Gewu_Session session; + OH_Gewu_ErrorCode error; +} OH_Gewu_CreateSessionResult; + + /** + * @param request The create request id + * @param error Error code of request submission. + * - OH_GEWU_OK will be returned if the request is submitted successfully. + * - OH_GEWU_NOMEM will be returned if the system does not have sufficient memory to + * submit the request. + */ +typedef struct { + OH_Gewu_Request request; + OH_Gewu_ErrorCode error; +} OH_Gewu_SubmitRequestResult; + + +/** + * @brief Callback to receive response of request. + * + * @param context The user context specified when submitting the request. + * @param reponse The json string of the response. + */ +typedef void (*OH_Gewu_OnResponse)(void* context, const char* response); + +/* + * json string of completion request. + * Completion request is a json string the specifies the following parameters: + * - messages: array. A list of messages. Each message contains the following fields: + * - role: stirng . The message type, which could be one of the following: + * - "developer": Developer-provided instructions. + * - "user": User-provided instructions. + * - "assistant": Message generated by the model in response to user messages. + * - content: string. The message content. + * - stream: boolean or null; optional. Enable streaming mode or not. if set to true, partial + * responses will be sent. if null or not set, defaults to nonstreaming mode. + * + * An example of completion request: + * { + * "messages": [ + { + "role": "developer", + "content": "Your are a helpful assistant." + }, + { + "role": "user", + "content": "What is OpenHarmony" + } + * ], + * "stream": true + * } + */ + +/** + * @brief Create a gewu session for inference. + * The lifecycle of the returned session object spans form the return of CreateSession + * to the call to DestroySession. + * + * @param attributes The json string of session attributes. + * + * @return Result of CreateSession + */ +OH_Gewu_CreateSessionResult OH_Gewu_CreateSession(const char* attributes); + +/** + * @brief Destroy the specified session. + * It is recommended that the client shall wait until all ongoing requests are done before calling + * this interface to destroy the session. If there are remaining requests in the session when this + * interface is called, those requests will be aborted and no further responses for those requests + * will be send to the client. + * Note that after calling this function successfully, the session cannot be used by the user code + * any more. + * + * @param session The session that will be destroyed. + * + * @return Error code. + * - OH_GEWU_OK while be returned if the session is destroyed successfully. + * - OH_GEWU_NOENT will be returned if the session is not found. + */ +OH_Gewu_ErrorCode OH_Gewu_DestroySession(OH_Gewu_Session session); + +/** + * @brief Abort the specified request. + * Note that after calling this function successfully, the client will not receive further resonses + * for this request, and the request object cannot be used by the user code any more. + * + * @param session The session that the request was submitted through. + * @param request The request object. + * + * @return Error code. + * - OH_GEWU_OK while be returned if the request is aborted successfully. + * - OH_GEWU_NOENT will be returned if the request is not found. + */ +OH_Gewu_ErrorCode OH_Gewu_AbortRequest(OH_Gewu_Session session, OH_Gewu_Request request); + +/** + * @brief Submit a request + * + * @param session The session object that the request should be submitted through. + * @param request The json string of request. + * @param callback The callback to receive response + * @param context The user context that should be passed to the response callback + * + * @return Error code. + * - OH_GEWU_OK while be returned if the request is accepted + * - OH_GEWU_NOMEM will be returned if the system does not have sufficient memory + * to accept the request. + */ +OH_Gewu_SubmitRequestResult OH_Gewu_SubmitRequest(OH_Gewu_Session session, const char* request, + OH_Gewu_OnResponse callback, void* context); + #ifdef __cplusplus }; #endif diff --git a/interfaces/kits/libqos.ndk.json b/interfaces/kits/libqos.ndk.json index e2b9422cc199e3766411686963a217cb823b3531..12936ac831f92fae236e054c0b7f1ed793ddfdcc 100644 --- a/interfaces/kits/libqos.ndk.json +++ b/interfaces/kits/libqos.ndk.json @@ -10,5 +10,21 @@ { "first_introduced": "12", "name": "OH_QoS_GetThreadQoS" + }, + { + "first_introduced": "12", + "name": "OH_Gewu_CreateSession" + }, + { + "first_introduced": "12", + "name": "OH_Gewu_DestroySession" + }, + { + "first_introduced": "12", + "name": "OH_Gewu_AbortRequest" + }, + { + "first_introduced": "12", + "name": "OH_Gewu_SubmitRequest" } ] \ No newline at end of file