diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h index 4403a579cc..ee103bacf5 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h @@ -59,13 +59,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp index f301065cf9..6cf907380e 100644 --- a/neuralnetworks/1.0/utils/src/Conversions.cpp +++ b/neuralnetworks/1.0/utils/src/Conversions.cpp @@ -290,10 +290,8 @@ nn::GeneralResult> convert(const nn::Model::OperandValues& ope } nn::GeneralResult convert(const nn::Memory& memory) { - const auto hidlMemory = hidl_memory(memory.name, memory.handle->handle(), memory.size); - // Copy memory to force the native_handle_t to be copied. - auto copiedMemory = hidlMemory; - return copiedMemory; + return hidl_memory(memory.name, NN_TRY(hal::utils::hidlHandleFromSharedHandle(memory.handle)), + memory.size); } nn::GeneralResult convert(const nn::Model& model) { diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index 8292f170c2..671416b9eb 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -157,8 +157,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference /*preference*/, nn::Priority /*priority*/, - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -181,8 +181,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IDevice::prepareModelFromCache not supported on 1.0 HAL service"; } diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h index f55ac6cb6d..c1e95fe1a5 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h @@ -59,13 +59,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index 03b0d6eb8e..a0378c94a0 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -159,8 +159,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/, - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -184,8 +184,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IDevice::prepareModelFromCache not supported on 1.1 HAL service"; } diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h index e6de011f9c..24911fea08 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h @@ -44,11 +44,11 @@ GeneralResult convert(const hal::V1_2::Timing& timing); GeneralResult convert(const hal::V1_2::Extension& extension); GeneralResult convert( const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation); -GeneralResult convert(const hardware::hidl_handle& handle); +GeneralResult convert(const hardware::hidl_handle& handle); GeneralResult> convert( const hardware::hidl_vec& extensions); -GeneralResult> convert( +GeneralResult> convert( const hardware::hidl_vec& handles); GeneralResult> convert( const hardware::hidl_vec& outputShapes); @@ -77,10 +77,10 @@ nn::GeneralResult convert(const nn::Timing& timing); nn::GeneralResult convert(const nn::Extension& extension); nn::GeneralResult convert( const nn::Extension::OperandTypeInformation& operandTypeInformation); -nn::GeneralResult convert(const nn::NativeHandle& handle); +nn::GeneralResult convert(const nn::SharedHandle& handle); nn::GeneralResult> convert(const std::vector& extensions); -nn::GeneralResult> convert(const std::vector& handles); +nn::GeneralResult> convert(const std::vector& handles); nn::GeneralResult> convert(const std::vector& outputShapes); } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h index eb317b12cf..bbd534335b 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -68,13 +68,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp index 378719afc9..08c94dec33 100644 --- a/neuralnetworks/1.2/utils/src/Conversions.cpp +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -257,16 +257,15 @@ GeneralResult convert( }; } -GeneralResult convert(const hidl_handle& handle) { - auto* cloned = native_handle_clone(handle.getNativeHandle()); - return ::android::NativeHandle::create(cloned, /*ownsHandle=*/true); +GeneralResult convert(const hidl_handle& hidlHandle) { + return hal::utils::sharedHandleFromNativeHandle(hidlHandle.getNativeHandle()); } GeneralResult> convert(const hidl_vec& extensions) { return convertVec(extensions); } -GeneralResult> convert(const hidl_vec& handles) { +GeneralResult> convert(const hidl_vec& handles) { return convertVec(handles); } @@ -487,18 +486,15 @@ nn::GeneralResult convert( }; } -nn::GeneralResult convert(const nn::NativeHandle& handle) { - const auto hidlHandle = hidl_handle(handle->handle()); - // Copy memory to force the native_handle_t to be copied. - auto copiedHandle = hidlHandle; - return copiedHandle; +nn::GeneralResult convert(const nn::SharedHandle& handle) { + return hal::utils::hidlHandleFromSharedHandle(handle); } nn::GeneralResult> convert(const std::vector& extensions) { return convertVec(extensions); } -nn::GeneralResult> convert(const std::vector& handles) { +nn::GeneralResult> convert(const std::vector& handles) { return convertVec(handles); } diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index ca236f17c6..517d61f85c 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -257,8 +257,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/, - nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -286,8 +286,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto hidlModelCache = NN_TRY(convert(modelCache)); const auto hidlDataCache = NN_TRY(convert(dataCache)); const auto hidlToken = token; diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h index 2f6c46a858..0f5234bd26 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h @@ -61,13 +61,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index c215f39ecf..5e3d5c2ce2 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -179,8 +179,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -211,8 +211,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto hidlDeadline = NN_TRY(convert(deadline)); const auto hidlModelCache = NN_TRY(V1_2::utils::convert(modelCache)); const auto hidlDataCache = NN_TRY(V1_2::utils::convert(dataCache)); diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index df9b280119..2781053d07 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -53,15 +53,6 @@ nn::ExecutionResult, nn::Timing>> convert return hal::utils::makeExecutionFailure(convertExecutionResultsHelper(outputShapes, timing)); } -nn::GeneralResult> convertSyncFences( - const std::vector& syncFences) { - hidl_vec handles(syncFences.size()); - for (size_t i = 0; i < syncFences.size(); ++i) { - handles[i] = NN_TRY(V1_2::utils::convert(syncFences[i].getHandle())); - } - return handles; -} - nn::GeneralResult> convertFencedExecutionCallbackResults( const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { return std::make_pair(NN_TRY(validatedConvertToCanonical(timingLaunched)), @@ -221,7 +212,7 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector +#include #include #include #include @@ -57,6 +59,13 @@ nn::GeneralResult unflushDataFromSharedToPointer( std::vector countNumberOfConsumers(size_t numberOfOperands, const std::vector& operations); +nn::GeneralResult createSharedMemoryFromHidlMemory(const hidl_memory& memory); + +nn::GeneralResult hidlHandleFromSharedHandle(const nn::SharedHandle& handle); +nn::GeneralResult sharedHandleFromNativeHandle(const native_handle_t* handle); +nn::GeneralResult> convertSyncFences( + const std::vector& fences); + } // namespace android::hardware::neuralnetworks::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h index 4f1afb983a..4a84e4dacc 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h @@ -63,13 +63,13 @@ class ResilientDevice final : public nn::IDevice, nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( @@ -81,12 +81,12 @@ class ResilientDevice final : public nn::IDevice, nn::GeneralResult prepareModelInternal( bool blocking, const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const; + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const; nn::GeneralResult prepareModelFromCacheInternal( bool blocking, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const; + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const; nn::GeneralResult allocateInternal( bool blocking, const nn::BufferDesc& desc, const std::vector& preparedModels, diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp index 25659728c3..c04c8dfa8b 100644 --- a/neuralnetworks/utils/common/src/CommonUtils.cpp +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -19,6 +19,7 @@ #include "HandleError.h" #include +#include #include #include #include @@ -247,4 +248,67 @@ std::vector countNumberOfConsumers(size_t numberOfOperands, return nn::countNumberOfConsumers(numberOfOperands, operations); } +nn::GeneralResult hidlHandleFromSharedHandle(const nn::SharedHandle& handle) { + if (handle == nullptr) { + return {}; + } + + std::vector fds; + fds.reserve(handle->fds.size()); + for (const auto& fd : handle->fds) { + int dupFd = dup(fd); + if (dupFd == -1) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Failed to dup the fd"; + } + fds.emplace_back(dupFd); + } + + native_handle_t* nativeHandle = native_handle_create(handle->fds.size(), handle->ints.size()); + if (nativeHandle == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Failed to create native_handle"; + } + for (size_t i = 0; i < fds.size(); ++i) { + nativeHandle->data[i] = fds[i].release(); + } + std::copy(handle->ints.begin(), handle->ints.end(), &nativeHandle->data[nativeHandle->numFds]); + + hidl_handle hidlHandle; + hidlHandle.setTo(nativeHandle, /*shouldOwn=*/true); + return hidlHandle; +} + +nn::GeneralResult sharedHandleFromNativeHandle(const native_handle_t* handle) { + if (handle == nullptr) { + return nullptr; + } + + std::vector fds; + fds.reserve(handle->numFds); + for (int i = 0; i < handle->numFds; ++i) { + int dupFd = dup(handle->data[i]); + if (dupFd == -1) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Failed to dup the fd"; + } + fds.emplace_back(dupFd); + } + + std::vector ints(&handle->data[handle->numFds], + &handle->data[handle->numFds + handle->numInts]); + + return std::make_shared(nn::Handle{ + .fds = std::move(fds), + .ints = std::move(ints), + }); +} + +nn::GeneralResult> convertSyncFences( + const std::vector& syncFences) { + hidl_vec handles(syncFences.size()); + for (size_t i = 0; i < syncFences.size(); ++i) { + handles[i] = + NN_TRY(hal::utils::hidlHandleFromSharedHandle(syncFences[i].getSharedHandle())); + } + return handles; +} + } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp index 95662d96bd..26025a5026 100644 --- a/neuralnetworks/utils/common/src/ResilientDevice.cpp +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -161,8 +161,8 @@ nn::GeneralResult> ResilientDevice::getSupportedOperations( nn::GeneralResult ResilientDevice::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { auto self = shared_from_this(); ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), model, preference, priority, deadline, modelCache, dataCache, @@ -174,8 +174,8 @@ nn::GeneralResult ResilientDevice::prepareModel( } nn::GeneralResult ResilientDevice::prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { auto self = shared_from_this(); ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), deadline, modelCache, dataCache, @@ -202,8 +202,8 @@ nn::GeneralResult ResilientDevice::allocate( nn::GeneralResult ResilientDevice::prepareModelInternal( bool blocking, const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto fn = [&model, preference, priority, deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModel(model, preference, priority, deadline, modelCache, dataCache, @@ -214,8 +214,8 @@ nn::GeneralResult ResilientDevice::prepareModelInternal nn::GeneralResult ResilientDevice::prepareModelFromCacheInternal( bool blocking, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto fn = [deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModelFromCache(deadline, modelCache, dataCache, token); }; diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp index 87d27c7ac3..402598c7aa 100644 --- a/neuralnetworks/utils/service/Android.bp +++ b/neuralnetworks/utils/service/Android.bp @@ -26,6 +26,7 @@ cc_library_static { "neuralnetworks_utils_hal_1_1", "neuralnetworks_utils_hal_1_2", "neuralnetworks_utils_hal_1_3", + "neuralnetworks_utils_hal_common", ], shared_libs: [ "android.hardware.neuralnetworks@1.0",