diff --git a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc index 2ea8287b3..9ba840317 100644 --- a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc +++ b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.cc @@ -591,6 +591,62 @@ HResult HFGetCudaDeviceId(HPInt32 device_id) { return HSUCCEED; } +HResult HFSetRockchipDefaultNpuCoreMask(HInt32 core_mask) { +#if defined(ISF_ENABLE_RKNN) || defined(ISF_ENABLE_RKNN2) + INSPIREFACE_CONTEXT->SetRockchipDefaultNpuCoreMask(core_mask); + return HSUCCEED; +#else + INSPIRE_LOGW("RKNN runtime is not enabled during compilation; default core mask configuration skipped."); + return HERR_EXTENSION_ERROR; +#endif +} + +HResult HFSetRockchipNpuCoreMask(HInt32 core_mask) { +#if defined(ISF_ENABLE_RKNN) || defined(ISF_ENABLE_RKNN2) + if (core_mask < 0) { + INSPIREFACE_CONTEXT->ClearRockchipThreadNpuCoreMask(); + } else { + INSPIREFACE_CONTEXT->SetRockchipThreadNpuCoreMask(core_mask); + } + return HSUCCEED; +#else + INSPIRE_LOGW("RKNN runtime is not enabled during compilation; thread core mask configuration skipped."); + return HERR_EXTENSION_ERROR; +#endif +} + +HResult HFClearRockchipNpuCoreMask(void) { +#if defined(ISF_ENABLE_RKNN) || defined(ISF_ENABLE_RKNN2) + INSPIREFACE_CONTEXT->ClearRockchipThreadNpuCoreMask(); + return HSUCCEED; +#else + INSPIRE_LOGW("RKNN runtime is not enabled during compilation; clear core mask skipped."); + return HERR_EXTENSION_ERROR; +#endif +} + +HResult HFGetRockchipNpuCoreMask(HPInt32 core_mask) { +#if defined(ISF_ENABLE_RKNN) || defined(ISF_ENABLE_RKNN2) + *core_mask = INSPIREFACE_CONTEXT->GetRockchipNpuCoreMask(); + return HSUCCEED; +#else + INSPIRE_LOGW("RKNN runtime is not enabled during compilation; returning default auto core mask."); + *core_mask = 0; + return HERR_EXTENSION_ERROR; +#endif +} + +HResult HFGetRockchipDefaultNpuCoreMask(HPInt32 core_mask) { +#if defined(ISF_ENABLE_RKNN) || defined(ISF_ENABLE_RKNN2) + *core_mask = INSPIREFACE_CONTEXT->GetRockchipDefaultNpuCoreMask(); + return HSUCCEED; +#else + INSPIRE_LOGW("RKNN runtime is not enabled during compilation; returning default auto core mask."); + *core_mask = 0; + return HERR_EXTENSION_ERROR; +#endif +} + HResult HFPrintCudaDeviceInfo() { #if defined(ISF_ENABLE_TENSORRT) return inspire::PrintCudaDeviceInfo(); diff --git a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h index 5038fb318..d1f483d8f 100644 --- a/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h +++ b/cpp-package/inspireface/cpp/inspireface/c_api/inspireface.h @@ -435,6 +435,40 @@ HYPER_CAPI_EXPORT extern HResult HFSetCudaDeviceId(HInt32 device_id); * */ HYPER_CAPI_EXPORT extern HResult HFGetCudaDeviceId(HPInt32 device_id); +/** + * @brief Set the default Rockchip NPU core mask. This value is used when the current thread does not override the mask. + * @param core_mask The default core mask to be set. + * @return HResult indicating the success or failure of the operation. + * */ +HYPER_CAPI_EXPORT extern HResult HFSetRockchipDefaultNpuCoreMask(HInt32 core_mask); + +/** + * @brief Set the Rockchip NPU core mask for the current thread. Call with -1 to fall back to the default mask. + * @param core_mask The core mask to be applied to the current thread. + * @return HResult indicating the success or failure of the operation. + * */ +HYPER_CAPI_EXPORT extern HResult HFSetRockchipNpuCoreMask(HInt32 core_mask); + +/** + * @brief Clear the Rockchip NPU core mask override for the current thread. + * @return HResult indicating the success or failure of the operation. + * */ +HYPER_CAPI_EXPORT extern HResult HFClearRockchipNpuCoreMask(void); + +/** + * @brief Get the Rockchip NPU core mask that will be used for the current thread. + * @param core_mask Pointer to the core mask to be returned. + * @return HResult indicating the success or failure of the operation. + * */ +HYPER_CAPI_EXPORT extern HResult HFGetRockchipNpuCoreMask(HPInt32 core_mask); + +/** + * @brief Get the default Rockchip NPU core mask value. + * @param core_mask Pointer to the default core mask to be returned. + * @return HResult indicating the success or failure of the operation. + * */ +HYPER_CAPI_EXPORT extern HResult HFGetRockchipDefaultNpuCoreMask(HPInt32 core_mask); + /** * @brief Print the CUDA device information. * @return HResult indicating the success or failure of the operation. diff --git a/cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h b/cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h index b5573ff95..b432c4679 100644 --- a/cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h +++ b/cpp-package/inspireface/cpp/inspireface/include/inspireface/launch.h @@ -75,6 +75,21 @@ class INSPIRE_API_EXPORT Launch { // Get the rockchip dma heap path std::string GetRockchipDmaHeapPath() const; + // Configure default Rockchip NPU core mask + void SetRockchipDefaultNpuCoreMask(int32_t core_mask); + + // Configure the Rockchip NPU core mask for the current thread + void SetRockchipThreadNpuCoreMask(int32_t core_mask); + + // Clear the Rockchip NPU core mask override for the current thread + void ClearRockchipThreadNpuCoreMask(); + + // Query the Rockchip NPU core mask for the current thread (fallback to default) + int32_t GetRockchipNpuCoreMask() const; + + // Query the default Rockchip NPU core mask + int32_t GetRockchipDefaultNpuCoreMask() const; + // Set the extension path void ConfigurationExtensionPath(const std::string& path); @@ -134,4 +149,4 @@ class INSPIRE_API_EXPORT Launch { } // namespace inspire -#endif // INSPIREFACE_LAUNCH_H \ No newline at end of file +#endif // INSPIREFACE_LAUNCH_H diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h b/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h index 881505bfa..f781c13e4 100644 --- a/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h +++ b/cpp-package/inspireface/cpp/inspireface/middleware/any_net_adapter.h @@ -82,6 +82,10 @@ class INSPIRE_API AnyNetAdapter { if (m_infer_type_ == InferenceWrapper::INFER_TENSORRT) { m_nn_inference_->SetDevice(INSPIREFACE_CONTEXT->GetCudaDeviceId()); + } else if (m_infer_type_ == InferenceWrapper::INFER_RKNN) { +#if defined(ISF_ENABLE_RKNN) || defined(ISF_ENABLE_RKNN2) + m_nn_inference_->SetDevice(INSPIREFACE_CONTEXT->GetRockchipNpuCoreMask()); +#endif } #if defined(ISF_GLOBAL_INFERENCE_BACKEND_USE_MNN_CUDA) && !defined(ISF_ENABLE_RKNN) diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter.h b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter.h index 844e9f40b..22341c888 100644 --- a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter.h +++ b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter.h @@ -11,6 +11,10 @@ #include "data_type.h" #include "log.h" +#if defined(RKNN_NPU_CORE_UNDEFINED) +#define INSPIREFACE_HAS_RKNN_CORE_MASK 1 +#endif + /** * @brief Function to get RKNN data type string. * @param type Data type @@ -167,7 +171,14 @@ class RKNNAdapter { } run_ = true; - return init_(); + ret = init_(); + if (ret != RKNN_SUCC) { + return ret; + } + if (core_mask_overridden_) { + ret = apply_core_mask_(); + } + return ret; } /** @@ -188,7 +199,14 @@ class RKNNAdapter { } run_ = true; - return init_(); + ret = init_(); + if (ret != RKNN_SUCC) { + return ret; + } + if (core_mask_overridden_) { + ret = apply_core_mask_(); + } + return ret; } /** @@ -385,6 +403,33 @@ class RKNNAdapter { outputs_want_float_ = outputsWantFloat; } + /** + * @brief Configure the target NPU core mask. + * @param core_mask Rockchip NPU core mask value. + * @return 0 on success, negative on failure. + */ + int SetCoreMask(int32_t core_mask) { + core_mask_ = core_mask; + core_mask_overridden_ = true; + if (run_) { + return apply_core_mask_(); + } + return 0; + } + + /** + * @brief Reset NPU core mask to auto scheduling. + * @return 0 on success, negative on failure. + */ + int ResetCoreMask() { + core_mask_ = 0; + core_mask_overridden_ = false; + if (run_) { + return apply_core_mask_(); + } + return 0; + } + private: /** * initial @@ -474,6 +519,23 @@ class RKNNAdapter { return ret; } + int apply_core_mask_() { + if (!run_) { + return 0; + } +#if defined(INSPIREFACE_HAS_RKNN_CORE_MASK) + // rknn_set_core_mask 需要 rknn_core_mask 类型,这里做显式转换 + int ret = rknn_set_core_mask(rk_ctx_, static_cast(core_mask_)); + if (ret != RKNN_SUCC) { + INSPIRE_LOGE("rknn_set_core_mask fail! ret=%d", ret); + } + return ret; +#else + INSPIRE_LOGW("Current RKNN runtime does not support core mask configuration, skip."); + return RKNN_SUCC; +#endif + } + private: rknn_context rk_ctx_; ///< The context manager for RKNN. rknn_input_output_num rk_io_num_; ///< The number of input and output streams in RKNN. @@ -493,6 +555,8 @@ class RKNNAdapter { unsigned char *model_data; ///< Pointer to the model's data stream. bool load_; bool run_; + int32_t core_mask_{0}; + bool core_mask_overridden_{false}; }; #endif // INSPIREFACE_RKNN_ADAPTER_RKNPU1_H diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter_nano.h b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter_nano.h index 2d5b67639..a94f42cb9 100644 --- a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter_nano.h +++ b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/customized/rknn_adapter_nano.h @@ -19,6 +19,9 @@ #include #include "log.h" +#if defined(RKNN_NPU_CORE_UNDEFINED) +#define INSPIREFACE_HAS_RKNN_CORE_MASK 1 +#endif inline std::vector softmax(const std::vector &input) { std::vector output; output.reserve(input.size()); @@ -80,6 +83,24 @@ class RKNNAdapterNano { RKNNAdapterNano &operator=(const RKNNAdapterNano &) = delete; RKNNAdapterNano() = default; + int32_t SetCoreMask(int32_t core_mask) { + core_mask_ = core_mask; + core_mask_overridden_ = true; + if (run_) { + return apply_core_mask_(); + } + return 0; + } + + int32_t ResetCoreMask() { + core_mask_ = 0; + core_mask_overridden_ = false; + if (run_) { + return apply_core_mask_(); + } + return 0; + } + int32_t Initialize(void *model_data, unsigned int model_size) { int ret = rknn_init(&m_rk_ctx_, model_data, model_size, 0, NULL); if (ret < 0) { @@ -168,6 +189,12 @@ class RKNNAdapterNano { } run_ = true; + if (core_mask_overridden_) { + ret = apply_core_mask_(); + if (ret != RKNN_SUCC) { + return ret; + } + } return 0; } @@ -254,6 +281,23 @@ class RKNNAdapterNano { return 0; } + int apply_core_mask_() { + if (!run_) { + return 0; + } +#if defined(INSPIREFACE_HAS_RKNN_CORE_MASK) + // rknn_set_core_mask 期望的是枚举类型 rknn_core_mask,这里做显式转换 + int ret = rknn_set_core_mask(m_rk_ctx_, static_cast(core_mask_)); + if (ret != RKNN_SUCC) { + INSPIRE_LOGE("rknn_set_core_mask fail! ret=%d", ret); + } + return ret; +#else + INSPIRE_LOGW("Current RKNN runtime does not support core mask configuration, skip."); + return RKNN_SUCC; +#endif + } + std::vector &GetOutputData(size_t index) { return m_output_nchw_[index]; } @@ -307,6 +351,8 @@ class RKNNAdapterNano { std::vector> m_output_nchw_; bool run_; + int32_t core_mask_{0}; + bool core_mask_overridden_{false}; }; #endif // SLEEPMONITORING_RKNN_ADAPTER_NANO_H diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter.cpp b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter.cpp index 5cd63bf6f..be40e3507 100644 --- a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter.cpp +++ b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter.cpp @@ -36,6 +36,19 @@ int32_t InferenceWrapperRKNNAdapter::SetNumThreads(const int32_t num_threads) { return WrapperOk; } +int32_t InferenceWrapperRKNNAdapter::SetDevice(int32_t device_id) { + core_mask_ = device_id; + core_mask_overridden_ = true; + if (net_) { + auto ret = net_->SetCoreMask(core_mask_); + if (ret != 0) { + INSPIRE_LOGE("Failed to apply RKNN core mask(%d), ret=%d", core_mask_, ret); + return WrapperError; + } + } + return WrapperOk; +} + int32_t InferenceWrapperRKNNAdapter::ParameterInitialization(std::vector &input_tensor_info_list, std::vector &output_tensor_info_list) { return WrapperOk; @@ -116,6 +129,13 @@ int32_t InferenceWrapperRKNNAdapter::Initialize(char *model_buffer, int model_si INSPIRE_LOGE("Rknn init error."); return WrapperError; } + if (core_mask_overridden_) { + auto mask_ret = net_->SetCoreMask(core_mask_); + if (mask_ret != 0) { + INSPIRE_LOGE("Failed to apply RKNN core mask(%d), ret=%d", core_mask_, mask_ret); + return WrapperError; + } + } return ParameterInitialization(input_tensor_info_list, output_tensor_info_list); } @@ -135,4 +155,4 @@ int32_t InferenceWrapperRKNNAdapter::ResizeInput(const std::vector& input_tensor_info_list, std::vector& output_tensor_info_list) override; int32_t Initialize(char* model_buffer, int model_size, std::vector& input_tensor_info_list, @@ -38,6 +39,8 @@ class InferenceWrapperRKNNAdapter : public InferenceWrapper { private: std::shared_ptr net_; int32_t num_threads_; + int32_t core_mask_{0}; + bool core_mask_overridden_{false}; }; #endif // INFERENCE_WRAPPER_ENABLE_RKNN diff --git a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter_nano.cpp b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter_nano.cpp index 8eee688cc..08ed6c04b 100644 --- a/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter_nano.cpp +++ b/cpp-package/inspireface/cpp/inspireface/middleware/inference_wrapper/inference_wrapper_rknn_adapter_nano.cpp @@ -36,6 +36,19 @@ int32_t InferenceWrapperRKNNAdapter::SetNumThreads(const int32_t num_threads) { return WrapperOk; } +int32_t InferenceWrapperRKNNAdapter::SetDevice(int32_t device_id) { + core_mask_ = device_id; + core_mask_overridden_ = true; + if (net_) { + auto ret = net_->SetCoreMask(core_mask_); + if (ret != 0) { + INSPIRE_LOGE("Failed to apply RKNN core mask(%d), ret=%d", core_mask_, ret); + return WrapperError; + } + } + return WrapperOk; +} + int32_t InferenceWrapperRKNNAdapter::ParameterInitialization(std::vector &input_tensor_info_list, std::vector &output_tensor_info_list) { return WrapperOk; @@ -112,6 +125,13 @@ int32_t InferenceWrapperRKNNAdapter::Initialize(char *model_buffer, int model_si INSPIRE_LOGE("Rknn init error."); return WrapperError; } + if (core_mask_overridden_) { + auto mask_ret = net_->SetCoreMask(core_mask_); + if (mask_ret != 0) { + INSPIRE_LOGE("Failed to apply RKNN core mask(%d), ret=%d", core_mask_, mask_ret); + return WrapperError; + } + } return ParameterInitialization(input_tensor_info_list, output_tensor_info_list); } @@ -131,4 +151,4 @@ int32_t InferenceWrapperRKNNAdapter::ResizeInput(const std::vector& input_tensor_info_list, std::vector& output_tensor_info_list) override; int32_t Initialize(char* model_buffer, int model_size, std::vector& input_tensor_info_list, @@ -38,6 +39,8 @@ class InferenceWrapperRKNNAdapter : public InferenceWrapper { private: std::shared_ptr net_; int32_t num_threads_; + int32_t core_mask_{0}; + bool core_mask_overridden_{false}; }; #endif // INFERENCE_WRAPPER_ENABLE_RKNN2 diff --git a/cpp-package/inspireface/cpp/inspireface/runtime_module/launch.cpp b/cpp-package/inspireface/cpp/inspireface/runtime_module/launch.cpp index 2ad404656..b151d1a0e 100644 --- a/cpp-package/inspireface/cpp/inspireface/runtime_module/launch.cpp +++ b/cpp-package/inspireface/cpp/inspireface/runtime_module/launch.cpp @@ -14,6 +14,8 @@ #include "image_process/nexus_processor/rga/dma_alloc.h" #endif #include +#include +#include #include "middleware/inference_wrapper/inference_wrapper.h" #include "middleware/system.h" #if defined(ISF_ENABLE_TENSORRT) @@ -59,6 +61,7 @@ class Launch::Impl { static std::shared_ptr instance_; // Data members + mutable std::mutex state_mutex_; std::string m_rockchip_dma_heap_path_; std::string m_extension_path_; std::unique_ptr m_archive_; @@ -67,6 +70,9 @@ class Launch::Impl { InferenceWrapper::SpecialBackend m_global_coreml_inference_mode_; Launch::ImageProcessingBackend m_image_processing_backend_; int32_t m_image_process_aligned_width_{4}; + int32_t m_default_rknn_core_mask_{0}; + std::unordered_map m_thread_rknn_core_masks_; + mutable std::mutex m_core_mask_mutex_; }; // Initialize static members @@ -88,7 +94,7 @@ std::shared_ptr Launch::GetInstance() { } InspireArchive& Launch::getMArchive() { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); if (!pImpl->m_archive_) { throw std::runtime_error("Archive not initialized"); } @@ -96,7 +102,7 @@ InspireArchive& Launch::getMArchive() { } int32_t Launch::Load(const std::string& path) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); #if defined(ISF_ENABLE_TENSORRT) int32_t support_cuda; auto ret = CheckCudaUsability(&support_cuda); @@ -143,7 +149,7 @@ int32_t Launch::Load(const std::string& path) { } int32_t Launch::Reload(const std::string& path) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); INSPIREFACE_CHECK_MSG(os::IsExists(path), "The package path does not exist because the launch failed."); #if defined(ISF_ENABLE_APPLE_EXTENSION) BuildAppleExtensionPath(path); @@ -180,7 +186,7 @@ bool Launch::isMLoad() const { } void Launch::Unload() { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); if (pImpl->m_load_) { pImpl->m_archive_.reset(); pImpl->m_load_ = false; @@ -191,15 +197,48 @@ void Launch::Unload() { } void Launch::SetRockchipDmaHeapPath(const std::string& path) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); pImpl->m_rockchip_dma_heap_path_ = path; } std::string Launch::GetRockchipDmaHeapPath() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_rockchip_dma_heap_path_; } +void Launch::SetRockchipDefaultNpuCoreMask(int32_t core_mask) { + std::lock_guard lock(pImpl->m_core_mask_mutex_); + pImpl->m_default_rknn_core_mask_ = core_mask; +} + +void Launch::SetRockchipThreadNpuCoreMask(int32_t core_mask) { + std::lock_guard lock(pImpl->m_core_mask_mutex_); + if (core_mask < 0) { + pImpl->m_thread_rknn_core_masks_.erase(std::this_thread::get_id()); + } else { + pImpl->m_thread_rknn_core_masks_[std::this_thread::get_id()] = core_mask; + } +} + +void Launch::ClearRockchipThreadNpuCoreMask() { + std::lock_guard lock(pImpl->m_core_mask_mutex_); + pImpl->m_thread_rknn_core_masks_.erase(std::this_thread::get_id()); +} + +int32_t Launch::GetRockchipNpuCoreMask() const { + std::lock_guard lock(pImpl->m_core_mask_mutex_); + auto it = pImpl->m_thread_rknn_core_masks_.find(std::this_thread::get_id()); + if (it != pImpl->m_thread_rknn_core_masks_.end()) { + return it->second; + } + return pImpl->m_default_rknn_core_mask_; +} + +int32_t Launch::GetRockchipDefaultNpuCoreMask() const { + std::lock_guard lock(pImpl->m_core_mask_mutex_); + return pImpl->m_default_rknn_core_mask_; +} + void Launch::ConfigurationExtensionPath(const std::string& path) { #if defined(ISF_ENABLE_APPLE_EXTENSION) INSPIREFACE_CHECK_MSG(os::IsDir(path), "The apple extension path is not a directory, please check."); @@ -209,12 +248,12 @@ void Launch::ConfigurationExtensionPath(const std::string& path) { } std::string Launch::GetExtensionPath() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_extension_path_; } void Launch::SetGlobalCoreMLInferenceMode(NNInferenceBackend mode) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); if (mode == NN_INFERENCE_CPU) { pImpl->m_global_coreml_inference_mode_ = InferenceWrapper::COREML_CPU; } else if (mode == NN_INFERENCE_COREML_GPU) { @@ -234,7 +273,7 @@ void Launch::SetGlobalCoreMLInferenceMode(NNInferenceBackend mode) { } Launch::NNInferenceBackend Launch::GetGlobalCoreMLInferenceMode() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); if (pImpl->m_global_coreml_inference_mode_ == InferenceWrapper::COREML_CPU) { return NN_INFERENCE_CPU; } else if (pImpl->m_global_coreml_inference_mode_ == InferenceWrapper::COREML_GPU) { @@ -255,37 +294,37 @@ void Launch::BuildAppleExtensionPath(const std::string& resource_path) { } void Launch::SetCudaDeviceId(int32_t device_id) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); pImpl->m_cuda_device_id_ = device_id; } int32_t Launch::GetCudaDeviceId() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_cuda_device_id_; } void Launch::SetFaceDetectPixelList(const std::vector& pixel_list) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); pImpl->m_face_detect_pixel_list_ = pixel_list; } std::vector Launch::GetFaceDetectPixelList() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_face_detect_pixel_list_; } void Launch::SetFaceDetectModelList(const std::vector& model_list) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); pImpl->m_face_detect_model_list_ = model_list; } std::vector Launch::GetFaceDetectModelList() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_face_detect_model_list_; } void Launch::SwitchLandmarkEngine(LandmarkEngine engine) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); if (pImpl->m_archive_->QueryStatus() != SARC_SUCCESS) { INSPIRE_LOGE("The InspireFace is not initialized, please call launch first."); return; @@ -303,7 +342,7 @@ void Launch::SwitchLandmarkEngine(LandmarkEngine engine) { } void Launch::SwitchImageProcessingBackend(ImageProcessingBackend backend) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); if (backend == IMAGE_PROCESSING_RGA) { #if defined(ISF_ENABLE_RGA) pImpl->m_image_processing_backend_ = backend; @@ -317,18 +356,18 @@ void Launch::SwitchImageProcessingBackend(ImageProcessingBackend backend) { } Launch::ImageProcessingBackend Launch::GetImageProcessingBackend() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_image_processing_backend_; } void Launch::SetImageProcessAlignedWidth(int32_t width) { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); pImpl->m_image_process_aligned_width_ = width; } int32_t Launch::GetImageProcessAlignedWidth() const { - std::lock_guard lock(pImpl->mutex_); + std::lock_guard lock(pImpl->state_mutex_); return pImpl->m_image_process_aligned_width_; } -} // namespace inspire \ No newline at end of file +} // namespace inspire diff --git a/cpp-package/inspireface/python/inspireface/modules/__init__.py b/cpp-package/inspireface/python/inspireface/modules/__init__.py index b37715997..39089b708 100644 --- a/cpp-package/inspireface/python/inspireface/modules/__init__.py +++ b/cpp-package/inspireface/python/inspireface/modules/__init__.py @@ -8,4 +8,5 @@ HF_PK_AUTO_INCREMENT, HF_PK_MANUAL_INPUT, HF_SEARCH_MODE_EAGER, HF_SEARCH_MODE_EXHAUSTIVE, \ ignore_check_latest_model, set_cuda_device_id, get_cuda_device_id, print_cuda_device_info, get_num_cuda_devices, check_cuda_device_support, terminate, \ InspireFaceError, InvalidInputError, SystemNotReadyError, ProcessingError, ResourceError, HardwareError, FeatureHubError, \ - switch_image_processing_backend, HF_IMAGE_PROCESSING_CPU, HF_IMAGE_PROCESSING_RGA, set_image_process_aligned_width, use_oss_download \ No newline at end of file + switch_image_processing_backend, HF_IMAGE_PROCESSING_CPU, HF_IMAGE_PROCESSING_RGA, set_image_process_aligned_width, use_oss_download, \ + set_default_rknn_core_mask, set_rknn_core_mask, clear_rknn_core_mask, get_rknn_core_mask, get_default_rknn_core_mask diff --git a/cpp-package/inspireface/python/inspireface/modules/core/native.py b/cpp-package/inspireface/python/inspireface/modules/core/native.py index 1c4359056..53df7fba9 100644 --- a/cpp-package/inspireface/python/inspireface/modules/core/native.py +++ b/cpp-package/inspireface/python/inspireface/modules/core/native.py @@ -1325,6 +1325,36 @@ class struct_HFImageBitmapData(Structure): HFSetCudaDeviceId.argtypes = [HInt32] HFSetCudaDeviceId.restype = HResult +# /Users/tunm/work/InspireFace/cpp/inspireface/c_api/inspireface.h: 448 +if _libs[_LIBRARY_FILENAME].has("HFSetRockchipDefaultNpuCoreMask", "cdecl"): + HFSetRockchipDefaultNpuCoreMask = _libs[_LIBRARY_FILENAME].get("HFSetRockchipDefaultNpuCoreMask", "cdecl") + HFSetRockchipDefaultNpuCoreMask.argtypes = [HInt32] + HFSetRockchipDefaultNpuCoreMask.restype = HResult + +# /Users/tunm/work/InspireFace/cpp/inspireface/c_api/inspireface.h: 455 +if _libs[_LIBRARY_FILENAME].has("HFSetRockchipNpuCoreMask", "cdecl"): + HFSetRockchipNpuCoreMask = _libs[_LIBRARY_FILENAME].get("HFSetRockchipNpuCoreMask", "cdecl") + HFSetRockchipNpuCoreMask.argtypes = [HInt32] + HFSetRockchipNpuCoreMask.restype = HResult + +# /Users/tunm/work/InspireFace/cpp/inspireface/c_api/inspireface.h: 462 +if _libs[_LIBRARY_FILENAME].has("HFClearRockchipNpuCoreMask", "cdecl"): + HFClearRockchipNpuCoreMask = _libs[_LIBRARY_FILENAME].get("HFClearRockchipNpuCoreMask", "cdecl") + HFClearRockchipNpuCoreMask.argtypes = [] + HFClearRockchipNpuCoreMask.restype = HResult + +# /Users/tunm/work/InspireFace/cpp/inspireface/c_api/inspireface.h: 469 +if _libs[_LIBRARY_FILENAME].has("HFGetRockchipNpuCoreMask", "cdecl"): + HFGetRockchipNpuCoreMask = _libs[_LIBRARY_FILENAME].get("HFGetRockchipNpuCoreMask", "cdecl") + HFGetRockchipNpuCoreMask.argtypes = [HPInt32] + HFGetRockchipNpuCoreMask.restype = HResult + +# /Users/tunm/work/InspireFace/cpp/inspireface/c_api/inspireface.h: 476 +if _libs[_LIBRARY_FILENAME].has("HFGetRockchipDefaultNpuCoreMask", "cdecl"): + HFGetRockchipDefaultNpuCoreMask = _libs[_LIBRARY_FILENAME].get("HFGetRockchipDefaultNpuCoreMask", "cdecl") + HFGetRockchipDefaultNpuCoreMask.argtypes = [HPInt32] + HFGetRockchipDefaultNpuCoreMask.restype = HResult + # /Users/tunm/work/InspireFace/cpp/inspireface/c_api/inspireface.h: 436 if _libs[_LIBRARY_FILENAME].has("HFGetCudaDeviceId", "cdecl"): HFGetCudaDeviceId = _libs[_LIBRARY_FILENAME].get("HFGetCudaDeviceId", "cdecl") @@ -2346,4 +2376,3 @@ class struct_HFInspireFaceExtendedInformation(Structure): # No inserted files # No prefix-stripping - diff --git a/cpp-package/inspireface/python/inspireface/modules/inspireface.py b/cpp-package/inspireface/python/inspireface/modules/inspireface.py index 3e6d0639a..3a47ac891 100644 --- a/cpp-package/inspireface/python/inspireface/modules/inspireface.py +++ b/cpp-package/inspireface/python/inspireface/modules/inspireface.py @@ -860,6 +860,43 @@ def switch_image_processing_backend(backend: int): check_error(ret, "Switch image processing backend", backend=backend) return True + +def set_default_rknn_core_mask(core_mask: int) -> bool: + """Set default Rockchip NPU core mask used when no thread override is provided.""" + ret = HFSetRockchipDefaultNpuCoreMask(core_mask) + check_error(ret, "Set default Rockchip core mask", core_mask=core_mask) + return True + + +def set_rknn_core_mask(core_mask: int) -> bool: + """Bind the current thread to the specified Rockchip NPU core mask.""" + ret = HFSetRockchipNpuCoreMask(core_mask) + check_error(ret, "Set Rockchip core mask", core_mask=core_mask) + return True + + +def clear_rknn_core_mask() -> bool: + """Clear the Rockchip NPU core mask override for the current thread.""" + ret = HFClearRockchipNpuCoreMask() + check_error(ret, "Clear Rockchip core mask override") + return True + + +def get_rknn_core_mask() -> int: + """Get the Rockchip NPU core mask that will be used by the current thread.""" + mask = HInt32() + ret = HFGetRockchipNpuCoreMask(byref(mask)) + check_error(ret, "Get Rockchip core mask") + return mask.value + + +def get_default_rknn_core_mask() -> int: + """Get the default Rockchip NPU core mask value.""" + mask = HInt32() + ret = HFGetRockchipDefaultNpuCoreMask(byref(mask)) + check_error(ret, "Get default Rockchip core mask") + return mask.value + def set_image_process_aligned_width(width: int): """Set the image process aligned width""" ret = HFSetImageProcessAlignedWidth(width)