From b4f5a20a03ce814db39ba61b29868b4c5fd9abb6 Mon Sep 17 00:00:00 2001 From: liuchuang Date: Wed, 4 Jun 2025 18:12:52 +0800 Subject: [PATCH] Submit the API and comments of gewu Signed-off-by: liuchuang --- frameworks/native/BUILD.gn | 5 + frameworks/native/qos_ndk.cpp | 117 ++++++++++++++++++++- interfaces/kits/c/qos.h | 178 ++++++++++++++++++++++++++++++++ interfaces/kits/libqos.ndk.json | 18 +++- 4 files changed, 316 insertions(+), 2 deletions(-) diff --git a/frameworks/native/BUILD.gn b/frameworks/native/BUILD.gn index ac8de4c..456fc94 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 4523b00..af85384 100644 --- a/frameworks/native/qos_ndk.cpp +++ b/frameworks/native/qos_ndk.cpp @@ -15,12 +15,22 @@ */ #include "qos.h" #include "inner_api/qos.h" +#include "concurrent_task_log.h" #include #include +#include #include +#include static constexpr int ERROR_NUM = -1; +const char* GEWU_CLIENT_LIB = "libgewu_client.z.so"; + +const char* GEWU_CREATE_SESSION_FUNC = "GewuCreateSession"; +const char* GEWU_DESTROY_SESSION_FUNC = "GewuDestroySession"; +const char* GEWU_SUBMIT_REQUEST_FUNC = "GewuSubmitRequest"; +const char* GEWU_ABORT_REQUEST_FUNC = "GewuAbortRequest"; + using namespace OHOS::QOS; using namespace std; @@ -53,4 +63,109 @@ int OH_QoS_GetThreadQoS(QoS_Level *level) } *level = static_cast(qosLevel); return 0; -} \ No newline at end of file +} + +using GewuCreateSessionFunc = OH_QoS_GewuCreateSessionResult(*)(const char* attributes); +using GewuDestroySessionFunc = OH_QoS_GewuErrorCode(*)(OH_QoS_GewuSession session); +using GewuAbortRequestFunc = OH_QoS_GewuErrorCode(*)(OH_QoS_GewuSession session, OH_QoS_GewuRequest request); +using GewuSubmitRequestFunc = OH_QoS_GewuSubmitRequestResult(*)(OH_QoS_GewuSession session, const char* request, + OH_QoS_GewuOnResponse callback, void *context); + +std::once_flag g_gewuInitFlag; +bool g_gewuInitialized = false; + +void* g_gewuNdkLibHandler = nullptr; + +GewuCreateSessionFunc g_CreateSession = nullptr; +GewuDestroySessionFunc g_DestroySession = nullptr; +GewuSubmitRequestFunc g_SubmitRequest = nullptr; +GewuAbortRequestFunc g_AbortRequest = nullptr; + +static inline void *LoadSymbol(const char* symbolName) +{ + void* funcPtr = dlsym(g_gewuNdkLibHandler, symbolName); + if (funcPtr == nullptr) { + CONCUR_LOGE("[Gewu] failed to load symbol: %{public}s, error: %{public}s", symbolName, dlerror()); + } + return funcPtr; +} + +static int LoadSymbols(void) +{ + g_CreateSession = reinterpret_cast(LoadSymbol(GEWU_CREATE_SESSION_FUNC)); + if (g_CreateSession == nullptr) { + return -1; + } + + g_DestroySession = reinterpret_cast(LoadSymbol(GEWU_DESTROY_SESSION_FUNC)); + if (g_DestroySession == nullptr) { + return -1; + } + + g_SubmitRequest = reinterpret_cast(LoadSymbol(GEWU_SUBMIT_REQUEST_FUNC)); + if (g_SubmitRequest == nullptr) { + return -1; + } + + g_AbortRequest = reinterpret_cast(LoadSymbol(GEWU_ABORT_REQUEST_FUNC)); + if (g_AbortRequest == nullptr) { + return -1; + } + + return 0; +} + +__attribute__((noinline)) static void InitializeGewu(void) +{ + g_gewuNdkLibHandler = dlopen(GEWU_CLIENT_LIB, RTLD_LAZY | RTLD_LOCAL); + if (g_gewuNdkLibHandler == nullptr) { + CONCUR_LOGE("[Gewu] failed to load library: %{public}s, error: %{public}s", GEWU_CLIENT_LIB, dlerror()); + return; + } + int err = LoadSymbols(); + if (err != 0) { + dlclose(g_gewuNdkLibHandler); + g_gewuNdkLibHandler = nullptr; + return; + } + g_gewuInitialized = true; +} + +static inline bool EnsureGewuInitialized(void) +{ + std::call_once(g_gewuInitFlag, InitializeGewu); + return g_gewuInitialized; +} + +extern "C" OH_QoS_GewuCreateSessionResult OH_QoS_GewuCreateSession(const char* attributes) +{ + if (!EnsureGewuInitialized()) { + return {OH_QOS_GEWU_INVALID_SESSION_ID, OH_QOS_GEWU_NOSYS}; + } + return g_CreateSession(attributes); +} + +extern "C" OH_QoS_GewuErrorCode OH_QoS_GewuDestroySession(OH_QoS_GewuSession session) +{ + if (!EnsureGewuInitialized()) { + return OH_QOS_GEWU_NOSYS; + } + return g_DestroySession(session); +} + +extern "C" OH_QoS_GewuSubmitRequestResult OH_QoS_GewuSubmitRequest(OH_QoS_GewuSession session, const char* request, + OH_QoS_GewuOnResponse callback, void* context) +{ + if (!EnsureGewuInitialized()) { + return {OH_QOS_GEWU_INVALID_REQUEST_ID, OH_QOS_GEWU_NOSYS}; + } + return g_SubmitRequest(session, request, callback, context); +} + +extern "C" OH_QoS_GewuErrorCode OH_QoS_GewuAbortRequest(OH_QoS_GewuSession session, OH_QoS_GewuRequest request) +{ + if (!EnsureGewuInitialized()) { + return OH_QOS_GEWU_NOSYS; + } + return g_AbortRequest(session, request); +} diff --git a/interfaces/kits/c/qos.h b/interfaces/kits/c/qos.h index c92ab5b..91bca10 100644 --- a/interfaces/kits/c/qos.h +++ b/interfaces/kits/c/qos.h @@ -108,6 +108,184 @@ int OH_QoS_ResetThreadQoS(); * @since 12 */ int OH_QoS_GetThreadQoS(QoS_Level *level); + +/** + * @brief Session id + * + * @since 20 + */ +typedef unsigned int OH_QoS_GewuSession; +#define OH_QOS_GEWU_INVALID_SESSION_ID (static_cast(0xffffffffU)) +/** + * @brief Request id + * + * @since 20 + */ +typedef unsigned int OH_QoS_GewuRequest; +#define OH_QOS_GEWU_INVALID_REQUEST_ID (static_cast(0xffffffffU)) + + +/** + * @brief Gewu error codes. + * + * @since 20 + */ +typedef enum { + OH_QOS_GEWU_OK = 0, + OH_QOS_GEWU_NOPERM = 201, + OH_QOS_GEWU_NOMEM = 203, + OH_QOS_GEWU_INVAL = 401, + OH_QOS_GEWU_EXIST = 501, + OH_QOS_GEWU_NOENT = 502, + OH_QOS_GEWU_NOSYS = 801, + OH_QOS_GEWU_FAULT = 901, +} OH_QoS_GewuErrorCode; + +/** + * @param session The created session id + * @param error Error code of CreateSession + * - OH_QOS_GEWU_OK will be returned if the session is created successfully. + * - OH_QOS_GEWU_NOMEM will be returned if the system does not have sufficient memory to + * create the session. + * + * @since 20 + */ +typedef struct { + OH_QoS_GewuSession session; + OH_QoS_GewuErrorCode error; +} OH_QoS_GewuCreateSessionResult; + +/** + * @param request The created request id + * @param error Error code of request submission. + * - OH_QOS_GEWU_OK will be returned if the request is submitted successfully. + * - OH_QOS_GEWU_NOMEM will be returned if the system does not have sufficient memory to + * submit the request. + * + * @since 20 + */ +typedef struct { + OH_QoS_GewuRequest request; + OH_QoS_GewuErrorCode error; +} OH_QoS_GewuSubmitRequestResult; + + +/** + * @brief Callback to receive response of the request. + * + * @param context The user context specified when submitting the request. + * @param reponse The json string of the response. + * + * @since 20 + */ +typedef void (*OH_QoS_GewuOnResponse)(void* context, const char* response); + +/** + * @brief Create a gewu session for inference. + * The lifecycle of the returned session object spans from the return of CreateSession + * to the call to DestroySession. + * + * json string of session attributes. + * + * The json string of session attributes include the following parameters + * - model: string. The directory of the model of the session. + * + * An example of json string of session attributes: + * @code{.json} + * { + * "model": "/data/storage/el2/base/files/qwen2/" + * } + * @endcode + * + * @param attributes The json string of session attributes. + * + * @return Result of CreateSession. + * + * @since 20 + */ +OH_QoS_GewuCreateSessionResult OH_QoS_GewuCreateSession(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 sent 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_QOS_GEWU_OK will be returned if the session is destroyed successfully. + * - OH_QOS_GEWU_NOENT will be returned if the session is not found. + * + * @since 20 + */ +OH_QoS_GewuErrorCode OH_QoS_GewuDestroySession(OH_QoS_GewuSession session); + +/** + * @brief Abort the specified request. + * Note that after calling this function successfully, the client will not receive further responses + * 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_QOS_GEWU_OK will be returned if the request is aborted successfully. + * - OH_QOS_GEWU_NOENT will be returned if the request is not found. + * + * @since 20 + */ +OH_QoS_GewuErrorCode OH_QoS_GewuAbortRequest(OH_QoS_GewuSession session, OH_QoS_GewuRequest request); + +/** + * @brief Submit a request. + * + * json string of completion request. + * Completion request is a json string that specifies the following parameters: + * - messages: array. A list of messages. Each message contains the following fields: + * - role: string. 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: + * @code{.json} + * { + * "messages": [ + { + "role": "developer", + "content": "Your are a helpful assistant." + }, + { + "role": "user", + "content": "What is OpenHarmony" + } + * ], + * "stream": true + * } + * @endcode + * + * @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_QOS_GEWU_OK will be returned if the request is accepted. + * - OH_QOS_GEWU_NOMEM will be returned if the system does not have sufficient memory + * to accept the request. + * + * @since 20 + */ +OH_QoS_GewuSubmitRequestResult OH_QoS_GewuSubmitRequest(OH_QoS_GewuSession session, const char* request, + OH_QoS_GewuOnResponse callback, void* context); + #ifdef __cplusplus }; #endif diff --git a/interfaces/kits/libqos.ndk.json b/interfaces/kits/libqos.ndk.json index e2b9422..0588dcc 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": "20", + "name": "OH_QoS_Gewu_CreateSession" + }, + { + "first_introduced": "20", + "name": "OH_QoS_Gewu_DestroySession" + }, + { + "first_introduced": "20", + "name": "OH_QoS_Gewu_AbortRequest" + }, + { + "first_introduced": "20", + "name": "OH_QoS_Gewu_SubmitRequest" } -] \ No newline at end of file +] -- Gitee